\documentclass[main.tex]{subfiles}
\begin{document}
\chapter{Asymptotic Analysis}

\epigraph{In algorithms, as in life, persistence usually pays off.}{Steven S.\ Skiena}

\minitoc

\section{Introduction}

What is an algorithm?

\begin{defn}[Algorithm]
	A recipe/description of a process that accomplishes a goal
\end{defn}

Why study algorithms? First, you will gain tools to \textit{compare} algorithms. Second, studying algorithms will help you to creatively make \textit{new} algorithms.

Why study algorithms in discrete math? Computers are discrete. Computers run programs, which are based on algorithms. Hence, algorithms must be discrete.

\section{\(\Oh\), \(\Omega\), and \(\Theta\) Notations}

Our motivation here is to describe the \textit{growth-rate} of functions. The growth-rate class gives us key insights to what the actual function does on large inputs.

\begin{defn}[Big-Oh]
	An upper-bound on the growth-rate of a function. Formally: \[f(n) \in \Oh(g(n)) \Leftrightarrow (\exists n_0 \in \N, \exists c \in \R^+, \forall n \in \N^{\geq n_0})[f(n) \leq c \cdot g(n)]\]
\end{defn}

\begin{defn}[Big-Omega]
	A lower-bound on the growth-rate of a function. Formally: \[f(n) \in \Omega(g(n)) \Leftrightarrow (\exists n_0 \in \N, \exists c \in \R^+, \forall n \in \N^{\geq n_0})[f(n) \geq c \cdot g(n)]\]
\end{defn}

\begin{defn}[Big-Theta]
	An exact growth-rate of a function. Formally: \[f(n) \in \Theta(g(n)) \Leftrightarrow f(n) \in \Oh(g(n)) \land f(n) \in \Omega(g(n))\]
\end{defn}

Informally, \(f(n) \in \Oh(g(n))\) just means that \textbf{eventually} (for big enough \(n\)) we have that (some constant-multiple of) \(g\) overtakes \(f\).
For example, \(2^n \in \Oh(n!)\) since \(2^n < n!\) (\(n!\) overtakes \(2^n\)) for \(n \geq 4\) (\(n \in \N\)).
So the growth-rate of \(2^n\) is bounded \textit{above} by \(n!\).
Similarly, \(n! \in \Omega(2^n)\) since \(n! > 2^n\) for \(n \geq 4\).
So \(n!\) is bounded \textit{below} by \(2^n\).
Oftentimes in algorithm analysis we aim to show an algorithm has exact run-time (\(\Theta\)), and we do this by showing it has both \(\Oh\) and \(\Omega\) run-time.
Sometimes, though, this is hard to do.

\begin{rem}
	You may see \(\Oh,\Omega,\Theta\) defined using \(\forall n \in \N^{> n_0}\).
	It does not actually matter.
	Just consult whichever definition your instructor uses.
\end{rem}

\begin{rem}
	You may see \(f(n) = \Oh(g(n))\) instead of \(f(n) \in \Oh(g(n))\).
	Both notations represent the same thing.
\end{rem}

\begin{rem}
	We need not use \(n\) for our function variable.
\end{rem}

\exproof{
	Show that \(f(x) = x^2 + 2x - 4 = \Oh(x^2)\).
}{
	To show \(\Oh\), it suffices to find a constant \(c\) and starting point \(x_0\).
	A typical way to do this is by selecting a starting point that might help us down the line.
	Consider \(x_0 = 1\).
	Then, \(x \geq x_0 = 1\).
	Then \(x \leq x^2\) so \(2x \leq 2x^2\) (this is where our starting point choice helps us).
	Thus \(x^2 + 2x - 4 \leq x^2 + 2x \leq x^2 + 2x^2 = 3x^2\).
	So we let \(c = 3\) and we are done.
}

\exproof{
	Show that \(f(x) = x^2 + 2x - 4 = \Omega(x^2)\).
}{
	We take a similar approach as in the previous example.
	Let \(x_0 = 4\).
	Then \(x \geq x_0 = 4\).
	Thus \(x \geq 4 = \frac{2}{1-\frac{1}{2}}\) so \((1-\frac{1}{2}x \geq 2\) so \(x - \frac{1}{2}x \geq 2\) thus \(x - 2 \geq \frac{1}{2}x\).
	Since \(x+2 \geq x-2\) then \(x+2 \geq \frac{1}{2}x\).
	Thus \((x+2)(x-2) \geq (\frac{1}{2}x)^2 = \frac{1}{4}x^2\).
	Since \((x+2)(x-2) = x^2 - 4\) and \(x \geq 4 > 0\) so \(2x > 0\), then \(x^2+2x-4 \geq x^2-4 \geq \frac{1}{4}x^2\).
	So we let \(c = \frac{1}{4}\) and we are done.
}

\begin{rem}
	We can conclude that our \(f(x)\) defined above is in \(\Theta(x^2)\) since it satisfies both \(\Oh\) and \(\Omega\).
	Note that the \(c,x_0\) used in the \(\Oh\) proof need not be the same as those in the \(\Omega\) proof (and vice versa).
	They only need to exist.
\end{rem}

A picture, to see what is going on.

%\pgfmathdeclarefunction{bound}{1}{%
%	\pgfmathparse{#1*x^2}%
%}
\begin{boxx}
	\begin{center}
		\begin{tikzpicture}
			\begin{axis}[
				mark=none,smooth,
				axis x line=bottom, % no box around the plot, only x and y axis
				axis y line=left,
				every fill between plot/.append style={fill=gray,fill opacity=0.1},
				samples=50]
				\addplot [name path=up,color=red,domain=4:6.5] {(3)*x^2} node[pos=1] (up) {};
				\addplot [name path=lo,color=blue,domain=4:6.5] {(1/4)*x^2} node[pos=1] (lo) {};
				\addplot [gray] fill between[of=up and lo];
				\addplot [color=black,domain=0:6.5] {x^2+2*x-4} node[pos=1] (func) {};
				\addplot [color=red,domain=0:6.5] {(3)*x^2} node[pos=1] (upper) {};
				\addplot [color=blue,domain=0:6.5] {(1/4)*x^2} node[pos=1] (lower) {};
				\node [label=135:{\(x_0\)},circle,fill,inner sep=1pt] at (axis cs:1,3) {};
				\node [label=135:{\(x_0\)},circle,fill,inner sep=1pt] at (axis cs:4,4) {};
			\end{axis}
			\node [above, color=black] at (func) {\(f(x)\)};
			\node [above, color=red] at (upper) {\(\Oh\)};
			\node [above, color=blue] at (lower) {\(\Omega\)};
		\end{tikzpicture}
	\end{center}
\end{boxx}

It should be easy to see from this picture that we can make tighter bounds by changing \(c\).
If you change your \(c\), then your \(x_0\) usually will also change.
It should also be easy to see from this picture that for a given \(c\), we may be able to find better \(x_0\).
In this case, we could move our \(\Omega\) \(x_0\) closer to 2.
Note that our function \(f\) is still bounded by our \(\Oh\) and \(\Omega\) functions.
As long as \(c,x_0\) \textit{exist}, we are good to go.

It might be confusing seeing these proofs, as we somewhat made everything appear out of nowhere.
Often, we solve these proofs using scratch work, then cleaning it up for presentation.

\begin{example}
	For \(\Omega\), we started at the goal of \(x^2 + 2x - 4 \stackrel{?}{\geq} cx^2\).
	Note that \(x^2 + 2x - 4 \geq x^2-4 = (x+2)(x-2)\).
	Since \(x+2 > x-2\) then if we can find \(d > 0\) such that \(x-2 \geq dx\) then we can conclude that \((x+2)(x-2) \geq d^2x^2\).
	Then we let \(c = d^2\).

	So now our goal is to solve \(x-2 \stackrel{?}{\geq} dx\).
	Rearranging yields \(x \stackrel{?}{\geq} \frac{2}{(1-d)}\).
	By letting \(d = \frac{1}{2}\), then we get \(x \geq 4\) and we can thus work backwards for the actual proof to find \(c = \frac{1}{4}\) with \(x_0 = 4\).
\end{example}

% todo -- limit definitions

\section{Analyzing Algorithms}

We can express algorithms in terms of functions. The function input is typically \(n\), the number of elements inputted into, or input size for, the algorithm, and the function output is typically time. Usually \textit{time} will be the number of certain operations performed during the algorithm.

\exsol{
	Come up with a function \(T(n)\) that describes the run-time of the following algorithm. Define run-time as the number of conditional evaluations. In the following algorithm, \(L\) is a list of integers of length \(n\).
	\begin{algorithmic}[1]
		\Function{GetMax}{\(L\), \(n\)\@}
			\State \(M \gets -\infty\)
			\State \(i \gets 0\)
			\While{\(i < n\)}
				\If{\(L[i] > M\)}
					\State \(M \gets L[i]\)
				\EndIf
				\State \(i \gets i+1\)
			\EndWhile
			\State \Return \(M\)
		\EndFunction
	\end{algorithmic}
}{
	We evaluate the if-statement in line 5 exactly \(n\) times, and we evaluate the while-loop condition exactly \(n+1\) times (the last time is when we break out of the loop). Thus, \(T(n) = n + n + 1 = 2n + 1\)
}

\exsol{
	Now come up with a function \(U(n)\) that outputs the number of \(\gets\) operations. Compare \(T(n)\) to \(U(n)\).
}{
	We have two initial stores from lines 1 and 2. Each while-loop iteration has a store command in line 8. The while-loop runs exactly \(n\) times, so this gives us \(n\) stores. Line 6 has a store command which is run \(\leq n\) times. We can model this using a natural number \(c \leq n\) where \(c\) is the number of times line 5 evaluates to true. Our function is thus \(U(n) = n + c + 2\)

	Since \(c \leq n\) we have that \(U(n) \leq T(n)\) for all \(n > 1\). Note that when \(n = 1\) we have \(T(n) = 3\) and \(U(n) = 4\) (since \(c = 1\)). In any case, we have that the growth-rates of both functions are solely dependent on \(n\) and are hence the same. Both functions are in \(\Theta(n)\)
}

\begin{defn}[The Loop-Heuristic]
	(algorithm analysis) For each nested loop in an algorithm, multiply \(n\) by the number of nested levels. This can be helpful in an initial analysis, however it will only take you so far.
\end{defn}

\begin{rem}
	We state the loop-heuristic as a definition, however it can be rephrased as a provable theorem.
\end{rem}

It is important to think about what is going on during the algorithm instead of blindly following the loop-heuristic. We present a few related examples.

\exsol{
	Analyze the following algorithm:
	\begin{algorithmic}[1]
		\Function{AnalyzeList}{\(L\), \(n\)\@}
			\State \(M \gets 0\)
			\For{\(i \gets 0\); \(i < n\); \(i \gets i + 1\)}
				\State \(k \gets L[i]\)
				\For{\(j \gets i\); \(j < n\); \(j \gets j + 1\)}
					\State \(k \gets k * L[j]\)
				\EndFor
				\State \(M \gets M + k\)
			\EndFor
			\State \Return \(M\)
		\EndFunction
	\end{algorithmic}
}{
	The algorithm contains 2 nested loops, so by the loop-heuristic our run-time is \(n^2\). We examine further. The outer loop goes through the list \(n\) times. For each iteration \(i\), we have a loop that goes through the list \(n - i\) times. The actual \textit{work} is done in the inner loop. Thus, the amount of work equals \(1 + 2 + 3 + \cdots + n = \frac{n(n+1)}{2} = \frac{1}{2}n^2 + \frac{1}{2}n\) by the Gaussian sum. This has a growth rate of \(n^2\), so we see that the loop-heuristic worked and the algorithm runs in \(\Oh(n^2)\). In fact, the amount of work does not change with respect to different input ordering, so the algorithm runs in \(\Theta(n^2)\)
}

\exsol{
	Examine the following algorithm:
	\begin{algorithmic}[1]
		\Function{AnalyzeGraph}{\(G = (V,E)\)\@}
			\State \(c \gets 0\)
			\For{\(v \in V\)}
				\For{\(w \in \text{UnvisitedNeighbors}(v)\)}
					\State Visit \(w\)
					\State \(c \gets c + 1\)
				\EndFor
			\EndFor
			\State \Return \(c\)
		\EndFunction
	\end{algorithmic}
}{
	\(G\) represents a graph, where \(V\) is the set of vertices and \(E\) is the set of edges. We usually denote \(|V| = n\) and \(|E| = m\).

	Let us first think about what the algorithm is \textit{doing}. We instantiate \(c=0\), then go through each unvisited vertex we increment \(c\). We consider the amount of work in the inner loop \(\Theta(1)\), and we do this exactly \(|V| = n\) times. So our algorithm runs in \(\Theta(V)\) (or \(\Theta(n)\)). % todo : undirected or directed? define neighbors?
}

\begin{rem}
	How would this change had we instead iterated through the \textit{neighbors}, instead of \textit{unvisited neighbors}? We will come back to this % todo
\end{rem}

Okay, so how does one determine whether an algorithm is \textit{good}? Well, it depends on how you define \textit{good}. Typically we define \textit{good} as having a low run-time. Unfortunately, an algorithm's run-time can change depending on the input. Remember: when writing algorithms, you cannot predetermine the input! This heeds way to the idea of \textit{best-case}, \textit{worst-case}, and \textit{average-case} analysis.

\begin{defn}[Best-case Analysis]
	Analyzing an algorithm based on an optimal input that minimizes its run-time.
\end{defn}

Best-case analysis is akin to bounding an algorithm's run-time function below, which is just determining the tightest Big-Omega bound. So, \(\Omega\) essentially tells you how fast the algorithm will run in the best case.

\begin{defn}[Worst-case Analysis]
	Analyzing an algorithm based on a pathological input that maximizes its run-time.
\end{defn}

By contrast, worst-case analysis is akin to bounding an algorithm's run-time function above, which is just determining the tightest Big-Oh bound. So, \(\Oh\) essentially tells you how fast the algorithm will run in the worst case.

\begin{defn}[Average-case Analysis]
	Analyzing an algorithm's run-time based on typical, expected, input.
\end{defn}

\begin{rem}
	You may be tempted to think that, as the analogy would imply, average-case analysis is akin to \(\Theta\). This is not true. \(\Theta\) tells you the \textit{exact} run-time, which is when \(\Oh\) and \(\Omega\) agree. If you know your algorithm run-time has a \(\Theta\) bound, then the average-case analysis will be this bound. The converse is not true though. If you have the average-case bound, this does not necessarily mean the worst-case or best-case is the same. An important example of this is the Quicksort algorithm.
\end{rem}

We present a pathological example to explain why these different analysis types are important.

\exsol{
	Examine the following algorithm:
	\begin{algorithmic}[1]
		\Function{Pathological}{\(L\), \(n\)\@}
		\If{\(n \equiv 0 \Mod{2}\)}
			\State
		\Else
			\State \Return \(L[0]\)
		\EndIf
		\State \(c \gets 0\)
		\For{\(v \in V\)}
		\For{\(w \in \text{UnvisitedNeighbors}(v)\)}
		\State Visit \(w\)
		\State \(c \gets c + 1\)
		\EndFor
		\EndFor
		\State \Return \(c\)
		\EndFunction
	\end{algorithmic}
	% todo function that takes exponential on if-branch, and constant on else
}{

}

% maybe another that is less pathological

\subsection{Solving Summations}

% todo

% we did a similar thing during the number theory chapter.
% i guess make it more explicit here? idk
% we use the sum of c, i and i^2 here

% recall addition is linear, so blah blah blah

\subsection{Solving Recurrences}

% todo

% tree table descending example

\begin{thm}[The Master Theorem]
	% todo
\end{thm}

Proof omitted.

% another example, but use master thm

\section{Common Complexities}

There are a handful of common run-time complexities that you should be familiar with. In this book, we give them to you in ascending order of growth rate in Big Theta notation.

\begin{defn}[Constant]
	\[\Theta(1)\]
\end{defn}

\begin{defn}[Logarithmic]
	\[\Theta(\log n)\]
\end{defn}

\begin{defn}[Linear]
	\[\Theta(n)\]
\end{defn}

\begin{defn}[Polynomial]
	\[\Theta(n^c),\ c > 1\]
	We call \(\Theta(n^2)\) Quadratic
\end{defn}

\begin{defn}[Exponential]
	\[\Theta(c^n),\ c > 1\]
\end{defn}

\section{P vs NP}

There exist many YouTube videos discussing the famous P vs.\ NP problem (\href{https://www.youtube.com/watch?v=EHp4FPyajKQ}{ex 1}, \href{https://www.youtube.com/watch?v=YX40hbAHx3s}{ex 2}). Moreover, if you solve it, the Clay Mathematics Institute has \href{https://www.claymath.org/millennium-problems/p-vs-np-problem}{\$1,000,000} waiting for you. So what is it?

\begin{defn}[P]
	The class of computational problems that can be solved in \textbf{P}olynomial time.
\end{defn}

\begin{defn}[NP]
	The class of computational problems where a given solution can be \textit{verified} in polynomial time.
\end{defn}

\begin{rem}
	NP stands for \textit{Nondeterministic Polynomial}. It does \textbf{not} stand for \textit{non-polynomial} as some people think.
\end{rem}

\begin{defn}[Reductions]

\end{defn}

\begin{defn}[NP-Complete]
	A computational problem is NP-Complete if it satisfies two conditions:
	\begin{enumerate}
		\item The problem is in NP
		\item Every problem in NP is reducible to it in polynomial time
	\end{enumerate}
\end{defn}

\begin{rem}
	Problems that satisfy the second condition above, and not necessarily the first, are called \textbf{NP-Hard}.
\end{rem}

The second condition is tricky.
As of now, the set of NP-Complete problems is empty.
So we need some form of \textit{starter problem} to which all reductions can be made.

\begin{thm}[The Cook-Levin Theorem]
	The Boolean satisfiability problem is NP-Complete.
\end{thm}

\begin{rem}
	While at this point in the course you likely can understand the proof, we omit it for scope.
\end{rem}

We leave this discussion with one final remark.
\(\text{P}=\text{NP}\) will render most (all) cryptographic algorithms and services broken.
This is because most modern cryptography is built on the observation that factoring very large primes is \textit{hard}.
If you are interested, look into RSA and/or the Diffie-Hellman key exchange.

\section{The Halting Problem}

Infinite loops are a software developer's worst nightmare. They are hard to find, debug, and (sometimes) fix. If only there were a piece of software that could examine your code and tell you whether there are any infinite loops. More abstractly, if it could tell you whether your program continues forever or eventually stops.

Well, we are sorry to break the news to you, but this piece of software can never exist; sort-of.

The halting problem is most commonly used as an introduction to computability theory. What problems can we compute? What does it even mean to be computable? These questions are out of scope of this book, but if the following problem interests you, consider taking a course on theory of computation.

\begin{defn}[The Halting Problem]
	A computational problem of determining whether an arbitrary computer program, with input, will stop or run forever.
\end{defn}

Think to yourself whether you can come up with a solution program. It is a difficult problem. Alan Turing proved in 1936 that no such algorithm could exist \textit{for all} pairs of programs and inputs. This proof led to (created) the Turing machine, and arguably all of modern computer science. The proof sketch follows. We call it a sketch because the actual proof is significantly more in-depth.

\begin{proof}
	Assume that such an algorithm (code description, function, method, whatever you want to call it) \(h\) exists. The function \(h : P \times I \rightarrow \mathbb{B}\) given by \(h : (p,i) \mapsto b\) tells us whether a given input program \(p \in P\) (the set of all programs) with input \(i \in I\) (the set of all program inputs) will halt (stop) or not: \(b \in \mathbb{B} = \{\text{True}, \text{False}\}\).

	Then the following procedure \(\textsc{g} \in P\):
	\begin{algorithmic}[1]
		\Function{g}{\(\cdot\)\@}
			\If{\(h(\textsc{g},\cdot)\)}
				\While{True}
				\Comment{loop forever}
				\EndWhile
			\EndIf
		\EndFunction
	\end{algorithmic}

	We have two cases: \(h(\textsc{g},\cdot)\) returns True, or \(h(\textsc{g},\cdot)\) returns False.

	Case 1: \(h(\textsc{g},\cdot) = \text{True}\). Then \textsc{g} stops. But since \(h\) returned True, the body of the if-statement will be executed. Then \textsc{g} will loop forever. But this contradicts the output of \(h\).

	Case 2: \(h(\textsc{g},\cdot) = \text{False}\). Then \textsc{g} does not stop. But since \(h\) returned False, the body of the if-statement is \textit{not} executed, so \textsc{g} will stop. But this contradicts the output of \(h\).

	Thus, the halting problem is undecidable (impossible to answer for all inputs).
\end{proof}

% todo

\section{Summary}

\begin{itemize}
	\item
	\item
	\item
\end{itemize}

\section{Practice}

\begin{enumerate}
	\item Analyze the following algorithm:
	\begin{algorithmic}[1]
		\Function{SomeFunc}{\(n\)\@}
			\State something
		\EndFunction
	\end{algorithmic}
	\item Order the following complexities: \(\Theta(n \log n)\), \(\Theta(n \log (n^2))\), \(\Theta(n)\), \(\Theta(n^2)\). Explain why your ordering is correct.
	\item Order the following complexities: \(\Theta(\log (3n))\), \(\Theta(n^n)\), \(\Theta(n!)\), \(\Theta(\log (\log n))\).
\end{enumerate}

%\section{Solutions}
%
%\begin{enumerate}
%	\item
%	\item Since \(n \log (n^2) = 2n \log n\) we have that \(n \log (n^2) \in \Theta(n \log n)\). So the growth-rate of those two functions are the same. It suffices to order \(\Theta(n \log n)\), \(\Theta(n)\), \(\Theta(n^2)\). We know \(n \in \Oh(n^2)\). It should be clear that \(n \in \Oh(n \log n)\) (consider \(1 < \log_b n \Rightarrow n < n \log_b n\) for all \(n > b\)). Similar logic can be applied to show that \(n \log n \in \Oh(n^2)\). Thus our ordering is \(n < n \log n < n \log (n^2) < n^2\) where \(a <b \) is shorthand for \(a \in \Oh(b)\)
%	\item \(\log \log n < \log (3n) < n! < n^n\) where \(a <b \) is shorthand for \(a \in \Oh(b)\)
%\end{enumerate}
\end{document}


\documentclass[11pt, a4paper]{article}

\usepackage{amsmath}
\usepackage{pgf}
\usepackage{tikz}
\usepackage{kbordermatrix}
\usetikzlibrary{arrows,automata, shapes, petri}
\usepackage{placeins}
\usepackage{multirow}
\usepackage{booktabs}

\begin{document}

\title{HIDDEN MARKOV MODELS}
\date{}
\maketitle

Hidden Markov Models(HMMs) are statistical tools to model sequential observations with the assumption that states of the system generating them follow a Markov process but these states are unobservable/hidden. However, an observation at any point is related to the underlying hidden state the system is in at that point.

\section{Example}

\begin{center}
	\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=5cm,
		semithick]

		\node[initial,state] (I)                    {$$};
		\node[state]         (S) [below left of=I] {$S$};
		\node[state]         (T) [below right of=I] {$T$};
		\node[rectangle]         (SX) [below left of=S,yshift=-1.2cm,xshift=1cm]     {$X$};
		\node[rectangle]         (SY) [below of=S]     {$Y$};
		\node[rectangle]         (SZ) [below right of=S,yshift=-1.2cm,xshift=-1cm]     {$Z$};
		\node[rectangle]         (TX) [below left of=T,yshift=-1.2cm,xshift=1cm]     {$X$};
		\node[rectangle]         (TY) [below of=T]     {$Y$};
		\node[rectangle]         (TZ) [below right of=T,yshift=-1.2cm,xshift=-1cm]     {$Z$};

		\path (I) edge [bend right]    node {0.6} (S)
		edge [bend left]     node {0.4} (T)
		(S) edge [loop left]    node {0.7} (S)
		edge [bend left]    node {0.3} (T)
		edge                node {0.1} (SX)
		edge                node {0.4} (SY)
		edge                node {0.5} (SZ)
		(T) edge [loop right]   node {0.6} (T)
		edge [bend left]    node {0.4} (S)
		edge                node {0.7} (TX)
		edge                node {0.2} (TY)
		edge                node {0.1} (TZ);
		\draw [to-to] (-7,-7) -- (7,-7);
		\node at (0, -6.5) {Hidden};
		\node at (0, -7.5) {Observable};
	\end{tikzpicture}
\end{center}

In this diagram, nodes $\{S, T\}$ represent the hidden states and $\{X, Y, Z\}$ represent observable states. The unlabelled node is the start node. These states together with the associated probabilities fully characterize the HMM. The state transition probabilites denoted by $A$ can be represented as,

\[
	A = \kbordermatrix{
		& S & T \\
		S & 0.7 & 0.3 \\
		T & 0.6 & 0.4 \\
	}
\]

The emmission probabilities are denoted by $B$.

\[
	B = \kbordermatrix{
		& X & Y & Z \\
		S & 0.1 & 0.4 & 0.5 \\
		T & 0.7 & 0.2 & 0.1 \\
	}
\]

Lastly, initial state distribution is denoted by $\pi$.

\[
	\pi = \kbordermatrix{
		& S & T \\
		& 0.6 & 0.4
	}
\]

\section{The three problems of HMM}

\subsection{The Evaluation Problem}

Given a HMM, $\lambda=(A, B, \pi)$ and a set of observations $O$, find $P(O|\lambda)$ (probability that the observations were generated by the model).

Consider the HMM in the example above and let $O = (ZXY)$.

\begin{align*}
	P(ZXY|\lambda) & = P(SSS, ZXY|\lambda)  \\
	               & +\ P(SST, ZXY|\lambda) \\
	               & +\ P(STS, ZXY|\lambda) \\
	               & +\ P(STT, ZXY|\lambda) \\
	               & +\ P(TSS, ZXY|\lambda) \\
	               & +\ P(TST, ZXY|\lambda) \\
	               & +\ P(TTS, ZXY|\lambda) \\
	               & +\ P(TTT, ZXY|\lambda) \\
\end{align*}

Each of the terms on R.H.S. can be calculated using the following law of probability.

\begin{align*}
	P(a, b|c) & = \frac{P(a, b, c) }{P(c)}                            \\
	          & = \frac{P(a, c) }{P(c)} * \frac{P(a, b, c) }{P(a, c)} \\
	          & = P(a|c) * P(b|a,c)
\end{align*}

\begin{table}[h!]
	\centering
	\caption{$P(ZXY|\lambda)$ calculation}
	\label{tab:table1}
	\begin{tabular}{cccc|c}
		\toprule
		HS  & OS  & $P(HS|\lambda)$   & $P(OS|HS, \lambda)$ & $P(HS, OS|\lambda)$ \\
		\midrule
		SSS & ZXY & 0.6*0.7*0.7=0.294 & 0.5*0.1*0.4=0.020   & 0.005880            \\
		SST & ZXY & 0.6*0.7*0.3=0.126 & 0.5*0.1*0.2=0.010   & 0.001260            \\
		STS & ZXY & 0.6*0.3*0.4=0.072 & 0.5*0.7*0.4=0.140   & 0.010080            \\
		STT & ZXY & 0.6*0.3*0.6=0.108 & 0.5*0.7*0.2=0.070   & 0.007560            \\
		TSS & ZXY & 0.4*0.4*0.7=0.112 & 0.1*0.1*0.4=0.004   & 0.000448            \\
		TST & ZXY & 0.4*0.4*0.3=0.048 & 0.1*0.1*0.2=0.002   & 0.000096            \\
		TTS & ZXY & 0.4*0.6*0.4=0.096 & 0.1*0.7*0.4=0.028   & 0.002688            \\
		TTT & ZXY & 0.4*0.6*0.6=0.144 & 0.1*0.7*0.2=0.014   & 0.002016            \\
		\midrule
		    &     &                   & $P(ZXY|\lambda)$    & 0.030028            \\
		\bottomrule
	\end{tabular}
\end{table}

Calculation in this manner is expensive because probabilities corresponding to all permutations of hidden states of the same length as the length of observed sequence have to be calculated.

To visualize the above calculation, consider the following diagrammatic represntation.

\begin{center}
	\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=4cm,
		semithick]

		\node[state] (Start)                    {$Start$};
		\node[state] (S1) [above right of=Start] {$S$};
		\node[state] (T1) [below right of=Start] {$T$};
		\node[state] (S2) [right of=S1] {$S$};
		\node[state] (T2) [right of=T1] {$T$};
		\node[state] (S3) [right of=S2] {$S$};
		\node[state] (T3) [right of=T2] {$T$};
		\node[state] (End) [below right of=S3] {$End$};
		\node [rectangle, node distance=2cm] (Z) [above of=S1] {Z};
		\node [rectangle, node distance=2cm] (X) [above of=S2] {X};
		\node [rectangle, node distance=2cm] (Y) [above of=S3] {Y};

		\path (Start) edge  node {0.6} (S1)
		edge  node {0.4} (T1)
		(S1) edge  node {0.5*0.7} (S2)
		edge  node [pos=0.2] {0.5*0.3} (T2)
		(T1) edge  node [pos=0.2] {0.1*0.4} (S2)
		edge  node {0.1*0.6} (T2)
		(S2) edge  node {0.1*0.7} (S3)
		edge node [pos=0.2] {0.1*0.3} (T3)
		(T2) edge node [pos=0.2] {0.7*0.4} (S3)
		edge node {0.7*0.6} (T3)
		(S3) edge node {0.4} (End)
		(T3) edge node {0.2} (End);
	\end{tikzpicture}
\end{center}

The arrow from $S$ under $Z$ and $S$ under $X$ is labelled 0.5*0.7 as probability of emitting $Z$ given $S$ is 0.5 and probability of transition from $S$ to $S$ is 0.7. The arrow from $Start$ to $S$ is labelled 0.6 as initial probability of transitioning to $S$ is 0.6. Similarly, the arrow from $S$ to End is labelled 0.4 as probability of emitting $Y$ given $S$ is 0.4.

Every path in the diagram from $Start$ to $End$ has a special meaning in the sense that the multiplication of all labels on the path (which henceforth shall be called its value) is equal to the joint probability of the observation sequence and the hidden state transition sequence defined by the path given the model.

The diagram also leads to the fact that $P(ZXY|\lambda)$ can be thought of as arising out of the enumeration of all paths from $Start$ to $End$ and then summation over their value.

Dynamic Programming can be used to circumvent enumeration and speed up the computation as shown below,

\begin{center}
	\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=4cm,
		semithick]

		\node[state] (Start)                    {$1$};
		\node[state] (S1) [above right of=Start] {$0.6$};
		\node[rectangle, node distance=2cm] (D1) [right of=S1] {$=1*0.6$};
		\node[state] (T1) [below right of=Start] {$0.4$};
		\node[rectangle, node distance=2cm] (D2) [right of=T1] {$=1*0.4$};
		\path (Start) edge  node {0.6} (S1)
		edge  node {0.4} (T1);
	\end{tikzpicture}
\end{center}

\noindent\rule{\textwidth}{0.6pt}

\begin{center}
	\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=4cm,
		semithick]

		\node[state] (S1) {$0.6$};
		\node[state] (T1) [below of=S1] {$0.4$};
		\node[state] (S2) [right of=S1] {$0.226$};
		\node[rectangle, node distance=4cm] (D2) [right of=S2] {$=0.6*0.5*0.7 + 0.4*0.1*0.4$};
		\node[state] (T2) [right of=T1] {$0.114$};
		\node[rectangle, node distance=4cm] (D2) [right of=T2] {$=0.6*0.5*0.3 + 0.4*0.1*0.6$};

		\path
		(S1) edge  node {0.5*0.7} (S2)
		edge  node [pos=0.2] {0.5*0.3} (T2)
		(T1) edge  node [pos=0.2] {0.1*0.4} (S2)
		edge  node {0.1*0.6} (T2);
	\end{tikzpicture}
\end{center}

\noindent\rule{\textwidth}{0.6pt}

\begin{center}
	\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=4cm,
		semithick]

		\node[state] (S2) {$0.226$};
		\node[state] (T2) [below of=S2] {$0.114$};
		\node[state] (S3) [right of=S2] {$0.04774$};
		\node[rectangle, node distance=4cm] (D3) [right of=S3] {$=0.226*0.1*0.7 + 0.114*0.7*0.4$};
		\node[state] (T3) [right of=T2] {$0.05466$};
		\node[rectangle, node distance=4cm] (D3) [right of=T3] {$=0.226*0.1*0.3 + 0.114*0.7*0.6$};

		\path
		(S2) edge  node {0.1*0.7} (S3)
		edge node [pos=0.2] {0.1*0.3} (T3)
		(T2) edge node [pos=0.2] {0.7*0.4} (S3)
		edge node {0.7*0.6} (T3);
	\end{tikzpicture}
\end{center}

\noindent\rule{\textwidth}{0.6pt}

\begin{center}
	\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=4cm,
		semithick]

		\node[state] (S3) {$0.04774$};
		\node[state] (T3) [below of=S3] {$0.05466$};
		\node[state] (End) [above right of=T3] {$0.030028$};
		\node[rectangle, node distance=4cm] (D4) [right of=End] {$=0.04774*0.4 + 0.05466*0.2$};
		\path
		(S3) edge node {0.4} (End)
		(T3) edge node {0.2} (End);
	\end{tikzpicture}
\end{center}

In this algorithm, each node on the right keeps track of sum of values of all paths from $Start$ to that node denoted by $\alpha_t(state)$.

\begin{table}[h!]
	\centering
	\begin{tabular}{c|c|c|c}
		\toprule
		              & $t=1$ & $t=2$ & $t=3$   \\
		\midrule
		$\alpha_t(S)$ & 0.6   & 0.226 & 0.04774 \\
		$\alpha_t(T)$ & 0.4   & 0.114 & 0.05466 \\
		\bottomrule
	\end{tabular}
\end{table}

The same algorithm can be run backwards from the $End$ node and work its way towards the $Start$ node. Now, each node in the left will keep track of sum of values of all paths from $End$ to that node denoted by $\beta_t(state)$.

\begin{table}[h!]
	\centering
	\begin{tabular}{c|c|c|c}
		\toprule
		             & $t=1$   & $t=2$ & $t=3$ \\
		\midrule
		$\beta_t(S)$ & 0.0413  & 0.034 & 0.4   \\
		$\beta_t(T)$ & 0.01312 & 0.196 & 0.2   \\
		\bottomrule
	\end{tabular}
\end{table}

It is apparent that the following relation must hold,

\begin{align*}
	\sum_{\text{all states}} \alpha_t(state)*\beta_t(state) = 0.030028\  \forall\ t
\end{align*}

\subsection{The Decoding Problem}

Given a HMM, $\lambda = (A, B, \pi)$ and a set of observations $O$, find the most likely sequence of hidden states that led the model to emit $O
$. The solution to this is straightforward. At each time step, the state corrresponding to maximum value of $\alpha_t(state)*\beta_t(state)$ is chosen.

\begin{table}[h!]
	\centering
	\caption{Decoding solution}
	\label{tab:table2}
	\begin{tabular}{c|c|c|c}
		\toprule
		             & $t=1$       & $t=2$       & $t=3$       \\
		\midrule
		S            & 0.6*0.0413  & 0.226*0.034 & 0.04774*0.4 \\
		T            & 0.4*0.01312 & 0.114*0.196 & 0.05466*0.2 \\
		\midrule
		Chosen State & S           & T           & S           \\
		\bottomrule
	\end{tabular}
\end{table}

\subsection{The Learning Problem}

If only the observation sequence $O$ were given, how can one estimate $\lambda$? Make a good guess of the number of hidden states and follow:

\begin{enumerate}
	\item Non uniformly initialize a model $\lambda = (A, B, \pi)$.
	\item Compute $\alpha_t(state)$ and $\beta_t(state)$ for all times and states using the solution to Problem 1.
	\item Re-estimate the model $\lambda$.
	\item Go to step 2 if $P(O|\lambda)$ increases reasonably or if out of iterations.
\end{enumerate}

The only question that remains is: How to re-estimate $\lambda$?

\begin{center}
	\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=4cm,
		semithick]

		\node[state] (S1) {$S$};
		\node[] (O1) [above of=S1, node distance=1cm]{$O_t$};
		\node[state] (T1) [below of=S1] {$T$};
		\node[state] (S2) [right of=S1] {$S$};
		\node[] (O2) [above of=S2, node distance=1cm]{$O_{t+1}$};
		\node[state] (T2) [right of=T1] {$T$};

		\path
		(S1) edge  node {1} (S2)
		edge  node [pos=0.2] {2} (T2)
		(T1) edge  node [pos=0.2] {} (S2)
		edge  node {} (T2);
	\end{tikzpicture}
\end{center}

Remember that $P(O|\lambda)$ is the sum of values if all paths from $Start$ to $End$. A fraction of $P(O|\lambda)$ comes from the sum of values of all paths that contain transtion $(state_t =S \rightarrow state_{t+1}=S)$ labelled by $1$ in the above figure. Denote it by $\gamma_t(S \rightarrow S)$.

A yet another fraction comes from the sum of values of all paths that contain transtion $(state_t =S \rightarrow state_{t+1}=T)$ labelled by $2$ denoted by $\gamma_t(S \rightarrow T)$. Also let,
\begin{align*}
	\gamma_t(S) = \gamma_t(S \rightarrow S) + \gamma_t(S \rightarrow T)
\end{align*}

Is $\frac{\gamma_t(S \rightarrow S)}{\gamma_t(S)}$ a good estimate of $A(S \rightarrow S)$? Kind of. But remember that only one time $t$ is considered. A better estimate would be,

\begin{align*}
	A(S \rightarrow S) \approx \frac{\sum_t \gamma_t(S \rightarrow S)}{\sum_t \gamma_t(S)}
\end{align*}

Similarly, $B(S \rightarrow OS)$ is estimated by,

\begin{align*}
	B(S \rightarrow OS) \approx \frac{\sum_{t|O_t = OS} \gamma_t(S)}{\sum_t \gamma_t(S)}
\end{align*}

This completes the discussion of the solution to the learning problem in HMMs.

\section{Applications}

HMMs are widely used in speech recognition, hand writing recognition, part of speech tagging, DNA sequence analysis etc. Wherever there is sequential aspect to data and the data can be thought of as arising out of an underlying simpler hidden probabilistic process, HMMs may be suited for application.

\end{document}

Hidden Markov Models/Hidden Markov Models.tex


%auto-ignore
\providecommand{\MainFolder}{..}
\documentclass[\MainFolder/Text.tex]{subfiles}

\begin{document}

\section{Gradings, degree shifts and completions
%for the \texorpdfstring{$\IBLInfty$-theory}{IBL-infinity-theory}
}
\allowdisplaybreaks
\label{Sec:Alg1a}

We will work with vector spaces over $\R$, possibly infinite-dimensional, graded by the \emph{degree} $d\in \Z$ and the \emph{weight} $k\in \N_0$.

\begin{Definition}[Weight-graded vector spaces]\label{Def:Grading}
A \emph{graded vector space} is a vector space~$W$ together with a collection  of subspaces $W^d \subset W$ for all $d\in \Z$ such that
\[ W=\bigoplus_{d\in \Z} W^d. \]
Elements of $W^d$ are called \emph{homogenous} of degree $d$; given $w\in W^d$, we denote the degree of $w$ by $\Abs{w} \coloneqq d$.

A linear map of graded vector spaces $f: W_1 \rightarrow W_2$ is called homogenous of degree $\Abs{f} \in \Z$ if it holds
\begin{equation}\label{Eq:StdGrading}
f(W_1^d)\subset W_2^{d+\Abs{f}}\quad\text{for all }d\in \Z.
\end{equation}

A \emph{weight-graded vector space} is a graded vector space $W$ together with a collection of subspaces $W_k^d \subset W^d$ for all $k\in \N_0$ and $d\in \Z$ such that
\[ W^d=\bigoplus_{k\in\N_0} W_k^d\quad\text{for all }d\in \Z. \]
We define the \emph{weight-$k$ component} of $W$ by
\[ W_k \coloneqq \bigoplus_{d\in \Z} W_k^d\quad\text{for all }k\in \N_0. \]
If $W_0^d = 0$ for all $d\in \Z$, we say that $W$ is \emph{weight-reduced.} We define the \emph{weight-reduced subspace} $\widebar{W}$ of a weight-graded vector space $W$ by
\[ \widebar{W} \coloneqq \bigoplus_{d\in \Z} \bigoplus_{k\in\N} W_k^d. \]

The superscript $\,{}^*$ usually denotes the dual in the category we work in, e.g., chain complexes. For a (weight-)graded vector space $W$, we also introduce the following notation to avoid confusion:%\footnote{This notation is applied only when it is clear that our main focus lies on the way a multi-graded vector space is dualized. Otherwise, ${}^*$ denotes the dualization in whichever category we currently work with and~${}'$ labels objects of the same type.}
\begin{equation}\label{Eq:Duals}\begin{aligned}
W^{\LD} \coloneqq \{\psi: W \rightarrow \R \text{ linear}\} &\;\,\dots&& \text{\emph{linear dual,}}\\[2\jot]
W^{\GD}  \coloneqq \bigoplus_{d\in  \Z} \prod_{k\in \N_0} W_{k}^{d*} &\;\,\dots&& \text{\emph{graded dual,}}\\
W^{\WGD} \coloneqq \bigoplus_{d\in \Z} \bigoplus_{k\in \N_0} W_k^{d*} &\;\,\dots&& \text{\emph{weight-graded dual.}}
\end{aligned}
\end{equation}
Here, $W^{\LD}$ is a vector space, $W^{\GD}$ a graded vector space and $W^{\WGD}$ a weight-graded vector space. The grading convention from \eqref{Eq:Duals} is the \emph{cohomological grading convention}, which differs from the convention \eqref{Eq:StdGrading} for maps $f: W \rightarrow \R$ by degree reversal (for this, see Definition~\ref{Def:DegreeShift}).

We identify $W^{\GD}$ with the subspace of $W^{\LD}$ generated by homogenous maps and~$W^{\WGD}$ with the subspace of $W^{\LD}$ generated by maps which are non-zero only on finitely many~$W_k^d$; hence, under this identification, we have the tower of inclusions
\[ W^{\WGD} \subset W^{\GD} \subset W^{\LD}.\]
\end{Definition}

% Pick a forgetful functor from the category of weight-graded to the category of graded. And a functor back by embedding graded vector spaces into weight graded.

\begin{Definition}[Koszul sign] \label{Def:Koszul}
Let $k\ge 1$, and let $\sigma\in \Perm_k$ be a permutation on~$k$ elements, i.e., a bijection of the set $\{1,\dotsc,k\}$. For $i=1$, $\dotsc$, $k$,  let $a_i$ and $b_i$ be graded symbols of degrees~$\Abs{a_i}$ and~$\Abs{b_i}$, respectively. We denote by
\[\varepsilon(\sigma,a) \quad\text{and}\quad\varepsilon(a,b)\]
the \emph{Koszul signs} of the transformations
 \[ a_1 \dots a_k \longmapsto a_{\sigma_1^{-1}} \dots a_{\sigma_k^{-1}} \quad \text{and} \quad a_1 \dots a_k b_1 \dots b_k \longmapsto a_1 b_1 \dots a_k b_k, \]
respectively. Here $\sigma_i^{-1} \coloneqq \sigma^{-1}(i)$. The Koszul sign is computed by permuting the left-hand side to the right-hand side via transpositions of two adjacent elements such that whenever we transpose two graded symbols, e.g., $a_i \longleftrightarrow a_{j}$, we multiply with $(-1)^{\Abs{a_i}\Abs{a_{j}}}$.
\end{Definition}

We emphasize that the Koszul sign depends only on the initial and the final order of the graded symbols and not on the sequence of transpositions; this is easy to show.

%We have
%\[\begin{aligned}
%W^{\WGD} = W^{\GD} &\Equiv \forall d\in \Z\ \exists I\subset \N_0, \Abs{I}<0\ \forall k\in \N_0 \backslash I:  W_k^d = 0, \\
%W^{\GD} = W^* &\Equiv \exists I \subset \Z, J \subset \N_0, \Abs{I}, \Abs{J}<\infty\ \forall (d,k)\in \Z\times \N_0 \backslash I\times J: W_k^d=0.
%\end{aligned}\]
%In particular, $W^* = W^{\GD} = W^{\WGD}$ if $\Dim(V)<\infty$.

\begin{Definition}[Degree shift and grading reversal]\label{Def:DegreeShift}
Let $A\in \Z$. The \emph{degree shift by $A$} is a functor which associates to a graded vector space $W$ the graded vector space $W[A]$ with degree-$d$ components
\[ W[A]^d \coloneqq W^{d+A}\quad \text{for all }d\in \Z.\]%In the following remark, we discuss two interpretations of the degree shift.
There is the canonical degree shift morphism
\begin{equation}\label{Eq:DegreeShift}
 W\longrightarrow W[A]
\end{equation}
of degree $-A$ mapping $W^d$ identically to $W[A]^{d-A}$. We view this morphism as multiplication from the left with a formal symbol $\Susp_A$ of degree $\Abs{\Susp_A}=-A$, so that~\eqref{Eq:DegreeShift} can be written as $w\in W \longmapsto \Susp_A w\in W[A]$.

Given graded vector spaces $W_1$, $W_2$ and constants $A_1$, $A_2\in \Z$, we associate to a morphism $f: W_1 \rightarrow W_2$ its \emph{degree shift} $f: W_1[A_1] \rightarrow W_2[A_2]$ by defining\footnote{This convention is not optimal; see Remark~\ref{Rem:BadConvention}.}
\begin{equation}\label{Eq:DegreeShiftConv}
f(\Susp_{A_1} w) \coloneqq \Susp_{A_2} f(w)\quad\text{for all } w \in W_1.
\end{equation}
Notice that if $f:W_1 \rightarrow W_2$ has degree $\Abs{f}$, then $f: W_1[A_1] \rightarrow W_2[A_2]$ has degree $\Abs{f} + A_1 - A_2$.

The \emph{grading reversal} $r$ is a functor which associates to a graded vector space~$W$ the graded vector space $r(W)$ with
\[ r(W)^d \coloneqq W^{-d}\quad\text{for all }d\in \Z. \]
There is the canonical morphism $W\rightarrow r(W)$ mapping $W^d$ identically to $W^{-d}$ for every $d\in \Z$. The degree reversal of a morphism $f: W_1 \rightarrow W_2$ is the morphism $f: r(W_1) \rightarrow  r(W_2)$ defined by conjugating $f$ with the canonical morphism. If $\Abs{f}$ is the degree of $f: W_1 \rightarrow W_2$, then $-\Abs{f}$ is the degree of $f: r(W_1) \rightarrow  r(W_2)$.
\end{Definition}

In our main reference \cite{Cieliebak2015}, they view $W$ and $W[A]$ as one vector space with two different gradings $\Deg(\cdot)$ and $\Abs{\cdot}$, respectively; these are related by
\begin{equation*}
%\label{Eq:DegreeRel}
\Abs{w} = \Deg(w) - A \quad\text{for all homogenous }w\in W.
\end{equation*}
%In particular, writing $w\in W$ and $w\in W[A]$ is for them equivalent.
%This is the ``passive'' point of view on degree shifts.
On the other hand, we think of $W$ and $W[A]$ as of two different graded vector spaces and never use the same symbol for an element $w\in W$ and its degree shift $\Susp_A w \in W[A]$. %It is the ``active'' point of view.
It allows us to use just one notation~$\Abs{\cdot}$ for the gradings on both~$W$ and~$W[A]$. However, in order to preserve compatibility with~\cite{Cieliebak2015}, we will also sometimes use the notation $\Deg(w)$ (in the exponent just $(-1)^w$) for the degrees on $W$.

For graded vector spaces $W_1$, $\dotsc$, $W_k$ and constants $A_1$, $\dotsc$, $A_k\in \Z$, we identify
\[ W_1[A_1]\otimes \dotsb \otimes W_k[A_k] \simeq (W_1\otimes \dotsb \otimes W_k)[A_1+\dotsb+A_k] \] using the \emph{Koszul convention for the tensor product}; for homogenous elements $w_1 \in W_1$,~$\dotsc$, $w_k \in W_k$, it reads
\begin{equation} \label{Eq:KoszulTensor}
\Susp_{A_1} w_1 \otimes \dotsb \otimes \Susp_{A_k} w_k = \varepsilon(\Susp_A,w) \underbrace{\Susp_{A_1}\dots\Susp_{A_k}}_{\displaystyle \mathclap{\eqqcolon \Susp_{A_1 + \dotsb + A_k}}\rule{0ex}{2ex}} w_1 \otimes \dotsb \otimes w_k.
\end{equation}
%We understand the product $\Susp_{A_1}\dots\Susp_{A_k}$ as one formal symbol of degree $-(A_1+\dotsb+A_k)$.
%we can abbreviate it by $\Susp_{\vec{A}}\coloneqq \Susp_{A_1} \dots \Susp_{A_k}$, and when $A_1 = \dotsb = A_k$, then we write $\Susp_A^k$ instead.
If $A_1 = \dotsb = A_k \eqqcolon A$ is fixed in the context, which is our usual case, we omit the subscript~$A$ and write just $\Susp$.

In the case of the multilinear map $f: W_1\otimes \dotsb \otimes W_k \rightarrow V_1\otimes \dotsb \otimes V_l$, the combination of~\eqref{Eq:DegreeShiftConv} and~\eqref{Eq:KoszulTensor} gives for $f: W_1[A_1]\otimes \dotsb\otimes W_k[A_k] \rightarrow V_1[B_1]\otimes \dotsb\otimes V_l[B_l]$ the following:
\begin{equation}\label{Eq:DegreeShiftConvII}
 f(\Susp_{A_1 +\dotsb + A_k} w_1 \otimes \dotsb \otimes w_k) = \Susp_{B_1 + \dotsb + B_l} f(w_1 \otimes \dotsb \otimes w_k).
\end{equation}

\begin{Remark}[Why is this sign convention bad?]\label{Rem:BadConvention}
Let us illustrate that \eqref{Eq:DegreeShiftConvII} is not compatible with the following standard Koszul rule:
\begin{equation*}
(K):\qquad (f_1 \otimes f_2)(w_1 \otimes w_2) = (-1)^{\Abs{f_2}\Abs{w_1}} f_1(w_1) \otimes f_2(w_2).
\end{equation*}
On one hand, we get
\[\begin{aligned}
(f_1 \otimes f_2)(\Susp^2 w_1 \otimes w_2) &\overset{\eqref{Eq:DegreeShiftConvII}}{=} \Susp^2 (f_1\otimes f_2)(w_1 \otimes w_2) \\
& \overset{(K)}{=} (-1)^{\Abs{f_2}\Abs{w_1}} \Susp^2 f_1(w_1) \otimes f_2(w_2)  \\
& \overset{\eqref{Eq:KoszulTensor}}{=} (-1)^{\Abs{f_2}\Abs{w_1} + A(\Abs{f_1} + \Abs{w_1})} \Susp f_1(w_1) \otimes \Susp f_2(w_2).
\end{aligned}\]
On the other hand, we get
\[\begin{aligned}
(f_1 \otimes f_2)(\Susp^2 w_1 \otimes w_2) &\overset{\eqref{Eq:KoszulTensor}}{=} (-1)^{A\Abs{w_1}}(f_1 \otimes f_2)(\Susp w_1 \otimes \Susp w_2)\\
&\overset{(K)}{=} (-1)^{A\Abs{w_1} + \Abs{f_2}(A+\Abs{w_1})} f_1(\Susp w_1) \otimes f_2(\Susp w_2)\\ &\overset{\eqref{Eq:DegreeShiftConvII}}{=}(-1)^{A\Abs{w_1}+ \Abs{f_2}(A+\Abs{w_1})} \Susp f_1(w_1) \otimes \Susp f_2(w_2).
\end{aligned}\]
The results differ by $(-1)^{A(\Abs{f_1}+\Abs{f_2})}$. Therefore, we can not use (K) to identify the tensor product $\Hom(W_1,V_1)\otimes \Hom(W_2,V_2)$ with a subspace of $\Hom(W_1\otimes W_2, V_1\otimes V_2)$ in general. We will rather define an ad-hoc pairing in the case where we need it (see Definition~\ref{Def:Pairings}).

Another caveat is that in the case of the tensor product, the degree shift by $A_1$ followed by the degree shift by~$A_2$ is not the same as the degree shift by $A_1 + A_2$. Indeed, we compute
\[\begin{aligned}
(\Susp_{A_1 + A_2}w_1) \otimes (\Susp_{A_1 + A_2}w_2) &=
(\Susp_{A_2} \Susp_{A_1}w_1) \otimes (\Susp_{A_2}\Susp_{A_1} w_2) \\ &= (-1)^{A_2(A_1 + \Abs{w_1})}\Susp_{A_2}^2 (\Susp_{A_1} w_1) \otimes (\Susp_{A_1} w_2) \\
&= (-1)^{A_2 A_1 + (A_1 + A_2)\Abs{w_1}} \Susp_{A_2}^2 \Susp_{A_1}^2 (w_1 \otimes w_2) \\ &= (-1)^{A_2 A_1 + (A_1 + A_2)\Abs{w_1}} \Susp_{2(A_1 + A_2)} (w_1 \otimes w_2),
\end{aligned}\]
which differs by $(-1)^{A_1 A_2}$ from the direct degree shift by $A_1 + A_2$. Therefore, we have to always remember the vector spaces which we started with and the sequence of degree shifts.

Note that we also have the unnatural ``$\Susp_{A_1} \Susp_{A_2} = \Susp_{A_1 + A_2} = \Susp_{A_2} \Susp_{A_1}$'' due to \eqref{Eq:KoszulTensor}.
\end{Remark}

\begin{Remark}[Is there a better sign convention?]
The author originally respected the Koszul rule for the algebra with formal symbols and considered the following map $\Susp^{l}_*\widebar{\Susp}^{k*} f: W[A]^{\otimes k} \rightarrow V[A]^{\otimes l}$ as the degree shift of $f: W^{\otimes k} \rightarrow V^{\otimes l}$:
\begin{equation}\label{Eq:AltConv}
(\Susp^{l}_*\widebar{\Susp}^{k*} f)(\Susp^{k} w_1 \otimes \dotsb \otimes w_k ) = (-1)^{k \Abs{f}A + \frac{1}{2}k(k-1) A} \Susp^l f(w_1 \otimes \dotsb \otimes w_k).
\end{equation}
Here $\DeSusp$ denotes the ``inverse'' of $\Susp$ with $\Abs{\widebar{\Susp}} = - \Abs{\Susp}$, $\Susp_*^l f = \Susp^l \circ f$ is the post-composition, $\DeSusp^{k*}f = (-1)^{k A \Abs{f}} f\circ \DeSusp^k$ the pre-composition, and the sign $ \varepsilon(\Susp, \DeSusp) = (-1)^{\frac{1}{2}k(k-1)A}$ comes from the ``collision'' $\DeSusp_1\dots \DeSusp_k \Susp_1 \dots \Susp_k \mapsto \DeSusp_1 \Susp_1 \dots \DeSusp_k \Susp_k$.

However, the author did not manage to reprove the theory in~\cite{Cieliebak2015} using~\eqref{Eq:AltConv} (because of too many ``external'' signs appearing and a problem with disconnected graphs). A~motivation to try a different sign convention was to explain some artificial signs in~\cite{Cieliebak2015} and formulate their coordinate constructions invariantly in order to generalize them to the ``continuous'' de Rham case.

It might be possible to deduce a ``universal'' sign convention ``respecting'' the Koszul rules by considering the category of chain complexes and graded morphisms $\mathcal{C}$ as the category enriched in the closed monoidal category of chain complexes and chain maps of degree~$0$. One can then define the enriched degree shift functor $\Susp_{A}: \mathcal{C} \rightarrow \mathcal{C}$, embed $\mathcal{C}^{\otimes k} \subset \mathcal{C}$ using~$(K)$ and study enriched natural transformations in the algebra of functors consisting of tensor products and compositions of $\Susp_{A}$, $\Hom(\cdot, \cdot)$ and the dual $*$. The question is whether the sign rules for degree shifts, in particular  \eqref{Eq:AltConv}, are uniquely determined by the requirements on enriched functors and enriched natural transformations.

Another idea for how to specify the degree shift convention~\eqref{Eq:AltConv} is the observation that maps $f: W^{\otimes k}\rightarrow W^{\otimes l}$ under consideration usually form an algebra $\Prop \rightarrow \End_W$ of a certain PROP $\Prop$ over $W$; here $\End_W$ denotes the endomorphism PROP. Suppose that there is a natural notion of the degree shift $\Prop[A]$ of a PROP $\Prop$ and a canonical degree shift morphism $\Prop \rightarrow \Prop[A]$. The PROPs $(\End_W)[A]$ and $\End_{W[A]}$ are better to be isomorphic, and any intelligent degree shift convention $\psi_{k,l}: \Hom(W^{\otimes k},W^{\otimes l})[A(k-l)] \rightarrow \Hom(W[A]^{\otimes k},W[A]^{\otimes l})$ should induce an isomorphism of the PROPs $(\End_W)[A]$ and $\End_{W[A]}$.
\end{Remark}
%We will also use two different formal symbols $\Susp$ and $\SuspU$ to shift the degrees.
%\begin{Question}
%Is it possible to reprove \cite{Wieliebak2015} using \eqref{Eq:AltWonv}?
%\end{Question}

\begin{Definition}[Standard action of permutations]\label{Def:Permutations}
For $k\ge 1$ and $\sigma\in \Perm_k$ ($\coloneqq$\,the group of permutations on $k$ elements), we define the \emph{standard action of $\sigma$} on $W^{\otimes k}$ by
\begin{equation}\label{Eq:Perm}
\sigma(w_1 \otimes \dotsb \otimes w_k) \coloneqq  \varepsilon(\sigma,w) w_{\sigma_1^{-1}}\otimes \dotsb \otimes w_{\sigma_k^{-1}}
\end{equation}
for all homogenous $w_1$, $\dotsc$, $w_k\in W$.
\end{Definition}

Notice that the $i$-th vector is permuted to the $\sigma_i$-th place --- this is the ``active'' convention for permutations.

\begin{Definition}[Symmetric algebra]\label{Def:SymAlgebra}
Let $\Ten(V)\coloneqq \bigoplus_{k\ge 0} V^{\otimes k}$ be the tensor algebra over a graded vector space~$V$. The \emph{symmetric algebra} over $V$ is defined by $\Sym(V)\coloneqq \bigoplus_{k\ge 0} \Sym_k(V)$, where
\[ \Sym_k(V) \coloneqq V^{\otimes k} \bigl/ \sum_{\sigma\in \Perm_k} \Im(\Id-\sigma)\quad(\eqqcolon \Perm_k\text{-coinvariants}). \]
It is a weight-graded vector space with components denoted by $(\Sym_k V)^d$ for all $d\in \Z$ and $k\in \N_0$. Note that $\Sym_0 V = \R$ has degree $0$ by definition. Consider the canonical projection
\[\begin{aligned}
\pi : \Ten(V) &\longrightarrow \Sym(V) \\
v_1\otimes \dotsb \otimes v_k &\longmapsto v_1\dotsb v_k.
\end{aligned}\]
%The dot $\cdot$ indicates the symmetric product.
If $v_i\in V$ are homogenous, we call $v_1 \dotsb v_k$ a \emph{generating word}; we have
\[ v_1 \dotsb  v_k = \varepsilon(\sigma,v) v_{\sigma_1^{-1}} \dotsb v_{\sigma_k^{-1}}\quad \text{for every }\sigma\in \Perm_k. \]
Let $\iota: \Sym(V) \rightarrow \Ten(V)$ be the section of $\pi$ defined by
\[ \iota(v_1\dotsb v_k) \coloneqq \frac{1}{k!}\sum_{\sigma\in\Perm_k} \varepsilon(\sigma,v) v_{\sigma_1^{-1}}\otimes \ldots \otimes v_{\sigma_k^{-1}}. \]
We use it to identify $\Sym(V)$ with the subspace of symmetric tensors
\[ \iota(\Sym_k(V)) = \bigcap_{\sigma\in \Perm_k} \Ker(\Id - \sigma) \subset \Ten_k(V)\quad(\eqqcolon\Perm_k\text{-invariants}). \]
\end{Definition}

\begin{Definition}[Filtrations] \label{Def:Filtrations}
Let $W$ be a graded vector space. A filtration of~$W$ is a collection of linear subspaces $\Filtr^\lambda W \subset W$ for $\lambda\in \R$ such that we have either
\begin{itemize}
\item $\Filtr^{\lambda_1}W\subset \Filtr^{\lambda_2}W$ for all $\lambda_1 \le \lambda_2$\quad$\Longleftrightarrow:$\quad\emph{increasing filtration}, or
\item  $\Filtr^{\lambda_1}W\supset \Filtr^{\lambda_2}W$ for all $\lambda_1 \le \lambda_2$\quad$\Longleftrightarrow:$\quad\emph{decreasing filtration.}
\end{itemize}
We will assume that our filtrations are \emph{graded} in the following sense:
\[ \forall \lambda\in \R:\quad \Filtr^\lambda W = \bigoplus_{d\in \Z} \Filtr^\lambda W^d,\quad \text{where}\quad\Filtr^\lambda W^d \coloneqq \Filtr^\lambda W \cap W^d.\]
A filtration $\Filtr^\lambda W$ is called:
\begin{align*}
 \text{\emph{exhaustive}}&\quad:\Equiv\quad\bigcup_{\lambda\in \R} \Filtr^\lambda W = W;\\
 \text{\emph{Hausdorff}} &\quad:\Equiv\quad\bigcap_{\lambda\in \R} \Filtr^\lambda W = 0;\\
 \text{\emph{$\Z$-gapped}} &\quad:\Equiv\quad\Filtr^\lambda W = \Filtr^{\lfloor\lambda\rfloor} W\text{ for all }\lambda \in \R;\\[3\jot]
 \text{\emph{bounded from below}}&\quad:\Equiv\quad\exists \lambda \in \R: \Filtr^\lambda W =0;\\[3\jot]
 \text{\emph{bounded from above}}&\quad:\Equiv\quad\exists \lambda\in \R: \Filtr^\lambda W =W.
\end{align*}

Given a graded vector space $W$ filtered by a $\Z$-gapped filtration $\Filtr^\lambda W$, we associate to it the bi-graded vector space
\[ \Gr(W) = \bigoplus_{d\in\Z}\bigoplus_{\lambda\in \Z} \Gr(W)_\lambda^d \]
called the \emph{graded module} whose components are given as follows:\footnote{The definition is made in such a way that if $r$ is the functor which reverses $\lambda$, i.e., $r(\Filtr)^\lambda = \Filtr^{-\lambda}$, then it holds $r(\Gr(\Filtr)) = \Gr(r(\Filtr))$. }\Modify[caption={DONE Graded module},noline]{Should not the grading of $\Gr$ be shitfted? I propose $gr_k = F_k/F_{k\pm 1}$ because $r(gr(\tilde{F})) = gr(F)$ for the degree reversed filtration.}
\[ \forall d, \lambda\in \Z: \quad \Gr(W)_\lambda^d \coloneqq \begin{cases}
                   \Filtr^\lambda W^d /\Filtr^{\lambda-1} W^d & \text{for increasing }\Filtr^\lambda W,\\
                   \Filtr^{\lambda} W^d / \Filtr^{\lambda+1} W^d & \text{for decreasing } \Filtr^\lambda W.
                 \end{cases}\]
We naturally extend a filtration over degree shifts, graded duals, direct sums, tensor products and symmetric products as follows: \allowdisplaybreaks
\begin{align*}
\Filtr^\lambda W[A]^d &\coloneqq \Filtr^\lambda W^{d+A},\\[3.5\jot]
\Filtr^\lambda (W^{\GD})^d &\coloneqq \{\psi\in W^{d*} \mid \Restr{\psi}{\Filtr^\lambda W} = 0\}, \\[3.5\jot]
\Filtr^\lambda\bigl(\bigoplus_{i\in I} W_i\bigr)^d &\coloneqq \bigoplus_{i\in I} \Filtr^{\lambda} W_i^d, \\[2\jot]
\Filtr^{\lambda}(W_1 \otimes \dotsb \otimes W_k)^d &\coloneqq \bigoplus_{\substack{d_1, \dotsc, d_k\in \Z \\ d_1 + \dotsb + d_k = d}}\ \sum_{\substack{\lambda_1, \dotsc, \lambda_k \in \R \\ \lambda_1 + \dotsb + \lambda_k = \lambda}} \Filtr^{\lambda_1} W_1^{d_1} \otimes \dotsb \otimes \Filtr^{\lambda_k} W_k^{d_k},\\
\Filtr^\lambda (\Sym_k V)^d &\coloneqq \pi(\Filtr^\lambda(V^{\otimes k})^d),
\end{align*}
where $\pi: \Ten(V) \rightarrow \Sym(V)$ is the canonical projection. The ground field $\R$ is filtered by the trivial filtration:
\begin{equation}\label{Eq:TrivFiltr}
\Filtr^\lambda \R \coloneqq \begin{cases} \R & \lambda\le 0, \\ 0 & \lambda >0. \end{cases}
\end{equation}
If $(W,\Bdd)$ is a filtered chain complex, we filter the homology as follows:
\[ \forall \lambda \in \R, d\in \Z: \quad \Filtr^\lambda \H_d(W,\Bdd) \coloneqq \{\alpha \in \H_d(C,\Bdd) \mid \exists w\in \alpha: w\in \Filtr^\lambda W^d \}. \]
\end{Definition}

\begin{Definition}[Completions]\label{Def:Completion}
Let $W$ be a graded vector space filtered by a decreasing filtration $\Filtr^\lambda W$. The \emph{filtration degree} of $w\in W$ is defined by
\[ \Norm{w} \coloneqq \sup\{ \lambda\in \R \mid w\in \Filtr^\lambda W\}. \]
The filtration degree of a linear map $f: W_1 \rightarrow W_2$ is defined by
\[ \Norm{f} \coloneqq \sup \{ \lambda\in \R \mid \Norm{f(w)} \ge \Norm{w} + \lambda\ \forall w\in W_1\}. \]
We say that the \emph{filtration degree is finite} if $\Norm{f}>-\infty$. Note that $\Norm{0} = \infty$.

The \emph{completion} of $W$ is the graded vector space
\[ \hat{W}\coloneqq \bigoplus_{d\in \Z} \hat{W}^d, \]
where for all $d\in \Z$  we define
\[ \hat{W}^d \coloneqq \Bigl\{ \sum_{i=0}^\infty w_i\ \Bigl|\   \forall i\in \N_0: w_i\in W^d; \Norm{w_i} \to \infty \text{ as }i\to \infty \Bigl\}\Bigl/\sim.
% \in \Filtr^{\lambda_i} W^d, \lambda_i \rightarrow \infty\text{ as }i\to \infty\Bigr\} \Bigl/ \sim.
\]
Here $\sum_{i=0}^\infty w_i \sim \sum_{i=0}^\infty w_i'$ if and only if $\Norm{\sum_{i=0}^n (w_i - w_i')}\to \infty$ as $n\to \infty$.\footnote{\label{Footnote:Compl}In fact, $\hat{W}$ is the inverse limit $\varprojlim_\lambda^{\mathrm{gr}}(W/\Filtr^\lambda W)$ in the category of graded vector spaces and~$\hat{W}^d$ the inverse limit $\varprojlim_\lambda(W^d/\Filtr^\lambda W^d)$ in the category of vector spaces. As a side-remark, if we forget the grading on $W$, we might also consider $\varprojlim_\lambda (W/\Filtr^\lambda W)$, which would be a vector space containing~$\hat{W}$ as a subspace\vphantom{$W^d$}.}
The completion~$\hat{W}$ is canonically filtered by the filtration $\Filtr^\lambda \hat{W}$ defined as follows:
\[ \forall \lambda\in \R, d\in \Z: \quad \Filtr^\lambda\hat{W}^d\coloneqq \Bigl\{\sum_{i=0}^\infty w_i \in \hat{W}^d \ \Bigr|\ \forall i\in \N_0: w_i \in \Filtr^\lambda W^d \Bigr\}. \]
We denote the completion of $W_1 \otimes \dotsb \otimes W_k$ by $W_1 \COtimes \dotsb \COtimes W_k$ and the completion of $\Sym_k V$ by $\hat{\Sym}_k V$.

A map $f: W_1 \rightarrow W_2$ of finite filtration degree
\emph{extends continuously} to a linear map $f: \hat{W}_1 \rightarrow \hat{W}_2$; this continuous extension is defined by
\[ f\Bigl(\sum_{i=0}^\infty w_i\Bigr)\coloneqq \sum_{i=0}^\infty f(w_i)\quad\text{for all }\sum_{i=0}^\infty w_i \in \hat{W}. \]
%For all $k\ge 0$, we denote by $\hat{E}_k W$ the completion of the graded vector space~$E_k W$ with respect to the filtration
%\[ \Filtr_\lambda E_k W = \sum_{\substack{\lambda_1, \dotsc, \lambda_k\in \R \\ \lambda_1+ \dotsb + \lambda_k = \lambda}} \pi(\Filtr_{\lambda_1}W[1] \otimes \dotsb \otimes \Filtr_{\lambda_k}W[1]), \]
%where $\pi: W[1]^{\otimes k} \rightarrow E_k W$ is the canonical projection. We set $\hat{E}_0 W \coloneqq \R$.
\end{Definition}

\begin{Remark}[Completed tensor product]\label{Rem:ComplTens}
Using Proposition~\ref{Prop:IsoCrit} below, one can show that the \emph{completed tensor product} $\COtimes$ is associative and that $W_1 \COtimes W_2 \simeq \hat{W}_1 \COtimes \hat{W}_2$. By refining this argument, one can show that $\hat{\Sym}_k V \simeq \hat{\Sym}_k\hat{V}$ for any $k\in \N$.
\end{Remark}

A weight-graded vector space $W$ is canonically \emph{filtered by weights:}
\begin{equation}\label{Eq:FiltrWeights}
\forall \lambda\in \R, d\in \Z:\quad\Filtr^\lambda W^d \coloneqq \bigoplus_{k\le \lambda} W_k^d.
\end{equation}
This filtration is $\Z$-gapped, exhaustive, Hausdorff, increasing and bounded from below. The induced filtration on the graded dual $W^{\GD}$ is $\Z$-gapped, Hausdorff, decreasing and bounded from above (and thus automatically exhaustive). It holds $\Gr(W) \simeq W$, and it is easy to see from \eqref{Eq:Duals} that the canonical map $W^{\WGD} \rightarrow W^{\GD}$ induces the isomorphism
\[ \widehat{W^{\WGD}} \simeq W^{\GD}. \]
We also see that the condition
\[ (WG0): \quad \forall d\in \Z\ \exists J\subset \N_0, \Abs{J}<\infty\ \forall k\in \N_0\backslash J: \quad W_k^d = 0 \]
is equivalent to $W^{\WGD}= W^{\GD}$.

A useful tool to compare completions is the following proposition:

\begin{Proposition}[{\cite[Proposition 7.3.7]{Fresse}}, Isomorphism criterion]\label{Prop:IsoCrit}
Let $W_1$ and~$W_2$ be graded vector spaces filtered by $\Z$-gapped filtrations which are decreasing and bounded from above. Suppose that $f: W_1 \rightarrow W_2$ is a filtration preserving homogenous linear map. Then the continuous extension $f: \hat{W}_1 \rightarrow \hat{W}_2$ is an isomorphism if and only if the induced map $f: \Gr(W_1) \rightarrow \Gr(W_2)$ is an isomorphism.
\end{Proposition}
\begin{proof}
The implication from the right to the left is obtained from the diagram
\[\begin{tikzcd}
0 \arrow{r} & \Gr(W_1)_\lambda \arrow[hook]{r} \arrow{d}{f} & W_1/\Filtr^{\lambda + 1}W_1 \arrow[two heads]{r} \arrow{d}{f} & W_1/\Filtr^{\lambda} W_1 \arrow{r}   \arrow{d}{f} & 0 \\
0 \arrow{r} & \Gr(W_2)_\lambda \arrow[hook]{r} & W_2/\Filtr^{\lambda+1}W_2 \arrow[two heads]{r} & \arrow{r}W_2/\Filtr^{\lambda} W_2   & 0
\end{tikzcd}\]
by induction using the definition of $\hat{W}$ as the inverse limit of $W/\Filtr^\lambda W$ (see Footnote \ref{Footnote:Compl} on page \pageref{Footnote:Compl}). The other implication follows from $\Filtr^\lambda\hat{W}/\Filtr^{\lambda-1}\hat{W}\simeq\Filtr^\lambda W/\Filtr^{\lambda-1}W$.
\end{proof}

For a graded vector space $W$ filtered by a $\Z$-gapped filtration, consider the following conditions:
\begin{equation}\label{Eq:WGs}
\begin{aligned}
(WG1):\quad& \forall \lambda\in \Z\ \exists I \subset \Z, \Abs{I}<\infty\ \forall d\in \Z\backslash I:& \Gr(W)_\lambda^d &= 0, \\
(WG2):\quad & \forall d, \lambda\in \Z:& \dim(\Gr(W)_\lambda^d) &< \infty.
\end{aligned}
\end{equation}

\begin{Lemma}[Completion of symmetric powers of the graded dual]\label{Lem:Terrible}
Let $W$ be a graded vector space filtered by an exhaustive $\Z$-gapped filtration~$\Filtr^\lambda W$ which is increasing and bounded from below. If (WG1) \& (WG2) are satisfied, then the natural map $\Sym_k(W^{\GD}) \rightarrow (\Sym_k W)^{\GD}$ induces the isomorphism
\[ \hat{\Sym}_k(W^{\GD}) \simeq  (\Sym_k W)^{\GD} \quad\text{for every }k\in \N.\]
Note that we filter graded duals by the induced filtration from Definition~\ref{Def:Filtrations}.
\end{Lemma}
\begin{proof}
The natural map $\Sym_k(W^{\GD}) \rightarrow (\Sym_k W)^{\GD}$ is clearly filtration preserving, and hence it extends continuously to a map of completions. The target space $(\Sym_k W)^{\GD}$ is already complete (the dual space $W^{\GD}$ is complete, provided that the filtration of~$W$ is exhaustive), and thus we obtain the map $\hat{\Sym}_k(W^{\GD}) \rightarrow (\Sym_k W)^{\GD}$. According to Proposition~\ref{Prop:IsoCrit}, this map is an isomorphism if and only if the induced map $\Gr(\Sym_k(W^{\GD})) \rightarrow \Gr((\Sym_k W)^{\GD})$ is. This is shown by the following computation (the maps involved are natural in at least one direction):
%We will show that it is an isomorphism in the following paragraph.
%Let $d$, $\lambda\in \Z$. In the following computation, we will use the notation
%\[ \vec{d} \coloneqq (d_1, \dotsc, d_k), \quad \bigoplus_{\Abs{\vec{d}} = d} \dotsb = \bigoplus_{\substack{d_1, \dotsc, d_k \in\Z \\ d_1 + \dotsb + d_k = d}} \dotsb\]
%and likewise for $\lambda$ instead of $d$ and $\sum$ instead of $\oplus$. We will not write down the maps because every indicated isomorphism is natural at least in one direction. We compute:
\allowdisplaybreaks
\begin{align*}
\frac{\Filtr^\lambda ({W^{\otimes k}}^{\GD})^d}{\Filtr^{\lambda+1} ({W^{\otimes k}}^{\GD})^d} &\simeq \frac{\Filtr^\lambda (W^{\otimes k})^{d*}}{\Filtr^{\lambda+1} (W^{\otimes k})^{d*}} \simeq  \Bigl(\frac{\Filtr^{\lambda+1}(W^{\otimes k})^d}{\Filtr^{\lambda}(W^{\otimes k})^d}\Bigr)^* \\
 &\simeq \Biggl( \frac{\bigoplus_{\Abs{\vec{d}}= d} \sum_{\Abs{\vec{\lambda}}= \lambda + 1} \Filtr^{\lambda_1} W^{d_1} \otimes \dotsb \otimes \Filtr^{\lambda_k} W^{d_k}}{\bigoplus_{\Abs{\vec{d}} = d}\sum_{\Abs{\vec{\lambda}} = \lambda} \Filtr^{\lambda_1} W^{d_1} \otimes \dotsb \otimes \Filtr^{\lambda_k} W^{d_k}}\Biggr)^* \\
&\simeq \Biggl( \bigoplus_{\Abs{\vec{d}}= d} \frac{\sum_{\Abs{\vec{\lambda}} = \lambda + 1} \Filtr^{\lambda_1} W^{d_1} \otimes \dotsb \otimes \Filtr^{\lambda_k} W^{d_k}}{\sum_{\Abs{\vec{\lambda}} = \lambda} \Filtr^{\lambda_1} W^{d_1} \otimes \dotsb \otimes \Filtr^{\lambda_k} W^{d_k}}\Biggr)^* \\
&\simeq\Bigl( \bigoplus_{\Abs{\vec{d}} = d} \bigoplus_{\Abs{\vec{\lambda}}=\lambda} \frac{\Filtr^{\lambda_1 + 1}W^{d_1}}{\Filtr^{\lambda_1} W^{d_1}} \otimes \dotsb \otimes \frac{\Filtr^{\lambda_k+1}W^{d_k}}{\Filtr^{\lambda_k} W^{d_k}}\Bigr)^*\\
&\simeq\Bigl( \bigoplus_{\Abs{\vec{\lambda}}=\lambda} \bigoplus_{\Abs{\vec{d}} = d} \frac{\Filtr^{\lambda_1 + 1} W^{d_1}}{\Filtr^{\lambda_1} W^{d_1}} \otimes \dotsb \otimes \frac{\Filtr^{\lambda_k + 1} W^{d_k}}{\Filtr^{\lambda_k} W^{d_k}}\Bigr)^* \\
&\mathclap{\substack{\Z-\text{gapped}  \\[1ex] \&\ \text{bounded below}  \\[1ex] \&\ (WG1)}\rightarrow\rule{7.7em}{0pt}}\simeq  \bigoplus_{\Abs{\vec{\lambda}}= \lambda} \bigoplus_{\Abs{\vec{d}} = d} \Bigl( \frac{\Filtr^{\lambda_1 + 1} W^{d_1}}{\Filtr^{\lambda_1} W^{d_1}} \otimes \dotsb \otimes \frac{\Filtr^{\lambda_k + 1} W^{d_k}}{\Filtr^{\lambda_k} W^{d_k}}\Bigr)^* \\
&\mathclap{{\scriptstyle (WG2)}\rightarrow\rule{4em}{0pt}}\simeq  \bigoplus_{\Abs{\vec{\lambda}}= \lambda} \bigoplus_{\Abs{\vec{d}} = d}  \Bigl( \frac{\Filtr^{\lambda_1 + 1} W^{d_1}}{\Filtr^{\lambda_1} W^{d_1}}\Bigr)^* \otimes \dotsb \otimes \Bigl( \frac{\Filtr^{\lambda_k + 1} W^{d_k}}{\Filtr^{\lambda_k} W^{d_k}}\Bigr)^* \\
&\simeq \bigoplus_{\Abs{\vec{d}} = d} \bigoplus_{\Abs{\vec{\lambda}}=\lambda} \frac{\Filtr^{\lambda_1}(W^{\GD})^{d_1}}{\Filtr^{\lambda_1 + 1}(W^{\GD})^{d_1}}\otimes \dotsb \otimes \frac{\Filtr^{\lambda_k}(W^{\GD})^{d_k}}{\Filtr^{\lambda_k + 1}(W^{\GD})^{d_k}} \\
%&\simeq \bigoplus_{\Abs{\vec{d}} = d} \frac{\sum_{\Abs{\vec{\lambda}} = \lambda} \Filtr^{\lambda_1} (W^{\GD})^{d_1} \otimes \dotsb \otimes \Filtr^{\lambda_k} (W^{\GD})^{d_k}}{ \sum_{\Abs{\vec{\lambda}} = \lambda + 1 } \Filtr^{\lambda_1} (W^{\GD})^{d_1} \otimes \dotsb \otimes \Filtr^{\lambda_k} (W^{\GD})^{d_k} } \\
%&\simeq \frac{\bigoplus_{\Abs{\vec{d}} = d} \sum_{\Abs{\vec{\lambda}} = \lambda} \Filtr^{\lambda_1} (W^{\GD})^{d_1} \otimes \dotsb \otimes \Filtr^{\lambda_k} (W^{\GD})^{d_k}}{\bigoplus_{\Abs{\vec{d}}= d} \sum_{\Abs{\vec{\lambda}} = \lambda + 1 } \Filtr^{\lambda_1} (W^{\GD})^{d_1} \otimes \dotsb \otimes \Filtr^{\lambda_k} (W^{\GD})^{d_k} }  \\
&\simeq \frac{\Filtr^{\lambda} ({W^{\GD}}^{\otimes k})^d}{\Filtr^{\lambda + 1} ({W^{\GD}}^{\otimes k})^d}.
\end{align*}
In fact, this computation shows that $\hat{\Ten}_k(W^{\GD}) \simeq (\Ten_k W)^{\GD}$. The conclusion for $\Sym_k$ follows by checking that the maps above are $\Perm_k$-equivariant.
%
%As for $\Sym_k$,
%%using the maps~$\iota$ and~$\pi$ from Definition~\ref{Def:SymAlgebra}
%we have
%\[ \Filtr^\lambda (\Sym_k(W^{\GD})) \simeq \Filtr^\lambda ({W^{\GD}}^{\otimes k}) / \Perm_k \quad \text{and}\quad \Filtr^\lambda (\Sym_k W)^{\GD} \simeq \Filtr^\lambda ({W}^{\otimes k})^{\GD} / \Perm_k. \]
%It is easy to check that the isomorphisms in the computation above are equivariant with respect to the action of $\Perm_k$. It follows that
%\[ \frac{\Filtr^\lambda (\Sym_k (W^{\GD}))^d}{\Filtr^{\lambda+1} (\Sym_k (W^{\GD}))^d} \simeq \frac{\Filtr^\lambda ({W^{\GD}}^{\otimes k})^d }{\Filtr^{\lambda+1} ({W^{\GD}}^{\otimes k})^d}\Bigr/ \Perm_k \simeq \frac{\Filtr^\lambda (W^{\otimes k})^{\GD}}{\Filtr^{\lambda +1} (W^{\otimes  k})^{\GD}} \Bigr/ \Perm_k \simeq \frac{\Filtr^\lambda {(\Sym_k W)^{\GD}}^d}{\Filtr^{\lambda+1} {(\Sym_k W)^{\GD}}^d}. \]
%This proves the lemma.
%%We used here the general fact that if a group $G$ acts on a vector space $V$ by linear maps and $W\subset V$ is an invariant subspace, then $(V/G)/(W/G) \simeq (V/W)/G$.
%%The only if part holds because $(W\otimes W)^* = W^* \otimes W^*$ iff $\Dim(W)<\infty$ and $(\bigoplus_{i\in I} W_i )^* \simeq \bigoplus_{i\in I} W_i^*$ iff $W_i = 0$ for all but finitely many $i\in I$.
\end{proof}

Given a chain complex $(W,\Bdd)$, the boundary operator $\Bdd$ induces the boundary operator $\Bdd_k : W^{\otimes k} \rightarrow W^{\otimes k}$ for all $k\in \N$; for all $w_1$, $\dotsc$, $w_k\in W$, it is defined~by
\begin{equation}\label{Eq:BddExt}
\Bdd_k(w_1 \otimes \dotsb \otimes w_k)\coloneqq \sum_{i=1}^k (-1)^{\Abs{w_1} + \dotsb + \Abs{w_{i-1}}} w_1 \otimes \dotsb \otimes \Bdd w_i \otimes \dotsb \otimes w_k.
\end{equation}
The map $\Bdd_k$ is clearly $\Perm_k$-equivariant, and thus induces the boundary operator $\Bdd_k : \Sym_k W \rightarrow \Sym_k W$.

\begin{Proposition}[K\"unneth formula for completed symmetric cohomology]\label{Prop:Kuenneth}
Let $(W,\Bdd)$ be a $\Z$-graded chain complex over $\R$ filtered by an exhaustive $\Z$-gapped filtration~$\Filtr^\lambda W$ which is increasing and bounded from below. Consider the dual cochain complex $(W^{\GD},\Dd\coloneqq \Bdd^*)$. Suppose that $\Dd$ has finite filtration degree, so that $\Dd_k: \Sym_k(W^{\GD}) \rightarrow \Sym_k(W^{\GD})$ extends continuously to $\Dd_k : \hat{\Sym}_k(W^{\GD}) \rightarrow \hat{\Sym}_k(W^{\GD})$ for every $k\in \N$. If (WG1) \& (WG2) are satisfied, then the natural map $\Sym_k \H(W^{\GD},\Dd) \rightarrow \H(\hat{\Sym}_k(W^{\GD}),\Dd_k)$ induces the isomorphism
\begin{equation*}
%\label{Eq:TTerrible}
\hat{\Sym}_k \H(W^{\GD},\Dd) \simeq \H(\hat{\Sym}_k(W^{\GD}), \Dd_k)\quad \text{for all }k\in \N.
\end{equation*}
\end{Proposition}
\begin{proof}
The natural map $\Sym_k \H(W^{\GD},\Dd) \rightarrow \H(\hat{\Sym}_k W^{\GD},\Dd_k)$ is clearly filtration preserving, and hence it extends continuously to a map of completions. The target space $\H(\hat{\Sym}_k W^{\GD},\Dd_k)$ is already complete (the homology of a complete space is complete), and hence we obtain the map $\hat{\Sym}_k \H(W^{\GD},\Dd) \rightarrow \H(\hat{\Sym}_k W^{\GD},\Dd_k)$. The following facts are easy to verify:
\begin{enumerate}[label=(\arabic*)]
 \item The isomorphism from Lemma~\ref{Lem:Terrible} is an isomorphism of cochain complexes
 \[ (\hat{\Sym}_k W^{\GD}, \Dd_k) \simeq ((\Sym_k W)^{\GD}, \Bdd_k^*). \]
\item If the filtration on~$W$ satisfies (WG1) and (WG2), then the filtration on $\H(W)$ also satisfies (WG1) and (WG2), respectively. Consequently, Lemma~\ref{Lem:Terrible} holds for symmetric powers of $\H(W,\Bdd)^{\GD}$ as well.
\item The Künneth formula $\H(W^{\otimes k}) \simeq \H(W)^{\otimes k}$ implies $\H(\Sym_k W) \simeq \Sym_k \H(W)$ for any $\Z$-graded chain complex $W$ over $\R$.
\item We have $(\H(W))^{\GD} \simeq \H(W^{\GD})$ over $\R$ by the universal coefficient theorem.
\end{enumerate}
Now, we compute
\begin{align*}
\H(\hat{\Sym}_k W^{\GD},\Dd_k ) &
\underset{\substack{\uparrow\rule{0pt}{1.5ex} \\ (1)}}{\simeq}
\H((\Sym_k W)^{\GD}, \Bdd_k^*)
\underset{\substack{\uparrow\rule{0pt}{1.5ex} \\ (4)}}{\simeq}
\H(\Sym_k W, \Bdd_k)^{\GD}
\underset{\substack{\uparrow\rule{0pt}{1.5ex} \\ (3)}}{\simeq}
(\Sym_k \H(W,\Bdd))^{\GD} \\
&\underset{\substack{\uparrow\rule{0pt}{1.5ex} \\ (2)}}{\simeq}
\hat{\Sym}_k (\H(W,\Bdd)^{\GD})
\underset{\substack{\uparrow\rule{0pt}{1.5ex} \\ (4)}}{\simeq}
\hat{\Sym}_k \H(W^{\GD},\Dd).
\end{align*}
%We did not write the maps because at least one direction of every equivalence is induced by a natural map.
This proves the proposition.
\end{proof}

\end{document}


Our type inference program for the $\lambda$-calculus imitates
the following structure.
\begin{gather*}
    \texttt{standard I/O} \xrightarrow{\text{chars}}
    \texttt{lexing} \xrightarrow{\text{tokens}} \texttt{parsing} \\
    \lhook\joinrel\xrightarrow{\text{terms}} \texttt{type-inferring}
    \xrightarrow{\text{type}/\text{error}} \texttt{pretty-printing}
\end{gather*}
where a program as a sequence of characters is first read from the
standard input, tokenized by a lexical analyzer, and parsed into
an abstract syntax tree. The program then infers the type for
the expression. The final
result is then printed to the standard output in a readable format.
This section mainly focuses on the implementation of the type
inference component.
The details on the lexer, parser, and pretty-printer can be consulted
in Appendix A, B, and C.

First, we represent the abstract syntax for the language defined in Section 2
with data types for expressions, types, and type schemes.
\begin{lstlisting}
    data Expr = Tru
               | Fls
               | Zero
               | Var String
               | If Expr Expr Expr
               | Succ Expr
               | Pred Expr
               | IsZero Expr
               | Let String Expr Expr
               | Lambda String Expr
               | App Expr Expr

    data Type = TVar Int
               | Boolean
               | Nat
               | Arr Type Type

    type TVar = Type

    data TypeScheme = ForAll [TVar] TypeScheme
                      | Scheme Type
\end{lstlisting}
The type synonym \lstinline{TVar} for \lstinline{Type} is used in
the construction of a quantified type scheme to indicate that only
type variables are supposed to be quantified.

\subsection{Unification}
The Hindley-Milner type inference algorithm relies on the unification
subroutine to compute a substitution that equates two types. The
data type for a substitution is defined as a mapping of type variables
to types.
\begin{lstlisting}
    data Substitution = Subs (Map Int Type)
\end{lstlisting}
Here, we represent a type variable simply as an integer. We also define
a typeclass \lstinline{Substitutable} to apply a substitution to types,
type schemes, and type environments.
\begin{lstlisting}
    instance Substitutable Type where
        subs s (TVar x)    = case lookUp s x of
            Just t  -> subs s t
            Nothing -> TVar x
        subs s (Arr t1 t2) = subs s t1 `Arr` subs s t2
        subs s t           = t

    instance Substitutable TypeScheme where
        subs s (Scheme t)    = Scheme $ subs s t
        subs s (ForAll xs c) = ForAll xs c'
          where
            c' = removeBoundVars s xs `subs` c

    instance Substitutable TypeEnv where
        subs s (TypeEnv r) = TypeEnv $ subs s `Map.map` r
\end{lstlisting}
When applying a substitution to a type variable results in another
type variable, we keep repeating the substitution process until the result
is either a precise type or a type variable that is not mapped to anything else.
Also, applying a substitution to a
type scheme, $S\sigma$, only affects free type variables. Therefore,
we need to remove all the quantified type variables in $\sigma$ from $S$
before performing substitution.

Given multiple substitutions, we need to be able to compose them into one.
\begin{lstlisting}
    compose :: Substitution -> Substitution -> Substitution
    compose s1 (Subs s2)
        | Map.null s2 = s1
    compose (Subs s1) s2
        | Map.null s1 = s2
    compose (Subs s1) (Subs s2) =
        Subs $ Map.union s1'' s2
      where
        s1'  = subs (Subs s2) `Map.map` s1
        s1'' = Map.filterWithKey mirror s1'
        mirror k a = case a of
            TVar x
                | k == x -> False
            _             -> True
\end{lstlisting}
The composition of two substitutions $S_1$ and $S_2$ is obtained by
first applying $S_2$ to every type value in $S_1$ and removing any mappings between two
identical type variables. Then we take the left-biased union of the new $S_1$
and $S_2$ to remove duplicate keys in $S_1$ from $S_2$. If either substitution
is empty, then we return the non-empty one as the composition.

Given the definition of a substitution, the unification algorithm is as follows.
\begin{lstlisting}
    unify :: Type -> Type -> GlobalState Substitution
    unify t1 t2
        | t1 == t2                = return Subs.empty
    unify (TVar x) t2
        | occurCheck x t2         = throwError $ Occur x t2
        | otherwise               = return $ Subs.insert Subs.empty x t2
    unify t1 (TVar x)
        | occurCheck x t1         = throwError $ Occur x t1
        | otherwise               = return $ Subs.insert Subs.empty x t1
    unify (Arr s1 t1) (Arr s2 t2) = do s'  <- unify s1 s2
                                       s'' <- unify (subs s' t1) (subs s' t2)
                                       return $ Subs.compose s'' s'
    unify t1 t2                   = throwError $ Mismatch t1 t2
\end{lstlisting}
There are four cases when unifying two types:
\begin{enumerate}
    \item An empty substitution is returned for two equivalent types.
    \item A singleton substitution mapping a type variable $\alpha$
    to another type $T$ is returned only if $\alpha$ does not occur in $T$. For instance,
    substitution $[a/(a \rightarrow \texttt{Nat})]$ applied to $a$ gives
    $a \rightarrow \texttt{Nat}$ but yields $(a \rightarrow \texttt{Nat}) \rightarrow \texttt{Nat}$
    when applied to $a \rightarrow \texttt{Nat}$. Hence, this substitution
    is invalid.
    \item  Unifying two function types involves composing the two substitutions
    resulted from unifying the argument types and the return types.
    \item An error is returned when unifying two inconsistent types.
\end{enumerate}

The unification algorithm plays an important role in type inference for
either finding substitutions used to specify the final type, or reporting a type
error.

\subsection{Algorithm W}
Given a type environment $\Gamma$ and an expression $e$, algorithm W
returns both a substitution $S$ and a type $\tau$ such that
\begin{align*}
    S\Gamma \vdash e : \tau
\end{align*}
The return result $(S, \tau)$ is wrapped inside the \lstinline{GlobalState}
monad, which is defined as
\begin{lstlisting}
    type GlobalState a = ExceptT Error (State Int) a
\end{lstlisting}
The combination of the \lstinline{State} and \lstinline{Except} monads
allows us to maintain a global counter for generating fresh type variable name
as well as to return errors during type inference.

Algorithm W is implemented as follows.
\begin{lstlisting}
    typeInfer' :: TypeEnv -> Expr -> GlobalState (Substitution, Type)
    typeInfer' r e = case e of
        -- | Constants
        Tru         -> return (Subs.empty, Boolean)
        Fls         -> return (Subs.empty, Boolean)
        Zero        -> return (Subs.empty, Nat)
        -- | Arithmetic
        Succ e'     -> typeInferArith r e' Nat
        Pred e'     -> typeInferArith r e' Nat
        IsZero e'   -> typeInferArith r e' Boolean
        -- | Conditional
        If e1 e2 e3 -> do (s1, t1) <- typeInfer' r e1
                          s1' <- unify Boolean t1
                          let s1'' = Subs.compose s1 s1'
                          let r1 = subs s1'' r
                          (s2, t2) <- typeInfer' r1 e2
                          let r2 = subs s2 r1
                          (s3, t3) <- typeInfer' r2 e3
                          s4 <- unify t2 t3
                          let s' = Subs.composeList [s4, s3, s2, s1'']
                          return (s', subs s4 t2)
        -- | Variable
        Var x       -> do c <- TypeEnv.lookUp r x
                          t <- instantiate c
                          return (Subs.empty, t)
        -- | Abstraction
        Lambda x e' -> do t <- GlobalS.newTVar
                          let r' = TypeEnv.insert r x $ Scheme t
                          (s', t') <- typeInfer' r' e'
                          return (s', subs s' t `Arr` t')
        -- | Application
        App e1 e2   -> do (s1, t1) <- typeInfer' r e1
                          let r' = subs s1 r
                          (s2, t2) <- typeInfer' r' e2
                          t <- GlobalS.newTVar
                          s3 <- subs s2 t1 `unify` Arr t2 t
                          let s = Subs.composeList [s3, s2, s1]
                          return (s, subs s3 t)
        -- | Let expressions
        Let x e1 e2 -> do (s1, t1) <- typeInfer' r e1
                          let r1 = subs s1 r
                          let r2 = TypeEnv.insert r x $ generalize r1 t1
                          let r3 = subs s1 r2
                          (s2, t2) <- typeInfer' r3 e2
                          let s = Subs.compose s2 s1
                          return (s, t2)
\end{lstlisting}
In the case of a constant, we simply return one of the base types.
Arithmetic and boolean operators as constant functions only differ in their
output type. We create a subroutine \lstinline{typeInferArith} to handle
different output types.
\begin{lstlisting}
    typeInferArith :: TypeEnv -> Expr -> Type -> GlobalState (Substitution, Type)
    typeInferArith r e retTy = do
        (s1, t1) <- typeInfer' r e
        t <- GlobalS.newTVar
        s2 <- unify (Arr Nat retTy) (Arr t1 t)
        let s = Subs.compose s2 s1
        return (s, subs s2 t)
\end{lstlisting}
The type $t_1$ of the input expression is first inferred. Then we unify
the type of the operator with type $t_1 \rightarrow \beta$, where $\beta$
is a new type variable generated using the subroutine \lstinline{GlobalS.newTVar}.
The resulting substitution is applied to $\beta$ for the final type.

In the case of a conditional expression, we first compute the type for the condition
and check if it is of type \texttt{Bool} through unification. Then we unify
the inferred types for the two branches to ensure their equivalence.
Note that every computed substitution is immediately applied to the type
environment to instantiate all the type schemes containing variables. The final
type of a conditional expression is the result of applying the last substitution
to one of the branch types. The composition of all the substitutions
computed during the process is then returned.

Type inference for a variable $x$ is simply the application of rule {\scriptsize{[TAUT]}}
to find the type scheme $\sigma$ for $x$ in $\Gamma$, and rule {\scriptsize{[INST]}}
to instantiate $\sigma$ with new type variables.

In the case of a $\lambda$-abstraction, we generate a new type variable $\beta$
as the type for the bound variable $x$. The type for the body
expression is inferred under the assumption that $x$ has type $\beta$
to yield the return type for the $\lambda$-abstraction.
Applying the resulting substitution to $\beta$ gives the input type for
the $\lambda$-abstraction.

To infer the type of an application, the algorithm first infers the types for the
operator $e_1$ and the argument $e_2$. A new type variable $\beta$ is used as the return type
for an operator that takes in the computed argument type. Both the original
and new function types are unified to produce a substitution for $\beta$ as
the final type. All the substitutions are composed and returned.

Finally, in the case of a \texttt{let}-expression ($\texttt{let} \: x = e_1 \: \texttt{in} \: e_2$),
the type $t_1$ of $e_1$ along with the substitution $S_1$ used for the inference are computed.
The resulting type is generalized with respect to the type environment $\Gamma$ after
the application of $S_1$. The type of a \texttt{let}-expression is just the type inferred
for $e_2$, where all the $x$ occurrences assume the generalized type scheme.

At the top level, we apply algorithm W to an input expression with an
empty type environment and an initial type variable name of 0. The \lstinline{GlobalState}
result is lifted to expose the inner \lstinline{Either} value that
represents either a type error or the most general type for the expression.
\begin{lstlisting}
    typeInfer :: Expr -> Either Error Type
    typeInfer e = case GlobalS.runTyInfer $ typeInfer' TypeEnv.empty e of
        Right (s, t) -> Right t
        Left err     -> Left err
\end{lstlisting}


\documentclass{article}

\usepackage{fullpage}
\usepackage{amsmath, amsfonts}

\begin{document}
\section{Introduction to Knapsack and Expanding Core}
Consider a set of items $I = \{i_1,...,i_n\}$ where each item is a weight value pair, $i_i = (w_i, v_i)$. Then the knapsack problem is to maximize the value of a subset of these items, which keeping their total weight within some capacity, $c$. In the 0-1 Knapsack problem (KP), we can only have integer solutions, so we describe a solution using $X = \{x_1,\ldots,x_n \ | \ x_i \in \{0,1\}\}$, which is called a {\bf decision vector}.
\begin{equation} \label{knapsackdef}
\begin{aligned}
    \text{maximize }& z = \sum\limits_{j=1}^n v_jx_j \\
    \text{such that }& \sum  w_j x_j \leq c\\
\end{aligned}
\end{equation}

In the linear knapsack problem (LKP), we are allowed to take fractional items. The optimal solution in this case can be found easily by greedily adding the items with the greatest value / weight ratio, $r_i$, until we can no longer add any complete items. This is known as the {\bf break solution}. The left over space is filled with a fraction of the remaining item with the greatest ratio, the {\bf break item}.We define the index $b$ as the index of this break item. Note that we assume $I$ is indexed from highest ratio to lowest.
\begin{equation} \label{breakitemdef}
    b = \min \{j \ | \ \sum\limits_{j=1}^n wj > c
\end{equation}

It has been observed that the optimal solution to an instance of the KP generally shares most of the items with the break solution, save for some changes around the break item. This suggest looking at a small interval of items about $b$, known as the {\bf core}. The core is an interval of indices, $[s,t]$, satisfying the following ordering:
\begin{equation} \label{coreOrdering}
    \begin{aligned}
        r_j &\geq e_{j+1} \ \ j = s, \ldots , t-1\\
        r_j &\geq e_s \ \ j = 1, \ldots ,s-1\\
        r_j &\leq e_t \ \ j = t+1, \ldots , n
    \end{aligned}
\end{equation}

Essentially, we only need a strict ordering of items within $[s,t]$. The interval $[1,s-1]$ has items with a greater ratio that $e_s$ and items in the interval $[t+1, n]$ have a greater ratio than $e_t$. As long as we are only considering items in the core, this ordering on the set of items will be sufficient.

We will be looking at partial decision vectors based on this core problem. The set of all partial decision vector at any step will be given by:
\begin{equation} \label{partialDec}
    \begin{aligned}
        X_{s,t} &= \{(x_s,\ldots,x_t) \ | \ x_i \in \{0,1\}\}
    \end{aligned}
\end{equation}
Note that enumerating all possible partial decision vectors would take $O(2^{t-s+1})$, so much of our effort will be spent on keeping tight bounds on $s$ and $t$. Algorithms that solve the knapsack by expanding this core interval are known as {\bf expanding core} algorithms.

\section{Finding the Break Item}
Finding the break item can be done simply in $O(n \log n)$ time by sorting the list of items and using \ref{knapsackdef}. However, given our weaker ordering requirements as described in \ref{coreOrdering}, sorting the entire list may not be necassary. As such, a variety of algorithms for finding the break item in $O(n)$ can be devised.

At the moment, this topic seems like a distraction, so we will return to it later. Maybe.

\section{Core Recursion}
Using the basic insight behing expanding core algorithms, we can defined a new recusion that solves the core problem first. Assume items adhere to the ordering described in \ref{coreOrdering}. We will be defining this as the function $f_{s,t}(\tilde{c})$. Note that $s,t$ are the bounds of our core interval. $\tilde{c}$ refers to the capacity for the core problem, $0 \leq \tilde{c} \leq 2c$.
$$\tilde{c} = \sum\limits_{j=1}^{s-1} w_j$$
Note, that the optimal solution can be expressed as $f_{1,n}(c)$. Then our recurrence is:
\begin{equation}
    \begin{aligned}
        f_{s,t}(\tilde{c}) = \max \left\{\sum\limits_{j=1}^{s-1}v_j + \sum\limits_{j=s}^t v_j x_j \ \bigg| \  \sum\limits_{j=1}^{s-1}w_j + \sum\limits_{j=s}^t w_j x_j \leq \tilde{c}, \ x_j \in \{0,1\}\right\}
    \end{aligned}
\end{equation}
We can express this in an equivalent way to better enumerate the possible choices.
\begin{equation} \label{reccurence}
    \begin{aligned}
        f_{s,t}(\tilde{c}) = \max \begin{cases} f_{s,t-1}(\tilde{c}) &  t \geq b\\
    f_{s,t-1}(\tilde{c} - w_t) + v_t &  t \geq b, \tilde{c} - w_t \geq 0 \\
    f_{s+1,t}(\tilde{c}) & s < b\\
    f_{s+1,t}(\tilde{c} + w_s) - v_s & s < b, \tilde{c} + w_s \leq 2c \end{cases}
\end{aligned}
\end{equation}
Now, let $f_{b,b-1}(\tilde{c}) = -\infty$ for $0 \leq \tilde{c} \leq \tilde{w} - 1$, and let $f_{b,b-1}(\tilde{c}) = \tilde{p}$ for $\tilde{w} \leq \tilde{c} \leq 2c$, where $\tilde{p} = \sum\limits_{j=1}^{b-1}p_j$, and $\tilde{w} = \sum\limits_{j=1}^{b-1}w_j$.

The idea here is that the enumeration starts with $(s,t) = (b, b-1)$, and we either take items out of the sack (lower $s$), or add items to the sack (raise $t$).

We will represent an undominated state with with the tuple $(\pi_i, \mu_i, \delta_i)$ where $\pi_i = f_{s,t}(\mu_i)$, and the

\end{document}


\subsection{Moving between polar and cartesian coordinates}

All polar numbers can be shown as Cartesian

\(ae^{i\theta }=a(\cos(\theta )+i\sin(\theta ))\)

\(ae^{i\theta }=a\cos(\theta )+ia\sin(\theta )\)

\(z=a+bi\)

\(e^{i\theta }=\)

\(e^x=\sum^{\infty }_{i=0} \dfrac{x^i}{i!}\)