\documentclass[./Thesis.tex]{subfiles}
\begin{document}

\chapter{Termination}
\label{chap:termination}

\epigraph{
  What can be asserted without evidence can also be dismissed without evidence.
}{Christopher Hitchens \cite{hitchens-quote}}

\begin{code}[hide]
  module Termination where
  open import Relation.Nullary using (¬_)
  open import Relation.Nullary.Decidable using (False)
  open import Relation.Nullary.Negation using (contradiction)
  open import Data.Empty using (⊥)
  open import AKS.Nat using (ℕ; zero; suc; _∸_; _*_; _<_; _≤_; lte; _≟_)
  open import AKS.Nat using (+-comm; suc-injective-≡; n≮0; 0≤n; n<1+n; ≤-refl) renaming (n≤m⇒n<m⊎n≡m to n≤m⇒n<m∨n≡m)
  open import Data.Sum using () renaming (inj₁ to or₁; inj₂ to or₂)
  open import AKS.Binary using (𝔹⁺)
  open 𝔹⁺
  open import AKS.Nat.Divisibility using (_div_; Euclidean; Euclidean✓)
  open Euclidean using () renaming (q to quotient)
  open import Relation.Binary.PropositionalEquality
    using (_≡_; _≢_; module ≡-Reasoning)
    renaming (refl to ≡-refl; sym to ≡-sym; cong to ≡-cong; cong₂ to ≡-cong₂)
  open ≡-Reasoning
  open import Data.Unit using (tt)
  open import Polynomial.Simple.AlmostCommutativeRing.Instances using (module Nat)
  open import Polynomial.Simple.Reflection using (solve)
  open Nat.Reflection using (∀⟨_⟩)
  open import Data.List using ([]; _∷_; List)
  open import Function using (_$_)
  open import AKS.Unsafe using (BOTTOM)
\end{code} % $
\section{A Correctness Interlude}
\label{sec:a-correctness-interlude}
The previous chapter omitted a critical flaw in its analysis. The code below is
rejected by the \Agda{} compiler. The compiler's \textit{termination checker} \cite{agda}
fails as \Agda{} can not infer that the result of non-zero integer division by
$2$ always returns an integer strictly smaller than the input. The termination
checker ensures than every function is total. In other words,
the termination checker disallows infinite loops. This termination proof
is obvious but termination proofs can quickly become complex. In general checking
termination, commonly called the halting problem, is undecidable.
\begin{code}[hide]
  module Bad₁ where
    {-# TERMINATING #-}
\end{code}
\begin{code}
    ⟦_⇑⟧⁺ : ∀ (n : ℕ) {≢0 : False (n ≟ 0)} → 𝔹⁺
    ⟦ suc n ⇑⟧⁺ with suc n div 2
    ... | Euclidean✓ (suc q) 0 _ _ = ⟦ suc q ⇑⟧⁺ 0ᵇ
    ... | Euclidean✓ zero    1 _ _ = 𝕓1ᵇ
    ... | Euclidean✓ (suc q) 1 _ _ = ⟦ suc q ⇑⟧⁺ 1ᵇ
\end{code}
This checker is a keystone of the correctness of the logic of \Agda{}. Consider
the following function with a similar call graph. Instead of the input
decreasing to some base case it doubles with every recursive call. This function can
be used to prove falsehood, thus a logic with unconstrained recursion is
inconsistent.
\begin{code}[hide]
  module Bad₂ where
    {-# TERMINATING #-}
\end{code}
\begin{code}
    increasing : ℕ → ⊥
    increasing n with 2 * n
    ... | q = increasing q

    false : ⊥
    false = increasing 0
\end{code}
In fact, the example above can be simplified in the code below. In English
this code expresses the famous fallacy of circular reasoning ``false is true
because false is true''.
\begin{code}[hide]
  module Bad₃ where
    {-# TERMINATING #-}
\end{code}
\begin{code}
    false : ⊥
    false = false
\end{code}
Thankfully none of these false expressions are accepted by the \Agda{} compiler.
This begs the question how does \Agda{} determine which recursive functions to
accept? Unfortunately the \Agda{} compiler can not solve the halting problem so
it must be restrictive. The compiler only accepts recursive
calls that are \textit{structurally decreasing}, a small
subset of the set of recursive functions. A recursive call is structurally
decreasing if the call occurs on a strict sub expression \cite{agda}. The
expression $\AgdaInductiveConstructor{suc} \, n$ is a strict sub-expression of
$\AgdaInductiveConstructor{suc} \,
  (\AgdaInductiveConstructor{suc} \,
    (\AgdaInductiveConstructor{suc} \, n))
$,
but $\AgdaInductiveConstructor{suc} \, n$ is not a strict sub-expression of
$\AgdaInductiveConstructor{suc} \, n$.
Addition, our first example of recursion, is acceptable as
$n <_{sub} \AgdaInductiveConstructor{suc} \, n$.
\begin{code}[hide]
  module Add where
\end{code}
\begin{code}
    _+_ : ℕ → ℕ → ℕ
    zero + m = m
    (suc n) + m = suc (n + m)
\end{code}
\begin{code}[hide]
  open import AKS.Nat using (_+_)
\end{code}
The following inductive definition of the Fibonacci function
has structurally decreasing calls as
$\AgdaInductiveConstructor{suc} \, n <_{sub} \AgdaInductiveConstructor{suc} \, (\AgdaInductiveConstructor{suc} \, n)$
and
$n <_{sub} \AgdaInductiveConstructor{suc} \, (\AgdaInductiveConstructor{suc} \, n)$.
\begin{code}
  fib : ℕ → ℕ
  fib zero = 0
  fib (suc zero) = 1
  fib (suc (suc n)) = fib (suc n) + fib n
\end{code}
So far all the recursive functions described have been
\textit{primitive recursive} \cite{soare}. This is a large class, but the set of
structurally decreasing functions is larger than the set of primitive
recursive functions. The Ackerrmann function is the canonical example of
function which is not primitive recursive.
\begin{code}
  ack : ℕ → ℕ → ℕ
  ack zero m = suc m
  ack (suc n) zero = ack n (suc zero)
  ack (suc n) (suc m) = ack n (ack (suc n) m)
\end{code}
\Agda{} accepts this definition as the recursive
calls are decreasing lexicographically.
The recursive call in the second case decreases in the first argument so
the second argument increasing is acceptable
$
(n, \, \AgdaInductiveConstructor{suc} \, \AgdaInductiveConstructor{zero})
<_{sub}
(\AgdaInductiveConstructor{suc} \, n, \, \AgdaInductiveConstructor{zero})
$.
For a similar reason the outer call in the third case is acceptable
$
(n, \, \AgdaFunction{ack} \, (\AgdaInductiveConstructor{suc} \, n) \, m)
<_{sub}
(\AgdaInductiveConstructor{suc} \, n, \, \AgdaInductiveConstructor{suc} \, m)
$.
The inner call is acceptable as the second argument decreases while the first
stays constant, this is lexicographic order
$
(\AgdaInductiveConstructor{suc} \, n, \, m)
<_{sub}
(\AgdaInductiveConstructor{suc} \, n, \, \AgdaInductiveConstructor{suc} \, m)
$. \\
\section{Well-Founded Relations}
\label{sec:well-founded-relations}
An astute reader may have noticed a pattern. \Agda{} accepts your recursive
definition if it can infer a structural \textit{well-founded relation}
\cite{soare}. A well-founded relation is a binary relation $\prec$ that has no
infinitely descending chains $\dots \prec x_k \prec \dots \prec x_1 \prec x_0$.
For instance the strict ordering over the naturals is well-founded
as every chain will eventually reach $0$.
\begin{align}
  \label{eqn:wellfounded-natural}
  0 < 1 < 2 < 3 < 4 < 5
\end{align}
The non-strict ordering is not well-founded as an infinite chain of the
reflexivity axiom can be constructed.
\begin{align}
  \label{eqn:non-wellfounded-natural}
  \dots \leq 0 \leq \dots \leq 0 \leq 0
\end{align}
Unfortunately, these relation chains do not capture the full structure of well-founded
relations. A well-founded relation often has multiple elements that could be
appended to the chain. This idea is illustrated in the well-founded tree
rooted at 3 found in figure \ref{fig:wellfounded-tree}.
\begin{figure}[h]
  \centering
  \begin{tikzpicture}
    \Tree
    [.3
      {$0 < 3$}
      [.{$1 < 3$}
        {$0 < 1$}
      ]
      [.{$2 < 3$}
        {$0 < 2$}
        [.{$1 < 2$}
          {$0 < 1$}
        ]
      ]
    ]
  \end{tikzpicture}
  \caption{A well-founded tree }
  \label{fig:wellfounded-tree}
\end{figure}
These trees encapsulate the full structure of a well-ordering relation.
Therefore, if we could express this tree as an \Agda{} datatype, we could supply
our own well-ordering relation even when \Agda{} can not infer it. The final
datatype that represents well-founded trees is somewhat puzzling at first
glance. So to introduce it we start with a sensible datatype and make small
changes to the definition until we have reached the correct representation.
These trees are general trees, trees that can have an arbitrary number
of children. They are often called rose trees in functional programming
literature. They make for a good starting datatype.
\begin{code}[hide]
  module Tree₁ where
\end{code}
\begin{code}
    data RoseTree : Set where
      Node : List RoseTree → RoseTree
\end{code}
We then apply a \textit{continuation passing style} \cite{harper} transformation to the
recursive call. Instead of having a list of children we have a continuation that
can be invoked with the index of the requested child.
\begin{code}[hide]
  module Tree₂ where
\end{code}
\begin{code}
    data RoseTree : Set where
      Node : (ℕ → RoseTree) → RoseTree
\end{code}
Unfortunately, this makes our definition unusable as now every rose tree must have
infinite size. From a \textit{game theotertic} perspective, a consumer may request
the first child of every node repetitively.
\begin{code}
    rosetree-uninhabited : RoseTree → ⊥
    rosetree-uninhabited (Node children) = rosetree-uninhabited (children 0)
\end{code}
Any well founded tree is necessarily finite as each node always has a finite
number of children ``less'' than itself. We can solve this by adding an upper
bound and ensuring that any index is less than the bound.
\begin{code}[hide]
  module Tree₃ where
\end{code}
\begin{code}
    data RoseTree (bound : ℕ) : Set where
      Node : (∀ {lower : ℕ} → lower < bound → RoseTree lower)
           → RoseTree bound
\end{code}
Note that the definition above does not make use of any properties specific to
natural numbers. The definition simply requires a binary relation.
By parameterizing the datatype by the relation we
arrive at our finial definition. This is often called the accessibility
predicate so we update the names accordingly.
\begin{code}
  data Acc {A : Set} (_≺_ : A → A → Set) (bound : A) : Set where
    acc : (∀ {lower : A} → lower ≺ bound → Acc _≺_ lower)
        → Acc _≺_ bound
\end{code}
Continuing with the game theoretic analysis proving a relation is well-founded
for a specific bound is a simple game. A game where the prover
continually asks for a lower bound and wins when it is impossible for the
other player to supply a lower bound. This game plays out below for a bound of $3$.
\begin{code}
  3-well-founded : Acc _<_ 3
  3-well-founded = acc λ l₁<3 → acc λ l₂<l₁ → acc λ l₃<l₂ → acc λ l₄<l₃ →
    contradiction l₄<l₃ (end l₁<3 l₂<l₁ l₃<l₂)
\end{code}
\begin{code}[hide]
    where
\end{code}
\begin{code}
    end : ∀ {l₁ l₂ l₃ l₄} → l₁ < 3 → l₂ < l₁ → l₃ < l₂ → ¬ (l₄ < l₃)
    end {2} {1} {0} {l₄} l₁<3 l₂<l₁ l₃<l₂ l₄<l₃ = contradiction l₄<l₃ n≮0
\end{code}
\section{Win Every Game}
\label{sec:win-every-game}
Now we turn to proving that any natural forms a rooted well-founded tree under the
strict ordering relation. Usually proving a property holds for any $n$ is harder
then proving that property holds for specific $n$. This concept applies to
proving that every natural is well-founded. Specifically our choice of
less than relation is poorly suited for this task. We will define an inductive
ordering relation and show that our original definition of ordering is a
subrelation of the inductive-definition. Then if the inductive definition is
well-founded the subrelation will be as well. This last idea is shown below.
\begin{code}[hide]
  module Sub₁ where
\end{code}
\begin{code}
    subrelation
        : ∀ {A : Set} {_≺₁_ _≺₂_ : A → A → Set} {n}
        → (∀ {a b} → a ≺₂ b → a ≺₁ b)
        → Acc _≺₁_ n
        → Acc _≺₂_ n
    subrelation ≺₂⇒≺₁ (acc down) =
      acc λ x≺₂n → subrelation ≺₂⇒≺₁ (down (≺₂⇒≺₁ x≺₂n))
\end{code}
Next we turn to the inductive ordering relation. The key idea behind this
definition is that each $\AgdaInductiveConstructor{≤-step}$ constructor adds one
to the right bound. The base case is the reflexivity axiom so the number of
$\AgdaInductiveConstructor{≤-step}$ constructors is the distance between the
left and right bound. The old definition internalizes this concept into the
definition as the $k$ in
$a \, \AgdaDatatype{≤} \, b = a \, \AgdaFunction{+} \, k \, \AgdaDatatype{≡} \, b$.
\begin{code}
    data _≤ⁱ_ (n : ℕ) (m : ℕ) : Set where
      ≤-same : n ≡ m → n ≤ⁱ m
      ≤-step : ∀ {o} → suc o ≡ m → n ≤ⁱ o → n ≤ⁱ m

    _<ⁱ_ : ℕ → ℕ → Set
    n <ⁱ m = suc n ≤ⁱ m

    2≤ⁱ4 : 2 ≤ⁱ 4
    2≤ⁱ4 = ≤-step {o = 3} ≡-refl (≤-step {o = 2} ≡-refl (≤-same ≡-refl))
\end{code}
This concept also hints at how to show that the old definition is a subrelation
of the inductive definition. Count $k$ down to $0$ adding a
$\AgdaInductiveConstructor{≤-step}$. We first transform
$a \, \AgdaFunction{+} \, k \, \AgdaDatatype{≡} \, b$ into
$k \, \AgdaFunction{+} \, a \, \AgdaDatatype{≡} \, b$ as $\AgdaFunction{\_+\_}$
is defined on the first argument. So it can simplify terms like
$0 \, \AgdaFunction{+} \, a$ into $a$ automatically.
\begin{code}
    ≤⇒≤ⁱ : ∀ {a b} → a ≤ b → a ≤ⁱ b
    ≤⇒≤ⁱ {a} {b} (lte k a+k≡b) = loop a b k $ begin
      k + a ≡⟨ +-comm k a ⟩ a + k ≡⟨ a+k≡b ⟩ b ∎
      where
      loop : ∀ a b k → k + a ≡ b → a ≤ⁱ b
      loop a b zero 0+a≡b = ≤-same $ begin
        a ≡⟨⟩ 0 + a ≡⟨ 0+a≡b ⟩ b ∎
      loop a (suc b) (suc k) 1+k+a≡1+b = ≤-step ≡-refl $ loop a b k $ begin
        k + a ≡⟨ suc-injective-≡ 1+k+a≡1+b ⟩ b ∎
\end{code}
\begin{code}
    <⇒<ⁱ : ∀ {a b} → a < b → a <ⁱ b
    <⇒<ⁱ {a} {b} a<b = ≤⇒≤ⁱ {suc a} {b} a<b
\end{code}
Next we need to prove that any natural forms a rooted well-founded tree under
the inductively defined ordering. This requires a set of mutually recursive
functions.
\begin{code}
    <ⁱ-well-founded : ∀ {n} → Acc _<ⁱ_ n
    <ⁱ-count-down : ∀ {m n} → m <ⁱ n → Acc _<ⁱ_ m
\end{code}
The first accepts the ``player'' supplied proof that some number $m$
is less than the bound. Then the second function counts $n$ down to $m$ until
they are equal. Then it asks the player for a proof that there is some number
smaller than $m$. Note that every case in $\AgdaFunction{<ⁱ-count-down}$ peals
off exactly one $\AgdaFunction{suc}$ so \Agda{} is able to infer that the
functions are structurally decreasing.
\begin{code}
    <ⁱ-well-founded {n} = acc (λ x<ⁱn → <ⁱ-count-down x<ⁱn)
    <ⁱ-count-down {m} {suc .m} (≤-same ≡-refl) = <ⁱ-well-founded {m}
    <ⁱ-count-down {m} {suc n} (≤-step ≡-refl m≤n) = <ⁱ-count-down {m} {n} m≤n
\end{code}
Lastly we bring all the puzzle pieces together and prove that our original
definition of ordering is well founded.
\begin{code}
    <-well-founded : ∀ {n} → Acc _<_ n
    <-well-founded {n} = subrelation <⇒<ⁱ <ⁱ-well-founded
\end{code}
\begin{code}[hide]
  open Sub₁ using (<-well-founded)
\end{code}
\section{Lie No More}
\label{sec:lie-no-more}
Now we can return to our function that upcasts a natural number to a binary
encoded number. In order to use the mechanism developed above we must first
prove a lemma that integer division by $2$ is strictly less than the input.
Thankfully this lemma is simple enough for an automated ring solver to prove.
\begin{code}
  div-< : ∀ n q r {q≢0 : False (q ≟ 0)} → n ≡ r + 2 * q → q < n
\end{code}
\begin{code}[hide]
  div-< n (suc q) r ≡-refl = lte (q + r) (∀⟨ q ∷ r ∷ [] ⟩)
\end{code}
Next we define a helper function that has an accessibility predicate on the
input. Eventually we lose the game as $\Floor{1 / 2} = 0$ and we can not call
the helper function on $0$ by assumption. Thankfully this lines up perfectly
with our desired base case.
\begin{code}
  ⟦_,_⇑⟧ʰ : ∀ (n : ℕ) (acc : Acc _<_ n) {≢0 : False (n ≟ 0)} → 𝔹⁺
  ⟦ suc n , acc down ⇑⟧ʰ with suc n div 2
  ... | Euclidean✓ (suc q) 0 pf _ = ⟦ suc q , down (div-< (suc n) (suc q) 0 pf) ⇑⟧ʰ 0ᵇ
  ... | Euclidean✓ zero    1 _ _ = 𝕓1ᵇ
  ... | Euclidean✓ (suc q) 1 pf _ = ⟦ suc q , down (div-< (suc n) (suc q) 1 pf) ⇑⟧ʰ 1ᵇ

  ⟦_⇑⟧⁺ : ∀ (n : ℕ) {≢0 : False (n ≟ 0)} → 𝔹⁺
  ⟦ suc n ⇑⟧⁺ = ⟦ suc n , <-well-founded ⇑⟧ʰ
\end{code}
\section{Binary Search}
\label{sec:binary-search}
Consider the following binary search for the value $10$ in the array
$
\rowarrowsep=-2pt
\begin{gmatrix}[b]
  1 & 5 & 8 & 10 & 11 & 20
\end{gmatrix}
$ depicted in equation \ref{eqn:binary-search}. The search starts with the bounds of the entire array
$\textcolor{blue}{[} 0, 5 \textcolor{blue}{]}$.
Then it updates the interval to the left half of the array
$\textcolor{green}{[} 3, 5 \textcolor{green}{]}$.
It finally narrows in on the correct answer the interval
$\textcolor{red}{[} 3, 3 \textcolor{red}{]}$.
As with all the examples described in this chapter this
algorithm terminates because the intervals are decreasing under a well-founded
relation, strict interval inclusion.
\begin{align}
  \label{eqn:binary-search}
  \begin{gmatrix}[b]
    \hspace{0.4em} \Line{blue} &
    1 &
    5 &
    8 &
    \Line{green} \hspace{0.4em} \Line{red} &
    10 &
    \Line{red} &
    11 &
    20 &
    \Line{green} \hspace{0.4em} \Line{blue} \hspace{0.4em}
  \end{gmatrix}
\end{align}
An interval $i_2$ strictly includes
an interval $i_1$ if $i_1$ is a proper subset of $i_2$. If the set is finite
then this relation is clearly well founded. Unfortunately working with sets is
tricky in a type theory. So we limit our definition of an
interval to sets of naturals. Then our intervals are uniquely represented by
their \textit{infimum} (lower bound) and \textit{supremum} (upper bound).
\begin{code}
  record Interval : Set where
    constructor [_,_∣_]
    field
      inf : ℕ
      sup : ℕ
      inf≤sup : inf ≤ sup
  open Interval
\end{code}
Now we have two bounds to manipulate so there are two possible ways to create an
interval smaller than another. Firstly to lower the supremum and secondly to
raise the infimum.
\begin{code}
  data _⊂_ (i₁ : Interval) (i₂ : Interval) : Set where
    downward : inf i₂ ≤ inf i₁ → sup i₁ < sup i₂ → i₁ ⊂ i₂
    upward : inf i₂ < inf i₁ → sup i₁ ≤ sup i₂ → i₁ ⊂ i₂
\end{code}
Often authors prove termination for their binary search algorithm by instead
thinking about how the distance between the left and right bound decreases. We
adopt this technique to show that interval inclusion is a subrelation of
$\AgdaFunction{\_<\_}$. Although it is not technically a subrelation. It is a
subrelation generated by the function $\AgdaFunction{width}$.
\begin{code}
  width : Interval → ℕ
  width i = sup i ∸ inf i

  ⊂⇒< : ∀ {i₁ i₂} → i₁ ⊂ i₂ → width i₁ < width i₂
\end{code}
\begin{code}[hide]
  open import AKS.Unsafe using (trustMe)

  ∸-monoˡ-< : ∀ {l₁ h₁ l₂ h₂} → l₁ ≤ h₁ → l₂ ≤ h₂ → l₂ ≤ l₁ → h₁ < h₂ → h₁ ∸ l₁ < h₂ ∸ l₂
  ∸-monoˡ-< {l₁} {h₁} {l₂} {h₂} l₁≤h₁ l₂≤h₂ l₂≤l₁ h₁<h₂ = lte ((h₂ ∸ l₂) ∸ suc (h₁ ∸ l₁)) trustMe

  ∸-monoʳ-< : ∀ {l₁ h₁ l₂ h₂} → l₁ ≤ h₁ → l₂ ≤ h₂ → l₂ < l₁ → h₁ ≤ h₂ → h₁ ∸ l₁ < h₂ ∸ l₂
  ∸-monoʳ-< {l₁} {h₁} {l₂} {h₂} l₁≤h₁ l₂≤h₂ l₂<l₁ h₁≤h₂ = lte ((h₂ ∸ l₂) ∸ suc (h₁ ∸ l₁)) trustMe

  ⊂⇒< {[ inf-i₁ , sup-i₁ ∣ inf-i₁≤sup-i₁ ]} {[ inf-i₂ , sup-i₂ ∣ inf-i₂≤sup-i₂ ]} (downward inf-i₂≤inf-i₁ sup-i₁<sup-i₂)
    = ∸-monoˡ-< inf-i₁≤sup-i₁ inf-i₂≤sup-i₂ inf-i₂≤inf-i₁ sup-i₁<sup-i₂
  ⊂⇒< {[ inf-i₁ , sup-i₁ ∣ inf-i₁≤sup-i₁ ]} {[ inf-i₂ , sup-i₂ ∣ inf-i₂≤sup-i₂ ]} (upward inf-i₂<inf-i₁ sup-i₁≤sup-i₂)
    = ∸-monoʳ-< inf-i₁≤sup-i₁ inf-i₂≤sup-i₂ inf-i₂<inf-i₁ sup-i₁≤sup-i₂
  -- ⊂⇒< = BOTTOM
\end{code}
As the types of our elements are different we need to generalize
$\AgdaFunction{subrelation}$. We add a function to covert between the types.
Technically the function is a \textit{functor} \cite{awodey}
from the \textit{category} with $\AgdaFunction{\_≺₂\_}$ as morphisms to the
category with $\AgdaFunction{\_≺₁\_}$ as morphisms.
\begin{code}
  subrelation
      : ∀ {A : Set} {B : Set}
          {_≺₁_ : A → A → Set}
          {_≺₂_ : B → B → Set}
          {f : B → A}
          {n : B}
      → (∀ {x y} → x ≺₂ y → f x ≺₁ f y)
      → Acc _≺₁_ (f n)
      → Acc _≺₂_ n
\end{code}
\begin{code}[hide]
  subrelation ≺₂⇒≺₁ (acc down) =
    acc λ x≺₂n → subrelation ≺₂⇒≺₁ (down (≺₂⇒≺₁ x≺₂n))
\end{code}
Although we will not be implementing binary search in this thesis, this concept
will prove useful as it allows us to write terminating code that counts up to
some fixed value.
\begin{code}
  ⊂-well-founded : ∀ {i} → Acc _⊂_ i
  ⊂-well-founded = subrelation ⊂⇒< <-well-founded

  count-up-to : ℕ → List ℕ
  count-up-to n = loop 0 0≤n ⊂-well-founded
\end{code}
\begin{code}[hide]
    where
\end{code}
Counting up is simply always choosing to tighten the left bound of the interval.
Eventually the user reaches the upper bound and interval becomes $[ n, n ]$.
This interval can not be shortened and the recursion terminates as shown below.
\begin{code}
    loop : ∀ (x : ℕ) (x≤n : x ≤ n) (acc : Acc _⊂_ [ x , n ∣ x≤n ]) → List ℕ
    loop x x≤n (acc next) with n≤m⇒n<m∨n≡m x≤n
    ... | or₂ x≡n = x ∷ []
    ... | or₁ x<n = x ∷ loop (1 + x) x<n (next [1+x,n]⊂[x,n])
\end{code}
\begin{code}[hide]
      where
\end{code}
\begin{code}
      [1+x,n]⊂[x,n] : [ 1 + x , n ∣ x<n ] ⊂ [ x , n ∣ x≤n ]
      [1+x,n]⊂[x,n] = upward n<1+n ≤-refl
\end{code}
\begin{code}
  zero-to-three : count-up-to 3 ≡ 0 ∷ 1 ∷ 2 ∷ 3 ∷ []
  zero-to-three = ≡-refl
\end{code}

\end{document}


\section{Fermi break-up simulation for light nuclei.}

\hspace{1.0em}For light nuclei ($A \leq 16$) the values of excitation
energy per nucleon are often comparable with nucleon binding
energy. Thus a light excited nucleus breaks into two or more fragments
with branching given by available phase space.  To describe a process of
nuclear disassembling the so-called Fermi break-up model is used
\cite{Fermi50}, \cite{Kretz61}, \cite{EG67}.  This statistical approach
was first used by Fermi \cite{Fermi50} to describe the multiple
production in high energy nucleon collision.

The initial information for calculation of break-up stage consists from
the atomic mass number $A$, charge $Z$ and number of neutrons $N$ of
residual (e. g. after cascade or fission) nucleus and its excitation
energy $U$. The total energy of nucleus in the rest system will be
$E=U+M(A,Z)$.

\subsection{Masses of nuclei.}

\hspace{1.0em}The tabulated values (calculated according to the liquid drop
model) \cite{CAM57} of mass defects  $\Delta M(A,Z)$
are used to calculate the masses of nuclei $M(A,Z)$ in ground states.

\subsection{ Allowed channel.}

\hspace{1.0em}The channel will be allowed for decay, if the total
kinetic energy $E_{kin}$ of all fragments of the given channel at the
moment of break-up is positive. This energy can be calculated according
to equation:
\begin{equation}
\label{FBS1}E_{kin} = U+M(A,Z)-E_{Coulomb} - \sum_{b=1}^{n}(m_b+\epsilon_{b}),
\end{equation}
$m_{b}$ and $\epsilon_{b}$ are masses and excitation energies of fragments,
respectively, $E_{Coulomb}$ is the Coulomb barrier for the given channel. It
is approximated by
\begin{equation}
\label{FBS2}E_{Coulomb} = \frac{3}{5} \frac{e^2}{r_{0}}(1 +
\frac{V}{V_{0}})^{-1/3}
(\frac{Z^2}{A^{1/3}}-\sum_{b=1}^{n}\frac{Z^2}{A_b^{1/3}}),
\end{equation}
where $V_0$ is the volume of the system corresponding to the normal
nuclear matter density and $\kappa = \frac{V}{V_0}$ is a parameter (
$\kappa = 1$ is used).

\subsection{Break-up probability.}

\hspace{1.0em}The total  probability per unit time for nucleus to
break-up into $n$ componets in the final state (i.e. residual nucleus,
if it will be, nucleons, deutrons, tritons, alphas etc) is given by
\begin{equation}
\label{FBS3}W(E,n) = (V/\Omega)^{n-1}\rho_{n}(E),
\end{equation}
where $\rho_{n}(E)$ is the density of a number of final states, $V$ is
the volume of decaying system and $\Omega = (2\pi h)^{3}$ is the
normalization volume.  The density $\rho_{n}(E)$ can be defined a
product of three factors:
\begin{equation}
\label{FBS4}\rho_{n}(E)=M_{n}(E)S_nG_n.
\end{equation}
The first one is the phase space factor defined as
\begin{equation}
\label{FBS5}M_{n} = \int_{-\infty}^{+\infty}...\int_{-\infty}^{+\infty}
\delta(\sum_{b=1}^{n} {\bf p_{b}}) \delta(E-\sum_{b=1}^{n}\sqrt{p^2+m^2_b})
\prod_{b=1}^{n} d^3p_b,
\end{equation}
where ${\bf p_b}$ are fragments momenta. The second one is the spin
factor
\begin{equation}
\label{FBS6} S_n = \prod_{b=1}^{n}(2s_b+1),
\end{equation}
which gives the number of states with different spin orientations.  The
last one is the permutation factor
\begin{equation}
\label{FBS7}G_n = \prod_{j=1}^{k}\frac{1}{n_j !},
\end{equation}
which takes into account identity of components in final state ($n_j$ is
a number of components of $j$- type particles and $k$ is defined by $n =
\sum_{j=1}^{k}n_{j}$). E.g. if in final state we have $n = 6$ particles
and from them there are $2$-alphas, $3$-nucleons and $1$-deutrons, then
$G_{6} = 1/(2! 3! 1!) = 1/12$.

In non-relativistic case (Eq. ($\ref{FBS10}$) the integration in
Eq. ($\ref{FBS5}$) can be evaluated analiticaly (see e. g. \cite{BBB58})
and the probability for a nucleus with energy $E$ disassembling into $n$
fragments with masses $m_b$, where $b = 1,2,3,...,n$ equals
\begin{equation}
\label{FBS8} W(E_{kin},n) =
S_nG_n (\frac{V}{\Omega})^{n-1}(\frac{1}{\sum_{b=1}^{n}m_b}
\prod_{b=1}^{n}
m_{b})^{3/2}
 \frac{2\pi^{3(n-1)/2}}{\Gamma(3(n-1)/2)}E_{kin}^{3n/2-5/2},
\end{equation}
where $\Gamma(x)$ is the gamma function ($\Gamma(3(n-1)/2 =  (3(n-1)/2
- 1)!$).

\subsection{Fermi break-up model parameter.}

\hspace{1.0em}Thus the Fermi break-up model has only one free parameter
$V$ is the volume of decaying system, which can be calculated as
following:
\begin{equation}
\label{FBS9} V = 4\pi R^3/3 = 4\pi r_{0}^3 A/3,
\end{equation}
where $r_{0} = 1.4 $ fm is used.

\subsection{ Fragment characteristics.}

We take into account the formation of fragments in their ground and
low-lying excited states, which are stable for nucleon
emission. However, several unstable fragments with large lifetimes:
$^{5}He$, $^{5}Li$, $^{8}Be$, $^{9}B$ etc are also considered.  Fragment
characteristics $A_b$, $Z_b$, $s_b$ and $\epsilon_b$ are taken from
\cite{AS81}.

\subsection{ MC procedure.}

\hspace{1.0em}The nucleus break-up is described by the Monte Carlo (MC)
procedure. We randomly (according to probability Eq. ($\ref{FBS8}$) and
condition Eq. ($\ref{FBS1}$)) select decay channel. Then for given
channel we calculate kinematical quantities of each fragment according
to $n$-body phase space distribution:
\begin{equation}
\label{FBS10}M_{n} = \int_{-\infty}^{+\infty}...\int_{-\infty}^{+\infty}
\delta(\sum_{b=1}^{n} {\bf p_{b}}) \delta(\sum_{b=1}^{n}
\frac{p^2_b}{2m_b}-E_{kin})
\prod_{b=1}^{n} d^3p_b.
\end{equation}
The Kopylov's sampling procedure \cite{Kopylov70} is applied.  The angular
distributions for emitted fragments are considered as isotropical.

We take into account that the chargeless fragments are not affected by
Coulomb field. When fragment fly away to infinity its total kinetic
energy can be approximated by the sum of its translational motion and
the contribution to the energy erasing from its Coulomb repulsion.


\documentclass[10pt]{beamer}
\usetheme{metropolis}
% all imports
\input{all_imports}

\AtBeginEnvironment{quote}{\singlespacing}

% new commands
\input{all_new_commands}

% definitions
\input{definitions/colors}
\input{definitions/styles}

\input{header}

\begin{document}
\nocite{DeepLearningbook}

\maketitle

\section{RNN}

\begin{frame}{RNN as a graph}
\input{TikzFiles/RNNGraphExpanded}
\end{frame}

\begin{frame}{RNN as a graph}
\input{TikzFiles/RNNSimplified}
\end{frame}

\begin{frame}{Unfolding the graph}
\input{TikzFiles/RNNSimplifiedUnfolded}
\end{frame}

\begin{frame}{RNN time unfolding}
\input{TikzFiles/rnn-time-unfolding}
\end{frame}

\section{BackPropagation}

\begin{frame}{Chain rule: RNN graph}
\input{TikzFiles/rnn-backprop}
\end{frame}

\begin{frame}{Chain rule: RNN graph}
\input{TikzFiles/rnn-backprop-through-time}
\end{frame}

\section{Language model}

\begin{frame}{The language model: graph}
\input{TikzFiles/LanguageModelExpanded}
\end{frame}

\begin{frame}{The language model: graph}
\input{TikzFiles/LanguageModelSimplified}
\end{frame}

\begin{frame}{The Language model: unfolding example}
\input{TikzFiles/LanguageModelUnfolded}
\end{frame}

\section{LSTM}

\begin{frame}{LSTM}
\input{TikzFiles/LSTM_simplified}
\end{frame}

\begin{frame}{LSTM: unfolded model}
\input{TikzFiles/LSTM_unfolded}
\end{frame}

\begin{frame}{Simplification}
\input{TikzFiles/Add_op_simplified}
\end{frame}

\begin{frame}{LSTM: recurrence}
\input{TikzFiles/LSTM_cell}
\end{frame}

\begin{frame}[allowframebreaks]{References}

  \bibliography{my_references}
  \bibliographystyle{abbrv}

\end{frame}

\end{document}


\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage[osf]{libertine}
\usepackage[scaled=0.8]{beramono}
\usepackage[margin=1.5in]{geometry}
\usepackage{url}
\usepackage{booktabs}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{nicefrac}
\usepackage{microtype}
\usepackage{subcaption}
\usepackage{bm}

\usepackage{sectsty}
\sectionfont{\large}
\subsectionfont{\normalsize}

\usepackage{titlesec}
\titlespacing{\section}{0pt}{10pt plus 2pt minus 2pt}{0pt plus 2pt minus 0pt}
\titlespacing{\subsection}{0pt}{5pt plus 2pt minus 2pt}{0pt plus 2pt minus 0pt}

\usepackage{pgfplots}
\pgfplotsset{
  compat=newest,
  plot coordinates/math parser=false,
  tick label style={font=\footnotesize, /pgf/number format/fixed},
  label style={font=\small},
  legend style={font=\small},
  every axis/.append style={
    tick align=outside,
    clip mode=individual,
    scaled ticks=false,
    thick,
    tick style={semithick, black}
  }
}

\pgfkeys{/pgf/number format/.cd, set thousands separator={\,}}

\usepgfplotslibrary{external}
\tikzexternalize[prefix=tikz/]

\newlength\figurewidth
\newlength\figureheight

\setlength{\figurewidth}{8cm}
\setlength{\figureheight}{6cm}

\newlength\squarefigurewidth
\newlength\squarefigureheight

\setlength{\squarefigurewidth}{4cm}
\setlength{\squarefigureheight}{4cm}

\newlength\smallsquarefigurewidth
\newlength\smallsquarefigureheight

\setlength{\smallsquarefigurewidth}{3.25cm}
\setlength{\smallsquarefigureheight}{3.25cm}

\newlength\smallfigurewidth
\newlength\smallfigureheight

\setlength{\smallfigurewidth}{6.25cm}
\setlength{\smallfigureheight}{4cm}

\setlength{\parindent}{0pt}
\setlength{\parskip}{1ex}

\newcommand{\acro}[1]{\textsc{\MakeLowercase{#1}}}
\newcommand{\given}{\mid}
\newcommand{\mc}[1]{\mathcal{#1}}
\newcommand{\data}{\mc{D}}
\newcommand{\model}{\mc{M}}
\newcommand{\intd}[1]{\,\mathrm{d}{#1}}
\newcommand{\inv}{^{-1}}
\newcommand{\trans}{^\top}
\newcommand{\mat}[1]{\bm{\mathrm{#1}}}
\renewcommand{\vec}[1]{\bm{\mathrm{#1}}}
\newcommand{\R}{\mathbb{R}}
\renewcommand{\epsilon}{\varepsilon}

\DeclareMathOperator{\var}{var}
\DeclareMathOperator{\cov}{cov}
\DeclareMathOperator{\diag}{diag}
\DeclareMathOperator*{\argmin}{arg\,min}
\DeclareMathOperator*{\argmax}{arg\,max}

\begin{document}

\section*{Bayesian model selection}

Consider the regression problem, where we want to predict the values
of an unknown function $y\colon \R^d \to \R$ given examples $\data =
\bigl\{ (\vec{x}_i, y_i) \bigr\}_{i = 1}^N$ to serve as training data.
In Bayesian linear regression, we made the following assumption about
$y(\vec{x})$:
\begin{equation}
  y(\vec{x}) = \phi(\vec{x})\trans \vec{w} + \epsilon(\vec{x}),
\end{equation}
where $\phi(\vec{x})$ is a now explicitly-written feature expansion of
$\vec{x}$.  We proceed in the normal Bayesian way: we place Gaussian
priors on our unknowns, the parameters $\vec{w}$ and the residuals
$\vec{\epsilon}$, then derive the posterior distribution over
$\vec{w}$ given $\data$, which we use to make predictions.

One question left unanswered is how to choose a good feature expansion
function $\phi(\vec{x})$.  For example, a purely linear model could
use $\phi(\vec{x}) = [1, \vec{x}]\trans$, whereas a quadratic model
could use $\phi(\vec{x}) = [1, \vec{x}, \vec{x}^2]\trans$, etc.  In
general, arbitrary feature expansions $\phi$ are allowed.  How can I
select between them?  Even more generally, how do I select whether I
should use linear regression or a completely different probabilistic
model to explain my data?  These are questions of \emph{model
  selection,} and naturally there is a Bayesian approach to it.

Before we continue our discussion of model selection, we will first
define the word \emph{model,} which is often used loosely without
explicit definition.  A model is a parametric family of probability
distributions, each of which can explain the observed data.  Another
way to explain the concept of a model is that if we have chosen a
likelihood $p(\data \given \theta)$ for our data, which depends on a
parameter $\theta$, then the model is the set of all likelihoods (each
one of which is a distribution over $\data$) for every possible value
of the parameter $\theta$.

In the case of linear regression, the weight vector $\vec{w}$ defines
the parametric family, and the model is the set of distributions
\begin{equation*}
  \bigl\{ p(\vec{y} \given \mat{X}, \vec{w}, \sigma^2) \bigr\}
  =
  \bigl\{ \mc{N}(\vec{y}; \mat{X}\vec{w}, \sigma^2 \mat{I}) \bigr\},
\end{equation*}
indexed by all possible $\vec{w}$.  Each one of these is a potential
explanation of the observed values $\vec{y}$ given $\vec{X}$.  In the
case of flipping a coin $n$ times with an unknown bias $\theta$ and
observing the number of heads $x$, the model is
\begin{equation*}
  \bigl\{ p(x \given n, \theta) \bigr\}
  =
  \bigl\{ \mathrm{Binomial}(x, n, \theta) \bigr\},
\end{equation*}
where there is one binomial distribution for every possible $\theta
\in (0, 1)$.  In the Bayesian method, we maintain a belief over which
elements in the model we consider plausible by reasoning about
$p(\theta \given \data)$ via Bayes' theorem.

Suppose now that I have at my disposal a finite set of models
$\{\model_i\}_i$ that I may use to explain my observed data $\data$,
and let us write $\theta_i$ for the parameters of model $\model_i$.
How do we know which model to prefer?  We work out the posterior
probability over the models via Bayes' theorem!  We have:
\begin{equation*}
  \Pr(\model_i \given \data)
  =
  \frac{p(\data \given \model_i)\Pr(\model_i)}
       {\sum_j p(\data \given \model_j)\Pr(\model_j)}.
\end{equation*}
Here $\Pr(\model_i)$ is a prior distribution over models that we have
selected; a common practice is to set this to a uniform distribution
over the models.  The value $p(\data \given \model_i)$ may also be
written in a more-familiar familiar form:
\begin{equation*}
  p(\data \given \model_i)
  =
  \int
  p(\data \given \theta_i, \model_i)
  p(\theta_i \given \model_i)
  \intd{\theta_i}.
\end{equation*}
This is exactly the denominator when applying Bayes' theorem to find
the posterior $p(\theta_i \given \data, \model_i)$!
\begin{equation*}
  p(\theta_i \given \data, \model_i)
  =
  \frac{p(\data \given \theta_i, \model_i) p(\theta_i \given \model_i)}
       {\int
         p(\data \given \theta_i, \model_i)
         p(\theta_i \given \model_i)
         \intd{\theta_i}.
       }
  =
  \frac{p(\data \given \theta_i, \model_i) p(\theta_i \given \model_i)}
       {p(\data \given \model_i)},
\end{equation*}
where we have simply conditioned on $\model_i$ to be explicit.  In the
context of model selection, the term $p(\data \given \model_i)$ is
known as the \emph{model evidence} or simply \emph{evidence.}  One
interpretation of the model evidence is the probability that your
model could have generated the observed data, under the chosen prior
belief over its parameters $\theta_i$.

Suppose now that we have exactly two models for the observed data that
we wish to compare: $\model_1$ and $\model_2$, with corresponding
parameter vectors $\theta_1$ and $\theta_2$ and prior probabilities
$\Pr(\model_1)$ and $\Pr(\model_2)$. In this case it is easiest to
compute the \emph{posterior odds}, the ratio of the models'
probabilities given the data:
\begin{equation*}
  \frac{\Pr(\model_1 \given \data)}
       {\Pr(\model_2 \given \data)}
  = \frac{\Pr(\model_1) p(\data \given \model_1)}
         {\Pr(\model_2) p(\data \given \model_2)}
  = \frac{\Pr(\model_1) \int p(\data \given \theta_1, \model_1)
          p(\theta_1 \given \model_1) \intd{\theta_1}}
         {\Pr(\model_2) \int p(\data \given \theta_2, \model_2)
          p(\theta_2 \given \model_2) \intd{\theta_2}},
\end{equation*}
which is simply the prior odds multiplied by the ratio of the evidence
for each model.  The latter quantity is also called the \emph{Bayes
  factor} in favor of $\model_1$.  Publishing Bayes factors allows
another practitioner to easily substitute their own model priors and
derive their own conclusions about the models being considered.

\subsection*{Example}

Wikipedia gives a truly excellent example of Bayesian model selection
in
practice.\footnote{\url{http://en.wikipedia.org/wiki/Bayes_factor#Example}}
Suppose I am presented with a coin and want to compare two models for
explaining its behavior.  The first model, $\model_1$, assumes that
the heads probability is fixed to $\nicefrac{1}{2}$.  Notice that this
model does not have any parameters.  The second model, $\model_2$,
assumes that the heads probability is fixed to an unknown value
$\theta \in (0, 1)$, with a uniform prior on $\theta$: $p(\theta
\given \model_2) = 1$ (this is equivalent to a beta prior on $\theta$
with $\alpha = \beta = 1$).  For simplicity, we choose a uniform model
prior: $\Pr(\model_1) = \Pr(\model_2) = \nicefrac{1}{2}$.

Suppose we flip the coin $n = 200$ times and observe $x = 115$ heads.
Which model should we prefer in light of this data?  We compute the
model evidence for each model.  The model evidence for $\model_1$ is
quite straightforward, as it has no parameters:
\begin{equation*}
  \Pr(x \given n, \model_1)
  =
  \mathrm{Binomial}(n, x, \nicefrac{1}{2})
  =
  \binom{200}{115}
  \frac{1}{2^{200}}
  \approx
  0.005956.
\end{equation*}
The model evidence for $\model_2$ requires integrating over the
parameter $\theta$:
\begin{align*}
  \Pr(x \given n, \model_2)
  &=
  \int
  \Pr(x \given n, \theta, \model_2)
  p(\theta \given \model2)
  \intd{\theta}
  \\
  &=
  \int_{0}^{1}
  \binom{200}{115}
  \theta^{115}
  (1 - \theta)^{200 - 115}
  \intd{\theta}
  \\
  &=
  \frac{1}{201}
  \approx
  0.004975.
\end{align*}
The Bayes factor in favor of $\model_1$ is approximately $1.2$, so the
data give very weak evidence in favor of the simpler model $\model_1$.

An interesting aside here is that a frequentist hypothesis test would
reject the null hypothesis $\theta = \frac{1}{2}$ at the $\alpha =
0.05$ level. The probability of generating at least 115 heads under
model $\model_1$ is approximately $0.02$ (similarly, the probability
of generating at least 115 tails is also $0.02$), so a two-sided test
would give a $p$-value of approximately $4\%$.

\subsection*{Occam's razor}

One spin on Bayesian decision theory is that it automatically gives a
preference towards simpler models, in line with Occam's razor.  One
way to see this is to consider the model evidence $p(\data \given
\model)$ as a probability distribution over datasets $\data$.  More
complex models can explain more datasets, so the support of this
distribution is wider in the sample space.  But note that the
distribution must normalize over the sample space as well, so we pay a
price for generality.  When moving from a simpler model to a more
complex model, the probability of some datasets that are well
explained by the simpler model must inevitably decrease to ``give up''
probability mass for the newly explained datasets in the widened
support of the more-complex model.  The model selection process then
drives us to select the model that is ``just complex enough'' to
explain the data at hand, an in-build Occam's razor.

In the coin flipping example above, model $\model_1$ can only explain
datasets with empirical heads probability reasonably near
$\frac{1}{2}$.  An observation of 200 heads, for example, would have
astronomically small probability under this model.  The second model
$\model_2$ can explain \emph{any} set of observations by selecting an
appropriate $\theta$.  The price for this generality, though, is that
datasets with a roughly equal number of heads and tails have a smaller
prior probability under the model than before.

\subsection*{Model selection for Bayesian linear regression}

A common application for model selection is for selecting between
feature expansion functions $\phi(\vec{x})$ in Bayesian linear
regression.  Here the model $\model_i$ could for example correspond
to order-$i$ polynomial regression with
\begin{equation*}
  \phi_i(\vec{x})
  =
  [1, \vec{x}, \vec{x}^2, \dotsc \vec{x}^i]\trans.
\end{equation*}
After selecting a set of these models to compare, as well as a prior
probability for each, the only remaining task is to compute the
evidence for each model in observed data $(\mat{X}, \vec{y})$.  In our
discussion of Bayesian linear regression, we have actually already
computed the desired quantity:
\begin{equation*}
  p(\vec{y} \given \mat{X}, \sigma^2, \model_i)
  =
  \mc{N}\bigl(\vec{y};
  \phi_i(\mat{X})\vec{\mu},
  \phi_i(\mat{X})\mat{\Sigma}\phi_i(\mat{X})\trans + \sigma^2\mat{I}\bigr),
\end{equation*}
where I have explicitly written the basis expansion in $\phi_i$.

Note that the model $\phi_i$ can also easily explain all datasets
well-explained by the models $\phi_j$ for $j < i$, by simply setting
the weights on higher-order terms to zero.  Again, however, the
simpler model will be preferred due the Occam's razor effect described
above.

\section*{Bayesian Model Averaging}

Note that a ``full Bayesian'' treatment of a problem would eschew
model selection entirely.  Instead, when making predictions, we should
theoretically use the sum rule to marginalize the unknown model, e.g.:
\begin{equation*}
  p(y_\ast \given \vec{x}_\ast, \data)
  =
  \sum_i
  p(y_\ast \given \vec{x}_\ast, \data, \model_i)
  \Pr(\model_i \given \data).
\end{equation*}
Such an approach is called \emph{Bayesian model averaging.}  Although
this is sometimes seen, model selection is still used widely in
practice.  The reason is that the computational overhead of using a
single model is much lower than having to continually retrain multiple
models, and that Bayesian model averaging uses a mixture distribution
for predictions, which can have annoying analytic properties (for
example, the predictive distribution could be multimodal).

\end{document}


\documentclass[11pt]{article}

\usepackage{texyousei}
\usepackage{tabularx}

\lhead{}
\chead{The Schur Complement for Fractional Sobolev Preconditioning}
\rhead{}

\usepackage{comment}
\excludecomment{oops}

\setlength{\leftmargini}{0.3in}

\DeclarePairedDelimiter{\inner}{\langle}{\rangle}
\newcommand{\ddx}{\frac{d}{dx}}
\newcommand{\ddy}{\frac{d}{dy}}
\newcommand{\ddn}{\frac{d}{dn}}
\newcommand{\ddm}{\frac{d}{dm}}
\newcommand{\sgn}[1]{\ \textrm{sgn}\left(#1\right)}
\newcommand{\calDf}{\mathcal{D}_f}

\begin{document}

\maketitle{The Schur Complement for Fractional Laplacians}{}

\thispagestyle{empty}

\section{Fractional Laplacian inverse approximation}
\label{sec:FractionalLaplacianInverseApproximation}

Recall that we now have a relatively efficient way to invert the fractional Laplacian $\Delta^{s}$ by factoring the inverse as $(\Delta^{-1}) (\Delta^{2 - s}) (\Delta^{-1})$; the two occurrences of $\Delta^{-1}$ are then be assembled as sparse cotan Laplacians, while the middle term has a positive power $2-s$ and can therefore be multiplied using hierarchical matrices. From here on, let $A = \Delta^{s}$, let $A^{-1} = (\Delta^{-1}) (\Delta^{2 - s}) (\Delta^{-1})$, and assume that we can multiply with $A^{-1}$ as a black box.

\section{The Schur complement}

For a general block matrix
$$M =
\left[
\begin{array}{cc}
A & B \\
C & D
\end{array}
\right]
$$
the Schur complement of the block $A$ is defined by $$M / A = D - C A^{-1} B.$$ Note that if $C$ has dimensions $k \times n$, then $M / A$ has dimensions $k \times k$. Then, if $A$ is invertible, then we have the following block expression for the inverse of $M$:
$$
M^{-1} = \left[
\begin{array}{cc}
A^{-1} + A^{-1} B (M / A)^{-1} C A^{-1} & -A^{-1} B (M / A)^{-1} \\
-(M / A)^{-1} C A^{-1} & (M / A)^{-1}
\end{array}
\right]
$$
Thus, in theory, we can invert the whole matrix $M$ by only inverting $A$ and $(M/A)$. (Analogous expressions exist for the complement $(M/D)$, but these expressions are not useful to us.)

\subsection{Application to the fractional Laplacian}

We would like to invert the saddle matrix
$$G =
\left[
\begin{array}{cc}
A & C^T \\
C & 0
\end{array}
\right]
$$
where $C$ is a $k \times 3|V|$ matrix whose rows contain the differentials of $k$ real-valued constraint functions, or alternatively, $C$ is the Jacobian of a constraint function $\Phi : \R^{3|V|} \to \R^k$.

Then, the expression for the complement becomes $$G / A = -C A^{-1} C^{\top}.$$ Note that we only have the ability to multiply $A^{-1}$ with column vectors, so we will have to apply the approximation from Section \ref{sec:FractionalLaplacianInverseApproximation} once per column of $C^{\top}$, or in other words, once per constraint.

As for the inverse, the only block that we need to apply is the top-left block, as this is the only block that contributes to the projected gradient; the other blocks either contribute to Lagrange multipliers that are unneeded for the flow, or are multiplied with entries that are always zero in the input. Thus, we only need the expression for the top-left block, which becomes $$A^{-1} + A^{-1} C^{\top} (M/A)^{-1} C A^{-1}.$$ We cannot assemble this block explicitly (nor would we want to for efficiency reasons), but we can multiply by this block by applying each of the operators in order, producing the expression $$G^{-1} x = A^{-1} x + A^{-1} C^{\top} (M / A)^{-1} C A^{-1} x.$$ This has the appearance of a ``correction'' being applied to the otherwise unconstrained projection $A^{-1} x$. Though $A^{-1}$ occurs 3 times in this expression, we only need to apply $A^{-1}$ twice, since the initial value of $A^{-1}x$ can be reused for both terms.

We do need to invert $(M/A)$, which is a dense matrix. However, it is of size $k \times k$, matching the number of real-valued constraints, so as long as this number is a small constant, the cost is negligible. Importantly, though, this means that this method will not scale to larger numbers of constraints (e.g. one constraint per triangle).

\subsection{Barycenter constraints}

At first, it seems reasonable to include barycenter constraints in the rows of $C$; this matches the way in which we've traditionally organized the saddle matrix in the past. But in fact, there is no need to do this. The above expressions for the Schur complement require that $A$ is invertible, and because $A$ is a fractional Laplacian, this is only true if we augment $A$ itself with barycenter constraints to factor out the null space of translations. This is exactly what we do with the approximation of Section \ref{sec:FractionalLaplacianInverseApproximation} -- we include barycenter constraints on the two integer Laplacians to make them invertible.

As such, including barycenter constraints in $C$ would not only be redundant, but would also require three additional applications of $A^{-1}$ as part of evaluating $A^{-1}C^{\top}$. Conceptually, we can instead organize the saddle matrix this way:
$$
\left[
\begin{array}{cc}
\left[
\begin{array}{cc}
A & B^{\top} \\
B & 0
\end{array}\right] & C^{\top} \\
C & 0
\end{array}
\right]
$$
where $B$ specifically corresponds to the rows for the barycenter constraint, and $C$ contains all the other constraints. Thus, the same saddle matrix is being inverted, but we save on applications of $A^{-1}$ by handling $B$ with the fractional Laplacian itself -- which we would need to do anyway to make it invertible.

\end{document}


\documentclass[11pt,letterpaper]{article}

\usepackage[pdftex]{graphicx}
\usepackage{natbib}
\usepackage{fullpage}
\usepackage{lineno}
\usepackage{multirow}
\usepackage{wrapfig}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{sidecap}
\usepackage{hyperref}

\begin{document}

\setlength{\parindent}{0mm}
\setlength{\parskip}{0.4cm}

\bibliographystyle{apalike}

%\modulolinenumbers[5]
%\linenumbers

\title{\textbf{GEMINI} test descriptions}
\author{Matthew D. Zettergren, PhD\\ Associate Professor of Engineering Physics\\ Center for Space and Atmospheric Physics\\ Physical Sciences Department \\Embry-Riddle Aeronautical University\\mattzett@gmail.com\\zettergm@erau.edu}
\maketitle

\tableofcontents

\pagebreak

\section{Purpose of this document}

The \textbf{G}eospace \textbf{E}nvironment \textbf{M}odel of \textbf{I}on-\textbf{N}eutral \textbf{I}nteractions (GEMINI) is a general-purpose, three-dimensional (3D) terrestrial ionospheric model capable of describing most processes relevant to the ionosphere at medium to small spatial scales (200 m to 10000 km).  The main source code repository for GEMINI can be found at \url{https://github.com/gemini3d/GEMINI}.  This document describes the formulation of tests used to verify the GEMINI build and functioning.

\section{Diffusion solver test problem, Dirichlet conditions}

As discussed in the formulation document \url{https://github.com/gemini3d/GEMINI-docs/blob/master/formulation/GEMINI.pdf}, the parabolic portions of the energy equations are solved using implicit finite difference methods (including TRBDF2 and backward Euler).  These are tested via solution of a simple heat equation describing the evolution of temperature $T(z,t)$ in space and time subject to uniform thermal conduction:
\begin{equation}
\frac{\partial T}{\partial t} - \lambda \frac{\partial^2 T}{\partial z^2} = 0.
\end{equation}
For purposes of testing we solve this equation on the \emph{bounded} domain $0 \le x \le 1$.  Invoking separation of variables we presume $T(z,t)=Z(z) \mathcal{T}(t)$ and substitute back into the original equation:
\begin{equation}
\frac{1}{\lambda \mathcal{T}} \frac{\partial \mathcal{T}}{\partial t} - \frac{1}{Z} \frac{\partial^2 Z}{\partial z^2} = 0.
\end{equation}
Each term depends solely on one of the independent variables $x,t$, which implies that for this relation to be valid for all $x,t$ then each term must be equal to a constant.
\begin{eqnarray}
\frac{1}{\lambda \mathcal{T}} \frac{d \mathcal{T}}{d t} &=& -k^2 \\
- \frac{1}{Z} \frac{d^2 Z}{d z^2} &=& k^2.
\end{eqnarray}
Note also that since we have dependence on only one variable that we have converted the derivatives into \emph{ordinary} derivatives.  The solutions to these ODEs read:
\begin{eqnarray}
\mathcal{T}(t) &=& A e^{-k^2 \lambda t} \\
Z(z) &=& A' \sin kz + B' \cos kz
\end{eqnarray}
The elemental solution ($k$ arbitrary) is given by:
\begin{equation}
\tilde{T}(z,t)=Z(z) \mathcal{T}(t) = e^{-k^2 \lambda t} \left( A'' \sin kz + B'' \cos kz \right)
\end{equation}
From this equation it is seen that the time scale for decay of a mode with wavenumber $k$ is given by
\begin{equation}
\tau = \frac{1}{k^2 \lambda}
\end{equation}

Further progress toward a general solution requires specific initial and boundary conditions.  For our test problem we assume that the temperature goes to zero on the boundaries ($z \in \{0,1\}$).  Let us also assume that the initial temperature of the system is given by:  $T(z,0) = f(z)$.  First employing the condition $T(0,t)=0$, we find that $B''=0$.  The other boundary condition $T(1,t)=0$ sets restrictions on the argument/eigenvalues of the sine function, namely that $k=n \pi, n \in \mathbb{Z}^+$ is a set of roots for the sine function.  The elemental solution is then:
\begin{equation}
\tilde{T}_n(z,t)= A_n e^{-n^2 \pi^2 \lambda t} \sin \left( n \pi z \right)
\end{equation}
Any integer value chosen for $n$ results in a legitimate solution for the original partial differential equation; therefore, the general solution is a linear superposition of all such solutions.
\begin{equation}
T(z,t)= \sum_{n=1}^{\infty} A_n ~ e^{-n^2 \pi^2 \lambda t} \sin \left( n \pi z \right).
\end{equation}
The initial condition can now be applied to solve for the coefficients $A_n$ by leveraging orthogonality of the sine functions.  That is by making use of the fact that:
\begin{equation}
\left< \sin(n \pi z) | \sin (n' \pi z) \right> = \int_0^1 \sin(n \pi z) \sin (n' \pi z) dz = \frac{1}{2} \delta_{nn'},
\end{equation}
we may produce a solution for $A_n$ from the series solution.  The initial condition is represented in summation form (a Fourer sine series) as:
\begin{equation}
T(z,0) = f(z) = \sum_{n=1}^{\infty} A_n ~ \sin \left( n \pi z \right).
\end{equation}
Taking the scalar product of both sides with $\sin (n' \pi z)$ gives:
\begin{equation}
\left< f(z) | \sin (n' \pi z) \right> = \sum_{n=1}^{\infty} A_n ~ \left< \sin(n \pi z) | \sin (n' \pi z) \right> = \sum_n = \frac{A_n}{2} \delta_{nn'} = \frac{A_{n'}}{2}
\end{equation}
Thus the coefficients are:
\begin{equation}
A_{n'} = 2 \left< f(z) | \sin (n' \pi z) \right> = 2 \int_0^1 f(z) \sin (n' \pi z) dz
\end{equation}

For purposes of testing it is easiest to pick a test problem with boundary conditions that are represented by a finite sum - one way this can be accomplished is by choosing a boundary condition that is an eigenfunction for this particular problem.  Additionally to fully test the algorithms we should should several different modes in order to illustrate different decay times, for example:
\begin{equation}
 f(z) = \sin(2 \pi z) + \sin(8 \pi z).
\end{equation}
From this, and orthogonality of the sine function it follows that:
\begin{equation}
A_{n'} = \left\{ \begin{array}{cc} 2 & n \in \{2,8\} \\ 0 & \mathrm{otherwise}  \end{array} \right. ,
\end{equation}
and that the general solution for this specific set of boundary and initial conditions is:
\begin{equation}
T(z,t) = e^{-4 \pi^2 \lambda t} \sin \left( 2 \pi z \right)+e^{-64 \pi^2 \lambda t} \sin \left( 8 \pi z \right)
\end{equation}

Energy diffusion in GEMINI is only performed in the field-aligned direction.  Thus, for a 3D system we are effectively just executing a sequence of 1D diffusion equation solutions.

\section{Diffusion solver test problem, Dirichlet/Neumann (mixed) conditions}

For this test case we consider a system similar to the previous section but with Neumann boundary conditions asserted at the boundary located at $z=1$, namely:
\begin{equation}
  \frac{\partial T}{\partial z} \left( z=1, t\right) = 0,
\end{equation}
which changes the modal structure of the solutions as described below.  Taking the results of the separation of variables as before:
\begin{eqnarray}
\mathcal{T}(t) &=& A e^{-k^2 \lambda t} \\
Z(z) &=& A' \sin kz + B' \cos kz
\end{eqnarray}
We see that the $z=0$ boundary conditions still leads to $B'=0$, while the remaining conditions is one on the derivative of our solution:
\begin{equation}
    \frac{\partial T}{\partial z} \left( z=1, t\right) = AA' e^{-k^2 \lambda t} k \cos kz = 0
\end{equation}
For $t \ne 0$, we have:
\begin{equation}
\cos kz = 0
\end{equation}
which implies that the condition $k=(2n+1) \pi /2, n \in \mathbb{Z}^+$ must hold so that the Solution reads:
\begin{equation}
T(z,t)= \sum_n A_n e^{-\left( \frac{(2n+1)^2 \pi^2}{4}\right) \lambda t} \sin \left( \frac{(2n+1)\pi}{2} z \right)
\end{equation}

For our initial conditions we again choose two different harmonics, corresponding to $n \in \{ 2,8\}$ so that the initial condition is:
\begin{equation}
 f(z) = \sin \left( \frac{5\pi}{2} z \right) + \sin \left( \frac{17 \pi}{2} z \right)
\end{equation}
yielding a full solution of the form:
\begin{equation}
T(z,t) = e^{- \frac{25\pi^2}{4} \lambda t} \sin \left( \frac{5 \pi}{2} z \right)+e^{- \frac{289 \pi^2}{4} \lambda t} \sin \left( \frac{17 \pi}{2} z \right)
\end{equation}

\section{Potential solver test problem}

The elliptic potential solver is tested using a simplified 2D test problem, Laplace's equation:
\begin{equation}
\frac{\partial^2 \Phi}{\partial x^2} + \frac{\partial^2 \Phi}{\partial y^2} = 0,
\end{equation}
on the domain $0 \le x \le 1, 0 \le y \le 1$ with the boundary conditions $\Phi(x,0)-=\Phi(0,y)=\Phi(1,y)=0, \Phi(x,1)=f(x)$.  Exploying separation of variables $\Phi(x,y)=X(x)Y(y)$ we find the ODE solutions for $X(x)$ and $Y(y)$ to be:
\begin{eqnarray}
X(x) &=& A \sin kx + B \cos kx \\
Y(y) &=& A' \sinh ky + B' \cosh ky
\end{eqnarray}
The boundary conditions dictate the following constraints:  $\Phi(0,y)=0 \implies B=0, \Phi(x,0) \implies B'=0, \Phi(1,y)=0 \implies k=n \pi$.  Thus we have the general solution:
\begin{equation}
\Phi(x,y) = \sum_n A_n \sinh (n \pi y) \sin (n \pi x)
\end{equation}
Again choosing our boundary conditions for this test problem so that only one term in the series survives we may choose:
\begin{equation}
f(x) = \sin(2 \pi x).
\end{equation}
Which gives:
\begin{equation}
f(x) = \sum_n A_n \sinh (n \pi) \sin (n \pi x),
\end{equation}
for the potential evaluated at the non-grounded boundary.  By orthogonality the coefficients are:
\begin{equation}
A_n = \frac{2}{\sinh (n \pi)} \left< f(x) | \sin (n \pi x) \right>;
\end{equation}
however the only nonzero coefficient occurs for $n=2$:
\begin{equation}
A_2 = \frac{2}{\sinh (2 \pi)} \left< \sin(2 \pi x) | \sin (2 \pi x) \right> = \frac{1}{\sinh(2 \pi)};
\end{equation}
The solution for this set of boundary conditions is, thus:
\begin{equation}
\Phi(x,y) = \frac{\sinh (2 \pi y)}{\sinh(2 \pi)} \sin (2 \pi x)
\end{equation}

All potential solutions currently in GEMINI are two-dimensional so this particular test problem is representative of each.

\section{Advection solver test problem}

The advection solver in GEMINI deals with problems of the form:
\begin{equation}
\frac{\partial \rho}{\partial t} + \frac{\partial}{\partial z} \left( \rho v \right) = 0,
\end{equation}
and higher dimensional equivalents (implemented through directional splitting).  For constant velocity (assumed to be given) a simpler equation, which can be solved analytically, results.
\begin{equation}
\frac{\partial \rho}{\partial t} + v \frac{\partial \rho}{\partial z} = 0,
\end{equation}
This equation can be seen to be equivalent to the wave equation by differentiating with respect to time and space respectively giving:
\begin{eqnarray}
\frac{\partial^2 \rho}{\partial t^2} + v \frac{\partial^2 \rho}{\partial t \partial z} &=& 0 \\
\frac{\partial^2 \rho}{\partial z \partial t} + v \frac{\partial^2 \rho}{\partial z^2} &=& 0
\end{eqnarray}
Eliminating the cross partial derivatives from these equations gives the familiar wave equation.
\begin{equation}
\frac{\partial^2 \rho}{\partial t^2} - v^2 \frac{\partial^2 \rho}{\partial z^2} = 0,
\end{equation}
The solution to this particular equation is a wave of the form:
\begin{equation}
\rho(z,t)=f(z-vt),
\end{equation}
where the function $f$ is arbitrary, generally speaking, but dictated by the specific initial conditions of the problem of interest.  This solution can be verified by direct substitution, or derived by separation of variables - analogous to the test problems above.  For an initial condition given by:
\begin{equation}
\rho(z,0)=e^{-\frac{z^2}{2 \sigma_z^2}}
\end{equation}
The solution at later times is:
\begin{equation}
\rho(z,t)=e^{-\frac{(z-vt)^2}{2 \sigma_z^2}}
\end{equation}
For testing purposes it is useful to numerical solve this on a periodic domain, e.g. $0 \le x \le 1$.

GEMINI advects mass, momentum, and energy in all three dimensions, representative of the equation:
\begin{eqnarray}
\frac{\partial \rho}{\partial t} + v_x \frac{\partial \rho}{\partial x} + v_y \frac{\partial \rho}{\partial y} + v_z \frac{\partial \rho}{\partial z} &=& 0 %\\
%\frac{\partial \rho}{\partial t} + \mathbf{v} \cdot \nabla \rho &=& 0 \\
\end{eqnarray}
For initial conditions given by:
\begin{equation}
\rho(z,0)=e^{-\frac{x^2}{2 \sigma_x^2}}e^{-\frac{y^2}{2 \sigma_y^2}}e^{-\frac{z^2}{2 \sigma_z^2}}
\end{equation}
the solution at later time is:
\begin{equation}
\rho(z,t)=e^{-\frac{(x-v_x t)^2}{2 \sigma_x^2}}e^{-\frac{(y - v_y t)^2}{2 \sigma_y^2}}e^{-\frac{(z-v_z t)^2}{2 \sigma_z^2}}
\end{equation}

\section{Error reporting}

Please create an issue on our GitHub website \url{https://github.com/gemini3d/} if you find an error in our documentation or codes.

\section{Contributors}

Major contributors to GEMINI source code and testing include:  M. Hirsch, G. Grubbs, and M. Burleigh.

\pagebreak
%\setcounter{page}{1}

%\bibliography{GEMINI.bib}

\end{document}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                              %
%   PAW   - Reference Manual -- LaTeX Source                                   %
%                                                                              %
%   PAW system functions (used by kuipch2.tex)                                 %
%                                                                              %
%   Editor: Michel Goossens / CN-AS                                            %
%   Last Mod.: 6 October 1993 oc                                               %
%                                                                              %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Histograms inquiry functions}
\begin{UL}
\item\texttt{\$HEXIST(id)} returns 1 if histogram \texttt{id} exists or 0 otherwise
\item\texttt{\$HINFO(id,'ENTRIES')} returns the number of entries.
\item\texttt{\$HINFO(id,'MEAN')} returns the mean value.
\item\texttt{\$HINFO(id,'RMS')} returns the standard deviation.
\item\texttt{\$HINFO(id,'EVENTS')} returns the number of equivalent event.
\item\texttt{\$HINFO(id,'OVERFLOW')} returns the content of overflow channel.
\item\texttt{\$HINFO(id,'UNDERFLOW')} returns the content of underflow channel.
\item\texttt{\$HINFO(id,'MIN')} returns the minimum bin content.
\item\texttt{\$HINFO(id,'MAX')} returns the maximum bin content.
\item\texttt{\$HINFO(id,'SUM')} returns the total histogram content.
\item\texttt{\$HINFO(id,'XBINS')} returns the number of bins in X direction.
\item\texttt{\$HINFO(id,'XMIN')} returns the lower histogram limit in X direction.
\item\texttt{\$HINFO(id,'XMAX')} returns the upper histogram limit in X direction.
\item\texttt{\$HINFO(id,'YBINS')} returns the number of bins in Y direction.
\item\texttt{\$HINFO(id,'YMIN')} returns the lower histogram limit in Y direction.
\item\texttt{\$HINFO(id,'YMAX')} returns the upper histogram limit in Y direction.
\item\texttt{\$HTITLE(id)} returns the histogram title.
\end{UL}

\subsection{Graphics inquiry functions}
\begin{UL}
\item\texttt{\$GRAFINFO('XZONES')} returns the number of zones in X direction.
\item\texttt{\$GRAFINFO('YZONES')} returns the number of zones in Y direction.
\item\texttt{\$GRAFINFO('NT')}
returns the current normalization transformation number.
\item\texttt{\$GRAFINFO('WNXMIN')}
returns the lower X limit of window in current NT.
\item\texttt{\$GRAFINFO('WNXMAX')}
returns the upper X limit of window in current NT.
\item\texttt{\$GRAFINFO('WNYMIN')}
returns the lower Y limit of window in current NT.
\item\texttt{\$GRAFINFO('WNYMAX')}
returns the upper Y limit of window in current NT.
\item\texttt{\$GRAFINFO('VPXMIN')}
returns the lower X limit of viewport in current NT.
\item\texttt{\$GRAFINFO('VPXMAX')}
returns the upper X limit of viewport in current NT.
\item\texttt{\$GRAFINFO('VPYMIN')}
returns the lower Y limit of viewport in current NT.
\item\texttt{\$GRAFINFO('VPYMAX')}
returns the upper Y limit of viewport in current NT.
\item\texttt{\$GRAFINFO('?attr')} returns the current value of the \HPLOT/\HIGZ{}
                              attribute \texttt{attr}. See the HELP of the command
                              \texttt{SET} to have the list of the valid values of
                              \texttt{attr}.
\end{UL}

\subsection{Cuts manipulations}
\begin{UL}
\item\texttt{\$CUT(n)} returns the cut expression \texttt{\$n}
\item\texttt{\$CUTEXPAND(string)}
replace \texttt{\$n} in the (quoted) string by \texttt{\$CUT(n)}
\end{UL}


\section{Theoretical Properties}
\label{sec:properties}
In this section, we see how the simplicity of the Elo-MMR formulas enables us to rigorously prove that the rating system is incentive-compatible, robust, and computationally efficient.

%\aram{erase this?} First, we discuss some properties that Elo-MMR has in common with the published systems of Codeforces and Topcoder, as well as the classical two-player systems Elo and Glicko. All of these systems propagate belief changes forward in time, never backward. This approach is simple, efficient, and has the benefit of never retroactively changing ratings from the past, nor the ratings of players who are not actively competing. In practice, Elo-MMR and Glicko also converge to the right results slightly faster than the others, by including an uncertainty parameter that starts high for new players.
\vspace{-.6em}
\subsection{Incentive-compatibility}
\label{sec:mono}

%\aram{erase this?} \emph{Aligned incentives} is one of our system's most important properties, so we devote this section to motivating, stating, and proving it. The main result, \Cref{thm:mono}, essentially guarantees that a player who seeks to improve their rating will never want to lose rounds, even if given the benefit of hindsight.

%To see that a "rational" rating system may fail monotonicity we begin with two examples.

%First, let's imagine a setting in which players typically maintain their "momentum"; that is, a player whose skill is improving rapidly, is expected to continue improving rapidly. A strategic player may then fake some momentum by intentionally performing at a weaker level, before returning to their actual level. The system may then believe that the player will continue to improve, granted inflated ratings until strong evidence arises to the contrary. This type of exploit was discovered in both the Topcoder rating system and the Pokemon Go rating system~\cite{forivsektheoretical, pokemongo}.%To show that this example is not just a hypothetical, \aram{cite Glicko-2, Topcoder, Pokemon Go}\cite{forivsektheoretical}.

%Next, we present a more subtle example. Consider a setting that presents players the choice between an easy challenge, which grants 1 point for partial success and 5 points for full success, or a hard challenge which grants 2 points for partial success and 10 points for full success.\footnote{This reward model is frequently used in coding competitions such as the International Olympiad of Informatics.} Experts with a high chance of a full success in the hard challenge should take it, whereas novices are likely to do better with the easy challenge. Let's suppose that, as a result, only experts attempt the hard challenges, and let's further suppose that a fraction of them fail to get a full success. Thus, there is a contingent of players with 2 points, all of whom are experts. If the rating system is powerful enough to know this, it may classify the 2-point players as stronger than the 5-point players, incentivizing a strategic novice to go for the lower point value!

%In summary, rating systems that are too powerful risk incentivizing players to perform cheap imitations of expert player behaviour, even when it undermines the game designer's objective for the player (e.g., to score more points).

To demonstrate the need for incentive-compatibility, let's look at the consequences of violating this property in the Topcoder and Glicko-2 rating systems. These systems track a ``volatility'' for each player, which estimates the variance of their performances. A player whose recent performance history is more consistent would be assigned a lower volatility score, than one with wild swings in performance. The volatility acts as a multiplier on rating changes; thus, players with an extremely low or high performance will have their subsequent rating changes amplified.

While it may seem like a good idea to boost changes for players whose ratings are poor predictors of their performance, this feature has an exploit. By intentionally performing at a weaker level, a player can amplify future increases to an extent that more than compensates for the immediate hit to their rating. A player may even ``farm'' volatility by alternating between very strong and very weak performances. After acquiring a sufficiently high volatility score, the strategic player exerts their honest maximum performance over a series of contests. The amplification eventually results in a rating that exceeds what would have been obtained via honest play. This type of exploit was discovered in Glicko-2 as applied to the Pokemon Go video game~\cite{pokemongo}. Table 5.3 of ~\cite{forivsektheoretical} presents a milder violation in Topcoder competitions.

To get a realistic estimate of the severity of this exploit, we performed a simple experiment on the first five years of the Codeforces contest dataset (see \Cref{sec:datasets}). In \Cref{fig:topcoder-gaming}, we plot the rating evolution of the world's \#1 ranked competitive programmer, Gennady Korotkevich, better known as {\tt tourist}. In the \emph{control} setting, we plot his ratings according to the Topcoder and Elo-MMR($1$) systems. We contrast these against an \emph{adversarial} setting, in which we have {\tt tourist} employ the following strategy: for his first 45 contests, {\tt tourist} plays normally (exactly as in the unaltered data). For his next 45 contests, {\tt tourist} purposely falls to last place whenever his Topcoder rating is above 2975. Finally, {\tt tourist} returns to playing normally for an additional 15 contests.

This strategy mirrors the Glicko-2 exploit documented in~\cite{pokemongo}, and does not require unrealistic assumptions (e.g., we don't demand {\tt tourist} to exercise very precise control over his performances). Compared to a consistently honest {\tt tourist}, the volatility farming {\tt tourist} ended up \emph{523 rating points ahead} by the end of the experiment, with almost 1000 rating points gained in the last 15 contests alone. Transferring the same sequence of performances to the Elo-MMR($1$) system, we see that it not only is immune to such volatility-farming attacks, but it also penalizes the dishonest strategy with a rating loss that decays exponentially once honest play resumes.

\begin{figure}
\begin{minipage}{0.50\textwidth}
    \includegraphics[width=0.95\textwidth]{images/topcoder.eps}
    \includegraphics[width=0.95\textwidth]{images/elo-mmr.eps}
\end{minipage}
    \caption{Volatility farming attack on the Topcoder system.}
    \label{fig:topcoder-gaming}
\end{figure}

Recall that a key purpose of modeling volatility in Topcoder and Glicko-2 was to boost rating changes for inconsistent players. Remarkably, Elo-MMR achieves the same effect: we'll see in \Cref{sec:robust} that, for $\rho\in [0,\infty)$, Elo-MMR($\rho$) also boosts changes to inconsistent players. And yet, we'll now prove that no strategic incentive for purposely losing exists in \emph{any} version of Elo-MMR.

To this end, we need a few lemmas. Recall that, for the purposes of the algorithm, the performance $p_i$ is defined to be the unique zero of the function $Q_i(p) := \sum_{j \succ i} l_j(p) + \sum_{j \sim i} d_j(p) + \sum_{j \prec i} v_j(p)$, whose terms $l_j,d_j,v_j$ are contributed by opponents against whom $i$ lost, drew, or won, respectively. Wins (losses) are always positive (negative) contributions to a player's performance score:
\begin{lemma}
\label{lem:mono-term}
Adding a win term to $Q_i(\cdot)$, or replacing a tie term by a win term, always increases its zero. Conversely, adding a loss term, or replacing a tie term by a loss term, always decreases it.
\end{lemma}

\begin{proof}
By \Cref{lem:decrease}, $Q_i(p)$ is decreasing in $p$. Thus, adding a positive term will increase its zero whereas adding a negative term will decrease it. The desired conclusion follows by noting that, for all $j$ and $p$, $v_j(p)$ and $v_j(p)-d_j(p)$ are positive, whereas $l_j(p)$ and $l_j(p)-d_j(p)$ are negative.
\end{proof}

While not needed for our main result, a similar argument shows that performance scores are monotonic across the round standings:

\begin{theorem}
If $i \succ j$ (that is, player $i$ beats $j$) in a given round, then player $i$ and $j$'s performance estimates satisfy $p_i > p_j$.
\end{theorem}

\begin{proof}
If $i \succ j$ with $i,j$ adjacent in the rankings, then
\[Q_i(p) - Q_j(p) = \sum_{k\sim i}(d_k(p) - l_k(p)) + \sum_{k\sim j}(v_k(p) - d_k(p)) > 0.\]
for all $p$. Since $Q_i$ and $Q_j$ are decreasing functions, it follows that $p_i > p_j$. By induction, this result extends to the case where $i,j$ are not adjacent in the rankings.
\end{proof}

What matters for incentives is that performance scores be \emph{counterfactually} monotonic; meaning, if we were to alter the round standings, a strategic player will always prefer to place higher:
\begin{lemma}
\label{lem:mono-perf}
In any given round, holding fixed the relative ranking of all players other than $i$ (and holding fixed all preceding rounds), the performance $p_i$ is a monotonic function of player i's prior rating and of player $i$'s rank in this round.
\end{lemma}

\begin{proof}
Monotonicity in the prior rating follows directly from monotonicity of the self-tie term $d_i$ in $Q_i$. Since an upward shift in the rankings can only convert losses to ties to wins, monotonicity in contest rank follows from \Cref{lem:mono-term}.
\end{proof}

Having established the relationship between round rankings and performance scores, the next step is to prove that, even with hindsight, players will always prefer their performance scores to be as high as possible:

\begin{lemma}
\label{lem:mono-rate}
Holding fixed the set of contest rounds in which a player has participated, their current rating is monotonic in each of their past performance scores.
\end{lemma}

\begin{proof}
The player's rating is given by the zero of $L'$ in \Cref{eq:multiplicities}. The pseudodiffusions of \Cref{sec:skill-drift} modify each of the $\beta_k$ in a manner that does not depend on any of the $p_k$, so they are fixed for our purposes. Hence, $L'$ is monotonically increasing in $s$ and decreasing in each of the $p_k$. Therefore, its zero is monotonically increasing in each of the $p_k$.

This is almost what we wanted to prove, except that $p_0$ is not a performance. Nonetheless, it is a function of the performances: specifically, a weighted average of historical ratings which, using this same lemma as an inductive hypothesis, are themselves monotonic in past performances. By induction, the proof is complete.
\end{proof}

Finally, we conclude that a rating-maximizing player is always motivated to improve their round rankings, or raw scores:

\begin{theorem}[Incentive-compatibility]
\label{thm:mono}
Holding fixed the set of contest rounds in which each player has participated, and the historical ratings and relative rankings of all players other than $i$, player $i$'s current rating is monotonic in each of their past rankings.
\end{theorem}

\begin{proof}
Choose any contest round in player $i$'s history, and consider improving player $i$'s rank in that round while holding everything else fixed. It suffices to show that player $i$'s current rating would necessarily increase as a result.

In the altered round, by \Cref{lem:mono-perf}, $p_i$ is increased; and by \Cref{lem:mono-rate}, player $i$'s post-round rating is increased. By \Cref{lem:mono-perf} again, this increases player $i$'s performance score in the following round. Proceeding inductively, we find that performance scores and ratings from this point onward are all increased.
\end{proof}

In the special cases of Elo-MM$\chi$ or Elo-MMR($\infty$), the rating system is ``memoryless'': the only data retained for each player are the current rating $\mu_{i,t}$ and uncertainty $\sigma_{i,t}$; detailed performance history is not saved. In this setting, we present a natural monotonicity theorem. A similar theorem was previously stated for the Codeforces system, albeit in an informal context without proof~\cite{Codeforces}.

\begin{theorem}[Memoryless Monotonicity]
In either the Elo-MM$\chi$ or Elo-MMR($\infty$) system, suppose $i$ and $j$ are two participants of round $t$. Suppose that the ratings and corresponding uncertainties satisfy $\mu_{i,t-1} \ge \mu_{j,t-1},\; \sigma_{i,t-1} = \sigma_{j,t-1}$. Then, $\sigma_{i,t} = \sigma_{j,t}$. Furthermore:

If $i \succ j$ in round $t$, then $\mu_{i,t} > \mu_{j,t}$.

If $j \succ i$ in round $t$, then $\mu_{j,t} - \mu_{j,t-1} > \mu_{i,t} - \mu_{i,t-1}$.
\end{theorem}

\begin{proof}
The new contest round will add a rating perturbation with variance $\gamma_t^2$, followed by a new performance with variance $\beta_t^2$. As a result,
\[\sigma_{i,t}
= \left( \frac{1}{\sigma_{i,t-1}^2 + \gamma_t^2} + \frac{1}{\beta_t^2} \right)^{-\frac 12}
= \left( \frac{1}{\sigma_{j,t-1}^2 + \gamma_t^2} + \frac{1}{\beta_t^2} \right)^{-\frac 12}
= \sigma_{j,t}.\]

The remaining conclusions are consequences of three properties: memorylessness, incentive-compatibility (\Cref{thm:mono}), and translation-invariance (ratings, skills, and performances are quantified on a common interval scale relative to one another).

Since the Elo-MM$\chi$ or Elo-MMR($\infty$) systems are memoryless, we may replace the initial prior and performance histories of players with any alternate histories of our choosing, as long as our choice is compatible with their current rating and uncertainty. For example, both $i$ and $j$ can be considered to have participated in the same set of rounds, with $i$ always performing at $\mu_{i,t-1}$. and $j$ always performing at $\mu_{j,t-1}$. Round $t$ is unchanged.

Suppose $i \succ j$. Since $i$'s historical performances are all equal or stronger than $j$'s, \Cref{thm:mono} implies $\mu_{i,t} > \mu_{j,t}$.

Suppose $j \succ i$. By translation-invariance, if we shift each of $j$'s performances, up to round $t$ and including the initial prior, upward by $\mu_{i,t-1} - \mu_{j,t-1}$, the rating changes between rounds will be unaffected. Players $i$ and $j$ now have identical histories, except that we still have $j\succ i$ at round $t$. Therefore, $\mu_{j,t-1} = \mu_{i,t-1}$ and, by \Cref{thm:mono}, $\mu_{j,t} > \mu_{i,t}$. Subtracting the equation from the inequality proves the second conclusion.
\end{proof}

\subsection{Robust response}
\label{sec:robust}

Another desirable property in many settings is robustness: a player's rating should not change too much in response to any one contest, no matter how extreme their performance. The Codeforces and TrueSkill systems lack this property, allowing for unbounded rating changes. Topcoder achieves robustness by clamping any changes that exceed a cap, which is initially high for new players but decreases with experience.

When $\rho>0$, Elo-MMR($\rho$) achieves robustness in a natural, smoother manner. To understand how, we look at the interplay between Gaussian and logistic factors in the posterior. Recall the notation in \Cref{eq:multiplicities}, describing the loss function and weights.

\begin{theorem}
\label{thm:robust}
In the Elo-MMR($\rho$) rating system, let
\[\Delta_+ := \lim_{p_t\rightarrow+\infty} \mu_{t}-\mu_{t-1},
\quad\Delta_- := \lim_{p_t\rightarrow-\infty}\mu_{t-1}-\mu_{t}.
\]
Then, for $\Delta_\pm \in \{\Delta_+, \Delta_-\}$,
\[\frac{\pi}{\beta_t\sqrt 3}
\left(w_0 + \frac{\pi^2}{6}\sum_{k\in\cH_{t-1}}w_k \right)^{-1}
\le \Delta_\pm
\le \frac{\pi}{\beta_t\sqrt 3}\frac{1}{w_0}.\]
%Then $\Delta_{min} \le \Delta < \Delta_{max}$, where
%\begin{align*}
%\Delta_{min} + \frac{2\pi\beta_t\beta_0^2}{\sqrt 3}(\sum_{k\in\mathcal R}\frac{1}{\beta_k})\tanh\frac{\Delta_{min}\pi}{4\sqrt 3 \beta_t} &= \frac{\pi\beta_0^2}{\beta_t\sqrt 3}
%\\\Delta_{max} &= \frac{\pi\beta_0^2}{\beta_t\sqrt 3}
%\end{align*}
\end{theorem}

\begin{proof}
The limits exist, by monotonicity. Using the fact that $0 < \frac{d}{dx}\tanh(x) \le 1$, differentiating $L'$ in \Cref{eq:multiplicities} yields
\[\forall s\in\mathbb R,\; w_0 \le L''(s)
\le w_0 + \frac{\pi^2}{6}\sum_{k\in\cH_{t-1}}w_k.\]

Now, the performance at round $t$ adds a new term with multiplicity one to $L'(s)$: its value is
$\frac{\pi}{\beta_k\sqrt{3}} \tanh \frac{(s-p_k)\pi}{\beta_k\sqrt{12}}$.

As a result, for every $s\in\mathbb R$, in the limit as $p_t\rightarrow\pm\infty$, $L'(s)$ increases by $\mp\frac{\pi}{\beta_t\sqrt 3}$. Since $\mu_{t-1}$ was a zero of $L'$ without this new term, we now have
$L'(\mu_{t-1}) \rightarrow \mp\frac{\pi}{\beta_t\sqrt 3}.$ Dividing by the former inequalities yields the desired result.
\end{proof}

The proof reveals that the magnitude of $\Delta_{\pm}$ depends inversely on that of $L''$ in the vicinity of the current rating, which in turn is related to the derivative of the $\tanh$ terms. If a player's performances vary wildly, the tanh terms will be widely dispersed, so any potential rating value will necessarily be in the tail ends of most of the terms. Tails contribute very small derivatives, enabling a larger rating change. Conversely, the $\tanh$ terms of a player with a very consistent performance history will contribute large derivatives, so the bound on their rating change will be small.

Thus, Elo-MMR naturally caps the rating changes of all players, and the cap is smaller for consistent performers. The cap will increase after an extreme performance, providing a similar ``momentum'' to the Topcoder and Glicko-2 systems, but without sacrificing incentive-compatibility (\Cref{thm:mono}).

We can compare the lower and upper bound in \Cref{thm:robust}: their ratio is on the same order as the fraction of the total weight that is held by the normal term. Recall that $\rho$ is the weight transfer rate: larger $\rho$ results in more weight being transferred into $w_0$; in this case, the lower and upper bound tend to stay close together. Conversely, the momentum effect is more pronounced when $\rho$ is small. In the extreme case $\rho=0$, $w_0$ vanishes for experienced players, so a sufficiently volatile player would be subject to correspondingly large rating updates. In the extended version of this paper, we quantify an asymptotic steady state for the weights, and argue that $1/\rho$ can be thought of as a momentum parameter.

\subsection{Runtime analysis and optimizations}
\label{sec:runtime}
Let's look at the computation time needed to process a round with participant set $\mathcal P$, where we again omit the round subscript. Each player $i$ has a participation history $\cH_i$.

Estimating $P_i$ entails finding the zero of a monotonic function with $O(|\mathcal P|)$ terms, and then obtaining the rating $\mu_i$ entails finding the zero of another monotonic function with $O(|\cH_i|)$ terms. Using either of the Illinois or Newton methods, solving these equations to precision $\epsilon$ takes $O(\log\log\frac 1\epsilon)$ iterations. As a result, the total runtime needed to process one round of competition is
\[O\left(\sum_{i\in\mathcal P}(|\mathcal P| + |\cH_i|) \log\log\frac 1\epsilon\right).\]
This complexity is more than adequate for Codeforces-style competitions with thousands of contestants and history lengths up to a few hundred. Indeed, we were able to process the entire history of Codeforces on a small laptop in less than half an hour. Nonetheless, it may be cost-prohibitive in truly massive settings, where $|\mathcal P|$ or $|\cH_i|$ number in the millions. Fortunately, it turns out that both functions may be compressed down to a bounded number of terms, with negligible loss of precision.

\paragraph{Adaptive subsampling}
In \Cref{sec:bayes_model}, we used Doob's consistency theorem to argue that our estimate for $P_i$ is consistent. Specifically, we saw that $O(1/\epsilon^2)$ opponents are needed to get the typical error below $\epsilon$. Thus, we can subsample the set of opponents to include in the estimation, omitting the rest. Random sampling is one approach. A more efficient approach chooses a fixed number of opponents whose ratings are closest to that of player $i$, as these are more likely to provide informative match-ups. On the other hand, if the setting requires incentive-compatibility to hold exactly, then one must avoid choosing different opponents for each player.

\paragraph{History compression}
Similarly, it's possible to bound the number of stored factors in the posterior. Our skill-evolution algorithm decays the weights of old performances at an exponential rate. Thus, the contributions of all but the most recent $O(\log\frac 1\epsilon)$ terms are negligible. Rather than erase the older logistic terms outright, we recommend replacing them with moment-matched Gaussian terms, similar to the transfers in \Cref{sec:skill-drift} with $\kappa_t=0$. Since Gaussians compose easily, a single term can then summarize an arbitrarily long prefix of the history.

Substituting $1/\epsilon^2$ and $\log\frac 1\epsilon$ for $|\cP|$ and $|\cH_i|$, respectively, the runtime of Elo-MMR with both optimizations becomes
\[O\left(\frac {|\mathcal P|}{\epsilon^2} \log\log\frac 1\epsilon\right).\]

If the contests are \emph{extremely large}, so that $\Omega(1/\epsilon^2)$ opponents have a rating and uncertainty in the same $\epsilon$-width bucket as player $i$, then it's possible to do even better: up to the allowed precision $\epsilon$, the corresponding terms can be treated as duplicates. Hence, their sum can be determined by counting how many of these opponents win, lose, or tie against player $i$. Given the pre-sorted list of ranks of players in the bucket, two binary searches would yield the answer. In practice, a single bucket might not contain enough participants, so we sample enough buckets to yield the desired precision.

\paragraph{Simple parallelism}
Since each player's rating computation is independent, the algorithm is embarrassingly parallel. Threads can read the same global data structures, so each additional thread contributes only $O(1)$ memory overhead.

% \subsection{erase all this, or present in a different way?}

% Imagine a player who performs very consistently over a long period of time, repeatedly achieving $p_i = 1000$ until convergence. Now, perhaps as a result of attending an intensive training camp in Petrozavodsk, their skill changes dramatically. From this point on, they consistently achieve $p_i = 3000$.

% How does each rating system respond to the first such surprise occurrence? Elo-MMR treats the new result as a fluke, an outlier that ought to be ignored. The player gains 48 points; as a result of the parameters we set, this is the maximum possible for an experienced player as $p_i \rightarrow \infty$. In practice, ratings may change by more than 48, as the maximum depends on existing fluctuations in their history; here we're looking at the extreme example of a player with a history of always performing at exactly $p_i = 1000$.

% \begin{figure}
%     \centering
%     \includegraphics[width=\columnwidth]{images/ResponsePlot.png}
%     \caption{An accelerated convergence effect in the presence of sustained improved performances.}
%     \label{fig:accelerated}
% \end{figure}

% Had we tried to perform outlier reduction in a memoryless fashion, we would continue to increase the rating by 48 per match, oblivious to the possibility that the player truly did experience a sudden improvement. In Elo-MMR, the outlier status of a performance is treated as tentative. If later matches support the hypothesis of having improved, the rating will increase by an additional 63 points, followed by over 100 points in each of the third and following matches, as plotted by the blue curve above.

% After six consecutive matches with $p_i = 3000$, the rating is 1875 and very unstable (even though $\sigma_i$ is unchanged!). The system is no longer sure which to trust: the extensive history at level 1000, or the smaller number of recent matches at level 3000. Depending on what comes next, the player's rating can very quickly fall toward 1000 or rise toward 3000. However, note that in either case, the change will not overshoot, say to 5000, unless enough new evidence is accumulated at that level. As the $p_i=3000$ streak continues, the seventh match on the blue curve jumps by a whopping 566 points. As the player's rating converges to 3000, the old $p_i = 1000$ data acquires outlier status, thus speeding convergence.

% In contrast, while a system such as Codeforces does not compute $p_i$ values in quite in the same way, we can obtain a good approximation by removing outlier reduction from Elo-MMR, effectively treating the performances to be averaged as normal instead of logistic measurements. This makes the system effectively memoryless, since it turns out that each match simply moves the rating about 16\% closer to the new $p_i$ value, independent of the history. With this change, we obtain the orange curve, which jumps a whopping 320 points at the very first performance. Indeed, there is no limit: if you could find players whose ratings are extremely high, and beat them even once, your rating would take arbitrarily large leaps.

% Note that this is not quite true of Topcoder, which incorporates a hack that caps the maximum rating change: if Topcoder's update formula demands too large a change, the cap kicks in. In contrast, Elo-MMR's cap is a natural and smooth consequence of its update formula and is sensitive to whether a change is charting new territory, or merely confirming a plausible hypothesis. Topcoder does attempt to make the magnitude of its updates sensitive to the amount of fluctuation in a player's history, using a volatility measure, but this measure does not account for the direction of the changes, resulting in the non-monotonicity flaw mentioned above.

% Notwithstanding arguments that a high rating ought to properly be earned over multiple matches rather than a single fluke, the other danger is that these observations also hold in reverse: one bad day on Codeforces can seriously damage one's rating and negate several rounds of steady progress. By using heavy-tailed logistic distributions everywhere, Elo-MMR understands that unusually high or low performances do occasionally occur, and one round in isolation is never a reliable signal.

% Interestingly, despite the slow start, the blue curve ultimately converges faster than the orange one. Since Elo-MMR uses its memory to dynamically adapt its view of potential outliers, it overtakes the orange curve as soon as new evidence outweighs the old hypothesis!

% \subsection{Inflation and division boundary artifacts: erase or rewrite?}

% The code and ratings of real Codeforces members as computed by Elo-MMR are available at https://github.com/EbTech/EloR. Original Codeforces ratings are at http://codeforces.com/ratings. One striking difference is massive inflation in the Codeforces system. Gennady Korotkevich, best known by his competitive programming handle ``tourist'', has been the reigning world champion for years. Toward the end of 2011, his rating reached a new ceiling of about 2700 according to both systems. However, as of this writing, his rating on Elo-MMR has increased by about 300 additional points, while on Codeforces it increased by almost 900. To get a sense of the magnitude of this change, 900 points is the difference between an average member and a Grandmaster! Indeed, most of the variance in the Codeforces system is concentrated at the top, with much smaller rating differences between beginner and intermediate members. This is caused by certain ad hoc elements of the system that are not founded on any rigorous model.


\XtoCBlock{PT1}
\label{block:PT1}
\begin{figure}[H]\includegraphics{PT1}\end{figure}

\begin{XtoCtabular}{Inports}
In & Input In(k)\tabularnewline
\hline
\end{XtoCtabular}

\begin{XtoCtabular}{Outports}
Out & Output Out(k)\tabularnewline
\hline
\end{XtoCtabular}

\begin{XtoCtabular}{Mask Parameters}
V & Gain\tabularnewline
\hline
fc & Cut off frequency of low pass filter\tabularnewline
\hline
ts\_fact & Multiplication factor of base sampling time (in integer format)\tabularnewline
\hline
method & Discretization method\tabularnewline
\hline
\end{XtoCtabular}

\subsubsection*{Description:}
First order low pass:

    G(s) = V/(s/w + 1)

% include optional documentation file
\InputIfFileExists{\XcHomePath/Library/Control/Doc/PT1_Info.tex}{\vspace{1ex}}{}

\subsubsection*{Implementations:}
\begin{tabular}{l l}
\textbf{FiP8} & 8 Bit Fixed Point Implementation\tabularnewline
\textbf{FiP16} & 16 Bit Fixed Point Implementation\tabularnewline
\textbf{FiP32} & 32 Bit Fixed Point Implementation\tabularnewline
\textbf{Float32} & 32 Bit Floating Point Implementation\tabularnewline
\textbf{Float64} & 64 Bit Floating Point Implementation\tabularnewline
\end{tabular}

\XtoCImplementation{FiP8}
\index{Block ID!3312}
\nopagebreak[0]
% Implementation details
\begin{tabular}{l l}
\textbf{Name} & FiP8 \tabularnewline
\textbf{ID} & 3312 \tabularnewline
\textbf{Revision} & 0.1 \tabularnewline
\textbf{C filename} & PT1\_FiP8.c \tabularnewline
\textbf{H filename} & PT1\_FiP8.h \tabularnewline
\end{tabular}
\vspace{1ex}

8 Bit Fixed Point Implementation

\begin{XtoCtabular}{Controller Parameters}
b0 & \tabularnewline
\hline
b1 & \tabularnewline
\hline
a0 & \tabularnewline
\hline
sfrb & \tabularnewline
\hline
sfra & \tabularnewline
\hline
in\_old & In(k-1)\tabularnewline
\hline
\end{XtoCtabular}

% Implementation data structure
\XtoCDataStruct{Data Structure:}
\begin{lstlisting}
typedef struct {
     uint16        ID;
     int8          *In;
     int8          Out;
     int8          b0;
     int8          b1;
     int8          a0;
     int8          sfrb;
     int8          sfra;
     int8          in_old;
} PT1_FIP8;
\end{lstlisting}

\ifdefined \AddTestReports
\InputIfFileExists{\XcHomePath/Library/Control/Doc/Test_PT1_FiP8.tex}{}{}
\fi
\XtoCImplementation{FiP16}
\index{Block ID!3313}
\nopagebreak[0]
% Implementation details
\begin{tabular}{l l}
\textbf{Name} & FiP16 \tabularnewline
\textbf{ID} & 3313 \tabularnewline
\textbf{Revision} & 0.1 \tabularnewline
\textbf{C filename} & PT1\_FiP16.c \tabularnewline
\textbf{H filename} & PT1\_FiP16.h \tabularnewline
\end{tabular}
\vspace{1ex}

16 Bit Fixed Point Implementation

\begin{XtoCtabular}{Controller Parameters}
b0 & \tabularnewline
\hline
b1 & \tabularnewline
\hline
a0 & \tabularnewline
\hline
sfrb & \tabularnewline
\hline
sfra & \tabularnewline
\hline
in\_old & In(k-1)\tabularnewline
\hline
\end{XtoCtabular}

% Implementation data structure
\XtoCDataStruct{Data Structure:}
\begin{lstlisting}
typedef struct {
     uint16        ID;
     int16         *In;
     int16         Out;
     int16         b0;
     int16         b1;
     int16         a0;
     int8          sfrb;
     int8          sfra;
     int16         in_old;
} PT1_FIP16;
\end{lstlisting}

\ifdefined \AddTestReports
\InputIfFileExists{\XcHomePath/Library/Control/Doc/Test_PT1_FiP16.tex}{}{}
\fi
\XtoCImplementation{FiP32}
\index{Block ID!3314}
\nopagebreak[0]
% Implementation details
\begin{tabular}{l l}
\textbf{Name} & FiP32 \tabularnewline
\textbf{ID} & 3314 \tabularnewline
\textbf{Revision} & 0.1 \tabularnewline
\textbf{C filename} & PT1\_FiP32.c \tabularnewline
\textbf{H filename} & PT1\_FiP32.h \tabularnewline
\end{tabular}
\vspace{1ex}

32 Bit Fixed Point Implementation

\begin{XtoCtabular}{Controller Parameters}
b0 & \tabularnewline
\hline
b1 & \tabularnewline
\hline
a0 & \tabularnewline
\hline
sfrb & \tabularnewline
\hline
sfra & \tabularnewline
\hline
in\_old & In(k-1)\tabularnewline
\hline
\end{XtoCtabular}

% Implementation data structure
\XtoCDataStruct{Data Structure:}
\begin{lstlisting}
typedef struct {
     uint16        ID;
     int32         *In;
     int32         Out;
     int32         b0;
     int32         b1;
     int32         a0;
     int8          sfrb;
     int8          sfra;
     int32         in_old;
} PT1_FIP32;
\end{lstlisting}

\ifdefined \AddTestReports
\InputIfFileExists{\XcHomePath/Library/Control/Doc/Test_PT1_FiP32.tex}{}{}
\fi
\XtoCImplementation{Float32}
\index{Block ID!3315}
\nopagebreak[0]
% Implementation details
\begin{tabular}{l l}
\textbf{Name} & Float32 \tabularnewline
\textbf{ID} & 3315 \tabularnewline
\textbf{Revision} & 0.1 \tabularnewline
\textbf{C filename} & PT1\_Float32.c \tabularnewline
\textbf{H filename} & PT1\_Float32.h \tabularnewline
\end{tabular}
\vspace{1ex}

32 Bit Floating Point Implementation

\begin{XtoCtabular}{Controller Parameters}
b0 & Coefficient b0\tabularnewline
\hline
b1 & Coefficient b1\tabularnewline
\hline
a0 & Coefficient a0\tabularnewline
\hline
in\_old & In(k-1)\tabularnewline
\hline
\end{XtoCtabular}

% Implementation data structure
\XtoCDataStruct{Data Structure:}
\begin{lstlisting}
typedef struct {
     uint16        ID;
     float32       *In;
     float32       Out;
     float32       b0;
     float32       b1;
     float32       a0;
     float32       in_old;
} PT1_FLOAT32;
\end{lstlisting}

\ifdefined \AddTestReports
\InputIfFileExists{\XcHomePath/Library/Control/Doc/Test_PT1_Float32.tex}{}{}
\fi
\XtoCImplementation{Float64}
\index{Block ID!3316}
\nopagebreak[0]
% Implementation details
\begin{tabular}{l l}
\textbf{Name} & Float64 \tabularnewline
\textbf{ID} & 3316 \tabularnewline
\textbf{Revision} & 0.1 \tabularnewline
\textbf{C filename} & PT1\_Float64.c \tabularnewline
\textbf{H filename} & PT1\_Float64.h \tabularnewline
\end{tabular}
\vspace{1ex}

64 Bit Floating Point Implementation

\begin{XtoCtabular}{Controller Parameters}
b0 & Coefficient b0\tabularnewline
\hline
b1 & Coefficient b1\tabularnewline
\hline
a0 & Coefficient a0\tabularnewline
\hline
in\_old & In(k-1)\tabularnewline
\hline
\end{XtoCtabular}

% Implementation data structure
\XtoCDataStruct{Data Structure:}
\begin{lstlisting}
typedef struct {
     uint16        ID;
     float64       *In;
     float64       Out;
     float64       b0;
     float64       b1;
     float64       a0;
     float64       in_old;
} PT1_FLOAT64;
\end{lstlisting}

\ifdefined \AddTestReports
\InputIfFileExists{\XcHomePath/Library/Control/Doc/Test_PT1_Float64.tex}{}{}
\fi


\subsection{Local properties}

Locally, a topology may have properties which are not present globally.