% Created 2020-09-21 lun 18:01
% Intended LaTeX compiler: pdflatex
\documentclass[presentation,aspectratio=169, usenames, dvipsnames]{beamer}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{grffile}
\usepackage{longtable}
\usepackage{wrapfig}
\usepackage{rotating}
\usepackage[normalem]{ulem}
\usepackage{amsmath}
\usepackage{textcomp}
\usepackage{amssymb}
\usepackage{capt-of}
\usepackage{hyperref}
\usepackage{khpreamble}
\usepackage{amssymb}
\usepgfplotslibrary{groupplots}
\usepackage{pgfplotstable}
\newcommand*{\shift}{\operatorname{q}}
\definecolor{ppc}{rgb}{0.1,0.1,0.6}
\definecolor{iic}{rgb}{0.6,0.1,0.1}
\definecolor{ddc}{rgb}{0.1,0.6,0.1}
\usetheme{default}
\author{Kjartan Halvorsen}
\date{2020-09-21}
\title{Process Automation Laboratory - Anti windup}
\hypersetup{
 pdfauthor={Kjartan Halvorsen},
 pdftitle={Process Automation Laboratory - Anti windup},
 pdfkeywords={},
 pdfsubject={},
 pdfcreator={Emacs 26.3 (Org mode 9.3.6)},
 pdflang={English}}
\begin{document}

\maketitle

\section{Context}
\label{sec:orgd19de8a}
\begin{frame}[label={sec:org69a135a}]{Two -tank model}
\begin{center}
\includegraphics[width=\linewidth]{../../figures/two-tanks-shutoff-valve}
\end{center}
\end{frame}

\section{Repetition PID}
\label{sec:org795dfcf}
\begin{frame}[label={sec:org9f8e291}]{Feedback control}
   \begin{center}
   \begin{tikzpicture}[node distance=22mm, block/.style={rectangle, draw, minimum width=15mm}, sumnode/.style={circle, draw, inner sep=2pt}]
  {
  \node[coordinate] (input) {};
  \node[sumnode, right of=input] (sum) {\tiny $\sum$};
  \node[block, right of=sum, node distance=2.6cm] (reg) {$F(s)$};
  \node[block, right of=reg, node distance=2.6cm] (plant) {$G(s)$};
  \node[coordinate, right of=plant, node distance=2cm] (output) {};
  \node[coordinate, below of=plant, node distance=12mm] (feedback) {};

  \draw[->] (plant) -- node[coordinate, inner sep=0pt] (meas) {} node[near end, above] {$y(t)$} (output);
  \draw[->] (meas) |- (feedback) -| node[very near end, left] {$-$} (sum);
  \draw[->] (input) -- node[very near start, above] {$r(t)$} (sum);
  \draw[->] (sum) -- node[above] {$e(t)$} (reg);
  \draw[->] (reg) -- node[above] {$u(t)$}(plant);
}
\end{tikzpicture}
\end{center}
\end{frame}

\begin{frame}[label={sec:org99d6d2f}]{The PID - practical form}
\definecolor{ppc}{rgb}{0.1,0.1,0.6}
\definecolor{iic}{rgb}{0.6,0.1,0.1}
\definecolor{ddc}{rgb}{0.1,0.5,0.1}

\begin{center}
  \begin{tikzpicture}[node distance=22mm, block/.style={rectangle, draw, minimum width=15mm}, sumnode/.style={circle, draw, inner sep=2pt}]

    \node[coordinate] (input) {};
    \node[sumnode, right of=input, node distance=16mm] (sum) {\tiny $\Sigma$};
    \node[color=iic,block, right of=sum, node distance=28mm] (ii)  {$\frac{1}{\tau_is}$};
    \node[color=ppc, coordinate, above of=ii, node distance=10mm] (pp)  {};
    \node[color=ddc,block, below of=ii, node distance=13mm] (dd)  {$\frac{\tau_ds}{\frac{\tau_d}{N}s + 1}$};
    \node[sumnode, right of=ii, node distance=20mm] (sum2) {\tiny $\Sigma$};
    \node[block, right of=sum2, node distance=20mm] (gain)  {$k_c$};
    \node[coordinate, below of=sum, node distance=12mm] (feedback) {};
    \node[coordinate, right of=gain, node distance=20mm] (output) {};

    \draw[->] (input) -- node[above, pos=0.3] {$r(t)$} (sum);
    \draw[->] (sum) -- node[above, pos=0.2] {$e(t)$} node[coordinate] (mm) {}  (ii);
    \draw[->] (gain) -- node[above, near end] {$u(t)$} (output);
    \draw[->] (feedback) -- node[left, near start] {$y(t)$} node[right, pos=0.95] {-} (sum);
    \draw[->, color=ppc] (mm) |- (pp) -| node[right,] {$u_P(t)$} (sum2);
    \draw[->, color=ddc] (feedback |- dd) -- node[above, pos=0.95] {-} (dd);
    \draw[->, color=ddc] (dd) -| node[right,] {$u_D(t)$} (sum2)  ;
    \draw[->, color=iic] (ii)  -- node[above,] {$u_I(t)$} (sum2);
    \draw[->] (sum2) -- node[above, near end] {} (gain);

  \end{tikzpicture}
\end{center}

The parameter \(N\) is chosen to limit the influence of noisy measurements. Typically,
\[  3 < N < 20 \]
\end{frame}

\begin{frame}[label={sec:org879c25a}]{The PID - practical aspects}
{\footnotesize Åström \& Hägglund (1988) \emph{PID controllers: Theory, design and tuning, 2nd ed} Instrument Society of America.}

\begin{block}{Approximating nonlinear systems with linear models}
\begin{itemize}
\item Model is accurate only in neighborhood of operating point for which system is approximated.
\item Solution: Divide operating range into many regions, with separate PID parameters for each region
\end{itemize}
\end{block}

\begin{block}{Approximating high-order systems with low-order models}
\begin{itemize}
\item Only accurate for low frequencies
\item Beware of behavior for high-frequency input to the closed-loop system
\end{itemize}
\end{block}
\end{frame}

\begin{frame}[label={sec:org2090f62}]{The PID - practical aspects, contd}
\begin{block}{When do PID controllers work well?}
\begin{itemize}
\item The plant dynamics can be well approximated with low-order model
\item Demands on performance not too high
\end{itemize}
\end{block}
\begin{block}{More sophisticated control needed when}
\begin{itemize}
\item Higher order dynamics
\item Oscillatory modes
\item Long deadtime
\end{itemize}
\end{block}
\end{frame}

\begin{frame}[label={sec:org2acf1f0}]{The PID - practical aspects, contd}
\begin{block}{Choice of controller}
\begin{enumerate}
\item P-controller if damping and steady-state error satisfied
\item PI-controller if steady-state error must be zero (often 1st order dynamics)
\item PID-controller if PI does not give sufficient damping (often 2nd order dynamics)
\item Tuning parameter \(\tau_c\) for SIMC tuning method:
\begin{itemize}
\item Smaller (=faster) than \(\tau\) if sufficiently damped and limitations on input signal not violated.
\item larger (=slower) than \(\tau\) if more damping required or smaller input signal required.
\end{itemize}
\end{enumerate}
\end{block}
\end{frame}

\begin{frame}[label={sec:orgf21026c}]{The PID - Parallel form, solution}
\(u(t) = k_c\Big( \textcolor{ppc}{e(t)} + \textcolor{iic}{\overbrace{\frac{1}{\tau_i} \int_0^{t} e(\xi) d\xi}^{u_I(t)}} + \textcolor{ddc}{ \underbrace{\tau_d \frac{d}{dt} \big(-y(t)\big)}_{u_D(t)}} \Big)\)
   \begin{center}
   \def\TT{1}
   \begin{tikzpicture}
   \begin{axis}[
    clip=false,
    width=14cm,
    height=5cm,
    ylabel={},
    xlabel={$t$},
    ymax = 2,
    ]
      \addplot[black, no marks, domain=-0.1:8, samples=200] {(x>0)*(1 - (1+x/\TT)*exp(-x/\TT)} node[coordinate, pin=-20:{$y(t)$}, pos=0.4] {};
      \addplot[magenta!70!black, no marks, domain=-0.1:8, samples=200] coordinates {(-0.1, 0) (0,0) (0,1) (8,1)} node[coordinate, pin=90:{$r(t)$}, pos=0.21] {};
      \addplot[color=ppc, no marks, domain=0:8, samples=200] {(x>=0)*( (1+x/\TT)*exp(-x/\TT)} node[coordinate, pin=20:{$e(t)$}, pos=0.7] {};
      \addplot[color=iic, no marks, domain=-0.1:8, samples=200] {(x>0)*(2*(1-exp(-x/\TT)) - \x/\TT*exp(-x/\TT))} node[coordinate, pin=-20:{$u_I(t)$}, pos=0.6] {};
      \addplot[color=ddc, no marks, domain=-0.1:8, samples=200] {(x>0)*(-\x/\TT*exp(-x/\TT))} node[coordinate, pin=-20:{$u_D(t)$}, pos=0.4] {};
    \end{axis}

 \end{tikzpicture}
\end{center}
\end{frame}

\begin{frame}[label={sec:org432862f}]{The PID - Integral signal}
\begin{center}
  \begin{tikzpicture}[node distance=22mm, block/.style={rectangle, draw, minimum width=15mm}, sumnode/.style={circle, draw, inner sep=2pt}, scale=0.6, every node/.style={scale=0.6}]

    \node[coordinate] (input) {};
    \node[sumnode, right of=input, node distance=16mm] (sum) {\tiny $\Sigma$};
    \node[color=iic,block, right of=sum, node distance=28mm] (ii)  {$\frac{1}{\tau_is}$};
    \node[color=ppc, coordinate, above of=ii, node distance=10mm] (pp)  {};
    \node[color=ddc,block, below of=ii, node distance=10mm] (dd)  {$\tau_ds$};
    \node[sumnode, right of=ii, node distance=20mm] (sum2) {\tiny $\Sigma$};
    \node[block, right of=sum2, node distance=20mm] (gain)  {$k_c$};
    \node[coordinate, below of=sum, node distance=12mm] (feedback) {};
    \node[coordinate, right of=gain, node distance=20mm] (output) {};

    \draw[->] (input) -- node[above, pos=0.3] {$r(t)$} (sum);
    \draw[->] (sum) -- node[above, pos=0.2] {$e(t)$} node[coordinate] (mm) {}  (ii);
    \draw[->] (gain) -- node[above, near end] {$u(t)$} (output);
    \draw[->] (feedback) -- node[left, near start] {$y(t)$} node[right, pos=0.95] {-} (sum);
    \draw[->, color=ppc] (mm) |- (pp) -| node[right,] {$u_P(t)$} (sum2);
    \draw[->, color=ddc] (feedback |- dd) -- node[above, pos=0.95] {-} (dd) -| node[right,] {$u_D(t)$}   (sum2);
    \draw[->, color=iic] (ii)  -- node[above,] {$u_I(t)$} (sum2);
    \draw[->] (sum2) -- node[above, near end] {} (gain);

  \end{tikzpicture}
  \small
  \(  u(t) = k_c\Big( \textcolor{ppc}{e(t)} + \textcolor{iic}{\overbrace{\frac{1}{\tau_i} \int_0^{t} e(\xi) d\xi}^{u_I(t)}} + \textcolor{ddc}{ \underbrace{\tau_d \frac{d}{dt} \big(-y(t)\big)}_{u_D(t)}} \Big)\)
\end{center}

   \begin{center}
   \def\wn{2}
   \def\zz{0.3}
   \pgfmathsetmacro{\wwd}{\wn*sqrt(1-\zz*\zz)}
   \pgfmathsetmacro{\zwn}{\zz*\wn}
  \pgfmathsetmacro{\thangle}{acos(\zz)}
   \begin{tikzpicture}
   \begin{axis}[
    clip=false,
    width=14cm,
    height=4.5cm,
    ylabel={},
    xlabel={$t$},
    ymax = 2,
    ymin = -0.5,
    ]
      \addplot[black, no marks, domain=-0.4:8, samples=200] {(x>0)*(1 - exp(-x * \zwn)/sqrt(1-\zz*\zz) * sin(deg(\wwd*x) + \thangle))} node[coordinate, pin=20:{$y(t)$}, pos=0.3] {};
      \addplot[magenta!70!black, no marks, domain=-0.4:8, samples=200] coordinates {(-0.4, 0) (0,0) (0,1) (8,1)} node[coordinate, pin=90:{$r(t)$}, pos=0.2] {};
    \end{axis}

 \end{tikzpicture}
\end{center}

\alert{Activity} Sketch the error signal \(e(t)\) and the integral signal \(u_I(t)\) (use \(\tau_i=1\))
\end{frame}

\begin{frame}[label={sec:org642bfac}]{The PID - Integral signal - Solution}
   \def\wn{2}
   \def\zz{0.3}
   \pgfmathsetmacro{\wwd}{\wn*sqrt(1-\zz*\zz)}
   \pgfmathsetmacro{\zwn}{\zz*\wn}
  \pgfmathsetmacro{\thangle}{acos(\zz)}
\pgfplotstablenew[ create on use/x/.style={ create col/expr={\pgfplotstablerow/50} },    create on use/y/.style={ create col/expr={ exp(-\thisrow{x} * \zwn)/sqrt(1-\zz*\zz) * sin(deg(\wwd*\thisrow{x}) + \thangle)} }, create on use/int/.style={       create col/expr={\pgfmathaccuma+(\thisrow{y}+\prevrow{y})/2*(\thisrow{x}-\prevrow{x})} }, columns={x,y,int}]{400} \pidtable

\begin{center}
  \begin{tikzpicture}[node distance=22mm, block/.style={rectangle, draw, minimum width=15mm}, sumnode/.style={circle, draw, inner sep=2pt}, scale=0.6, every node/.style={scale=0.6}]

    \node[coordinate] (input) {};
    \node[sumnode, right of=input, node distance=16mm] (sum) {\tiny $\Sigma$};
    \node[color=iic,block, right of=sum, node distance=28mm] (ii)  {$\frac{1}{\tau_is}$};
    \node[color=ppc, coordinate, above of=ii, node distance=10mm] (pp)  {};
    \node[color=ddc,block, below of=ii, node distance=10mm] (dd)  {$\tau_ds$};
    \node[sumnode, right of=ii, node distance=20mm] (sum2) {\tiny $\Sigma$};
    \node[block, right of=sum2, node distance=20mm] (gain)  {$k_c$};
    \node[coordinate, below of=sum, node distance=12mm] (feedback) {};
    \node[coordinate, right of=gain, node distance=20mm] (output) {};

    \draw[->] (input) -- node[above, pos=0.3] {$r(t)$} (sum);
    \draw[->] (sum) -- node[above, pos=0.2] {$e(t)$} node[coordinate] (mm) {}  (ii);
    \draw[->] (gain) -- node[above, near end] {$u(t)$} (output);
    \draw[->] (feedback) -- node[left, near start] {$y(t)$} node[right, pos=0.95] {-} (sum);
    \draw[->, color=ppc] (mm) |- (pp) -| node[right,] {$u_P(t)$} (sum2);
    \draw[->, color=ddc] (feedback |- dd) -- node[above, pos=0.95] {-} (dd) -| node[right,] {$u_D(t)$}   (sum2);
    \draw[->, color=iic] (ii)  -- node[above,] {$u_I(t)$} (sum2);
    \draw[->] (sum2) -- node[above, near end] {} (gain);

  \end{tikzpicture}
  \small
  \(  u(t) = k_c\Big( \textcolor{ppc}{e(t)} + \textcolor{iic}{\overbrace{\frac{1}{\tau_i} \int_0^{t} e(\xi) d\xi}^{u_I(t)}} + \textcolor{ddc}{ \underbrace{\tau_d \frac{d}{dt} \big(-y(t)\big)}_{u_D(t)}} \Big)\)
\end{center}

   \begin{center}
   \def\wn{2}
   \def\zz{0.3}
   \pgfmathsetmacro{\wwd}{\wn*sqrt(1-\zz*\zz)}
   \pgfmathsetmacro{\zwn}{\zz*\wn}
  \pgfmathsetmacro{\thangle}{acos(\zz)}
   \begin{tikzpicture}
   \begin{axis}[
    clip=false,
    width=14cm,
    height=4.5cm,
    ylabel={},
    xlabel={$t$},
    ymax = 2,
    ymin = -0.5,
    ]
      \addplot[black, no marks, domain=-0.4:8, samples=200] {(x>0)*(1 - exp(-x * \zwn)/sqrt(1-\zz*\zz) * sin(deg(\wwd*x) + \thangle))} node[coordinate, pin=20:{$y(t)$}, pos=0.3] {};
      \addplot[color=ppc, no marks, domain=-0.4:8, samples=600] {(x>0)*(exp(-x * \zwn)/sqrt(1-\zz*\zz) * sin(deg(\wwd*x) + \thangle))} node[coordinate, pin=200:{$e(t)$}, pos=0.3] {};
      \addplot [color=iic, thick] table [y=int] {\pidtable};
      \addplot[magenta!70!black, no marks, domain=-0.4:8, samples=200] coordinates {(-0.4, 0) (0,0) (0,1) (8,1)} node[coordinate, pin=90:{$r(t)$}, pos=0.2] {};
    \end{axis}

 \end{tikzpicture}
\end{center}
\end{frame}

\section{Windup}
\label{sec:orgdc284b6}

\begin{frame}[label={sec:org744d11d}]{Integral windup}
\href{https://tecdemonterrey.instructuremedia.com/embed/6fb197b1-38a6-4938-b622-b25d4a45efcc}{Video by Tomás Alejandro Lugo Salinas (MTY)}
\end{frame}

\section{Anti-windup}
\label{sec:org744d659}

\begin{frame}[label={sec:org60c71b8}]{Anti-windup using back-calculation}
\begin{center}
\includegraphics[width=1.02\linewidth]{../../figures/anti-windup-back-calculation.png}
\end{center}
\end{frame}
\end{document}


\chapter{字首樹 Trie}
Things related to Trie data structure.
\newline

\section{Implement Trie (Prefix Tree)} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{sec:implement-trie}

\subsubsection{描述}
Implement a trie with insert, search, and startsWith methods.

Example:
\begin{Code}
Trie trie = new Trie();

trie.insert("apple");
trie.search("apple");   // returns true
trie.search("app");     // returns false
trie.startsWith("app"); // returns true
trie.insert("app");
trie.search("app");     // returns true
\end{Code}

Note:
\begindot
\item You may assume that all inputs are consist of lowercase letters a-z.
\item All inputs are guaranteed to be non-empty strings.
\myenddot

\subsubsection{代碼}
\begin{Code}
// 時間複雜度O()，空間複雜度O()
struct TrieNode {
    bool flag;
    map<char, TrieNode*> next;
};
class Trie {
private:
    TrieNode* root;

public:
    /** Initialize your data structure here. */
    Trie() {
        root = new TrieNode();
    }

    /** Inserts a word into the trie. */
    void insert(string word) {
        TrieNode* p = root;
        for (int i = 0; i < word.length(); ++i) {
            if ((p->next).count(word[i]) <= 0) {
                // insert a new node if the path does not exist
                (p->next).insert(make_pair(word[i], new TrieNode()));
            }
            p = (p->next)[word[i]];
        }
        p->flag = true;
    }

    /** Returns if the word is in the trie. */
    bool search(string word) {
        TrieNode* p = root;
        for (int i = 0; i < word.length(); ++i) {
            if ((p->next).count(word[i]) <= 0) {
                return false;
            }
            p = (p->next)[word[i]];
        }
        return p->flag;
    }

    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        TrieNode* p = root;
        for (int i = 0; i < prefix.length(); ++i) {
            if ((p->next).count(prefix[i]) <= 0) {
                return false;
            }
            p = (p->next)[prefix[i]];
        }
        return true;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * bool param_2 = obj.search(word);
 * bool param_3 = obj.startsWith(prefix);
 */
\end{Code}

\section{Map Sum Pairs} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{sec:map-sum-pairs}

\subsubsection{描述}
Implement a MapSum class with insert, and sum methods.

For the method insert, you'll be given a pair of (string, integer). The string represents the key and the integer represents the value. If the key already existed, then the original key-value pair will be overridden to the new one.

For the method sum, you'll be given a string representing the prefix, and you need to return the sum of all the pairs' value whose key starts with the prefix.

Example 1:
\begin{Code}
Input: insert("apple", 3), Output: Null
Input: sum("ap"), Output: 3
Input: insert("app", 2), Output: Null
Input: sum("ap"), Output: 5
\end{Code}

\subsubsection{分析}
1. 暴力，先記低每一個加入的文字和其數值，當要求總加時，歷遍所有

2. 利用字首樹

\subsubsection{字首樹}
\begin{Code}
// 時間複雜度O(k)，空間複雜度O(n)
class MapSum {
public:
    /** Initialize your data structure here. */
    MapSum() {

    }

    void insert(string key, int val) {
        TrieNode *p = &m_root;
        // delta 是關鍵，用來解決 value replacement 的問題。
        int delta = val - m_cache[key];
        m_cache[key] = val;
        for (const auto& c : key)
        {
            if ((p->m_next).count(c) <= 0)
                (p->m_next).emplace(c, new TrieNode());

            p = (p->m_next)[c];
            p->m_val += delta;
        }
    }

    int sum(string prefix) {
        TrieNode *p = &m_root;

        for (const char& c : prefix)
        {
            if ((p->m_next).count(c) <= 0)
                return 0;

            p = (p->m_next)[c];
        }

        return p->m_val;
    }
private:
    TrieNode m_root;
    unordered_map<string, int> m_cache;
};

/**
 * Your MapSum object will be instantiated and called as such:
 * MapSum* obj = new MapSum();
 * obj->insert(key,val);
 * int param_2 = obj->sum(prefix);
 */
\end{Code}

\section{Replace Words} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{sec:replace-words}

\subsubsection{描述}
In English, we have a concept called root, which can be followed by some other words to form another longer word - let's call this word successor. For example, the root an, followed by other, which can form another word another.

Now, given a dictionary consisting of many roots and a sentence. You need to replace all the successor in the sentence with the root forming it. If a successor has many roots can form it, replace it with the root with the shortest length.

You need to output the sentence after the replacement.

Example 1:
\begin{Code}
Input: dict = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
Output: "the cat was rat by the bat"
\end{Code}

Constraints:
\begindot
\item The input will only have lower-case letters.
\item 1 <= dict.length <= 1000
\item 1 <= dict[i].length <= 100
\item 1 <= sentence words number <= 1000
\item 1 <= sentence words length <= 1000
\myenddot

\subsubsection{暴力計算}
\begin{Code}
// 時間複雜度O(sum of all w^2)，空間複雜度O(n)
// 先記低全部 prefix，然後每個文子，每個 substring 都檢查一次並且取代原本的文字。
class Solution {
public:
    string replaceWords(vector<string>& dict, string sentence) {
        unordered_set<string> prefixDict(dict.begin(), dict.end());

        string result;
        bool isFirst = true;
        for (const string& word : GetVec(sentence))
        {
            string tmp;
            for (const char& w : word)
            {
                tmp += w;
                if (prefixDict.count(tmp) > 0)
                    break;
            }
            if (isFirst)
                result += tmp;
            else
                result += " " + tmp;
            isFirst = false;
        }

        return result;
    }
private:
    vector<string> GetVec(const string& sentence)
    {
        vector<string> result;
        for (auto i = sentence.begin(); i != sentence.end(); )
        {
            i = find_if(i, sentence.end(), [&](const char& c){ return (c >= 'a' && c <= 'z'); });
            if (i == sentence.end()) return result;

            auto j = find_if(i, sentence.end(), [&](const char& c){ return c == ' '; });
            result.push_back(string(i, j));
            i = j;
        }
        return result;
    }
};
\end{Code}

\subsubsection{Tier}
\begin{Code}
// 時間複雜度O(k)，空間複雜度O(n)
struct TrieNode
{
    bool m_isWord;
    unordered_map<char, TrieNode*> m_next;

    TrieNode () { m_isWord = false; };
};
class Solution {
public:
    string replaceWords(vector<string>& dict, string sentence) {
        // 造字首樹
        TrieNode root;
        for (const string& s : dict)
        {
            TrieNode *p = &root;
            // 每一個字母
            for (const char& c : s)
            {
                if (p->m_next.count(c) <= 0) p->m_next.insert(make_pair(c, new TrieNode));
                p = p->m_next[c];
                if (p->m_isWord) break; // 剪枝，當已經有 prefix 存在
            }
            p->m_isWord = true;
        }

        string result;
        bool isFirst = true;
        for (const string& word : GetVec(sentence, ' '))
        {
            string tmp = GetByPrefix(root, word);
            if (isFirst)
                result += tmp;
            else
                result += " " + tmp;
            isFirst = false;
        }

        return result;
    }
private:
    vector<string> GetVec(const string& sentence, char delimiter)
    {
        string result;
        vector<string> res;
        istringstream iss(sentence);
        while (getline(iss, result, delimiter)) {
            res.push_back(result);
        }
        return res;
    }
    string GetByPrefix(const TrieNode& root, const string& word)
    {
        string result;
        TrieNode const * p = &root;
        for (const char& c : word)
        {
            result += c;
            auto it = p->m_next.find(c);
            if (it != p->m_next.end())
            {
                p = it->second;
                if (p->m_isWord) return result;
            }
            else
                return word;
        }

        return word;
    }
};
\end{Code}

\section{Design Search Autocomplete System} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{sec:design-search-autocomplete-system}

\subsubsection{描述}
Design a search autocomplete system for a search engine. Users may input a sentence (at least one word and end with a special character '\#'). For each character they type except '\#', you need to return the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. Here are the specific rules:

\begindot
\item The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before.
\item The returned top 3 hot sentences should be sorted by hot degree (The first is the hottest one). If several sentences have the same degree of hot, you need to use ASCII-code order (smaller one appears first).
\item If less than 3 hot sentences exist, then just return as many as you can.
\item When the input is a special character, it means the sentence ends, and in this case, you need to return an empty list.
\myenddot

Your job is to implement the following functions:

The constructor function:

AutocompleteSystem(String[] sentences, int[] times): This is the constructor. The input is historical data. Sentences is a string array consists of previously typed sentences. Times is the corresponding times a sentence has been typed. Your system should record these historical data.

Now, the user wants to input a new sentence. The following function will provide the next character the user types:

List<String> input(char c): The input c is the next character typed by the user. The character will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('\#'). Also, the previously typed sentence should be recorded in your system. The output will be the top 3 historical hot sentences that have prefix the same as the part of sentence already typed.

Example:
Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2])
The system have already tracked down the following sentences and their corresponding times:
"i love you" : 5 times
"island" : 3 times
"ironman" : 2 times
"i love leetcode" : 2 times
Now, the user begins another search:

Operation: input('i')
Output: ["i love you", "island","i love leetcode"]
Explanation:
There are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same hot degree. Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be in front of "ironman". Also we only need to output top 3 hot sentences, so "ironman" will be ignored.

Operation: input(' ')
Output: ["i love you","i love leetcode"]
Explanation:
There are only two sentences that have prefix "i ".

Operation: input('a')
Output: []
Explanation:
There are no sentences that have prefix "i a".

Operation: input('\#')
Output: []
Explanation:
The user finished the input, the sentence "i a" should be saved as a historical sentence in system. And the following input will be counted as a new search.

\subsubsection{暴力計算}
\begin{Code}
// 時間複雜度O(k * l)，空間複雜度O(n + mlogm)
class AutocompleteSystem {
public:
    AutocompleteSystem(vector<string>& sentences, vector<int>& times) {
        if (sentences.size() == times.size())
        {
            // 記低每個字句的出現次數
            for (size_t i = 0; i < sentences.size(); i++)
                m_cache.emplace(sentences[i], times[i]);
        }
    }

    vector<string> input(char c) {
        if (c == '#')
        {
            m_cache[m_curSentence] += 1;
            m_curSentence = "";

            return vector<string>();
        }
        else
        {
            m_curSentence += c;
            vector<pair<string, int>> resultCount;
            // 歷遍每一個 sentence 找出 prefix
            for (const auto& [k, v] : m_cache)
            {
                // 找尋 prefix
                if (k.find(m_curSentence) == 0)
                {
                    resultCount.emplace_back(k, v);
                }
            }

            sort(resultCount.begin(), resultCount.end()
                 , [&](const auto& left, const auto& right)
                 {
                     // 先比較出現次數的多少
                     if (left.second == right.second)
                     {
                         // 後比較文字的先後
                         return left.first < right.first;
                     }
                     else
                         return left.second > right.second;
                 });

            vector<string> result; result.reserve(3);
            int loop = 0;
            for (const auto& [str, count] : resultCount)
            {
                result.push_back(str);
                if (++loop >= 3) break;
            }

            return result;
        }
    }
private:
    unordered_map<string, int> m_cache;
    string m_curSentence;
};
\end{Code}


\newpage
\section{Variables}

\begin{Variable}[assumptions]{ASSUMPTIONS}
\index{solve}
After solving a linear or polynomial equation system
with parameters, the variable \name{assumptions} contains a list
of side relations for the parameters. The solution is valid only
as long as none of these expression is zero.
\begin{Examples}
solve({a*x-b*y+x,y-c},{x,y});&
\{\{x=\rfrac{b*c}{a + 1},y=c\}\} \\
assumptions; & \{a + 1\}
\end{Examples}
\end{Variable}

\begin{Variable}[card_no]{CARD_NO}
\index{FORTRAN}\index{output}
\name{card_no} sets the total number of cards allowed in a Fortran
output statement when \name{fort} is on.  Default is 20.

\begin{Examples}
on fort; \\
card_no := 4;                &         CARD_NO=4. \\
z := (x + y)**15;            &
\begin{multilineoutput}{6cm}
      ANS1=5005.*X**6*Y**9+3003.*X**5*Y**10+1365.*X**4*Y**
     . 11+455.*X**3*Y**12+105.*X**2*Y**13+15.*X*Y**14+Y**15
      Z=X**15+15.*X**14*Y+105.*X**13*Y**2+455.*X**12*Y**3+
     . 1365.*X**11*Y**4+3003.*X**10*Y**5+5005.*X**9*Y**6+
     . 6435.*X**8*Y**7+6435.*X**7*Y**8+ANS1
\end{multilineoutput}
\end{Examples}

\begin{Comments}
Twenty total cards means 19 continuation cards.  You may set it for more
if your Fortran system allows more.  Expressions are broken apart in a
Fortran-compatible way if they extend for more than \name{card_no}
continuation cards.
\end{Comments}
\end{Variable}

\begin{Constant}[e]{E}
The constant \name{e} is reserved for use as the base of the natural
logarithm.  Its value is approximately 2.71828284590, which REDUCE gives
to the current decimal precision when the switch \nameref{rounded} is on.

\begin{Comments}
\name{e} may be used as an iterative variable in a \nameref{for} statement,
or as a local variable or a \nameref{procedure}.  If \name{e} is defined
as a local
variable inside the procedure, the normal definition as the base of the
natural logarithm would be suspended inside the procedure.
\end{Comments}
\end{Constant}

\begin{Variable}[eval\_mode]{EVAL\_MODE}
\index{algebraic}\index{symbolic}
The system variable \name{eval\_mode} contains the current mode, either
\nameref{algebraic} or \nameref{symbolic}.

\begin{Examples}
EVAL\_MODE;                  &        ALGEBRAIC
\end{Examples}

\begin{Comments}
Some commands do not behave the same way in algebraic and symbolic modes.
%You can determine what mode you are in without using this command by noting
%that the numbered prompt in algebraic mode contains a colon (\name{:}), while
%the numbered prompt in symbolic mode contains an asterisk (\name{*}).
\end{Comments}
\end{Variable}

\begin{Variable}[fort\_width]{FORT\_WIDTH}
\index{output}\index{FORTRAN}
The \name{fort\_width} variable sets the number of characters in a line of
Fortran-compatible output produced when the \nameref{fort} switch is on.
Default is 70.

\begin{Examples}
fort_width := 30;            &         FORT\_WIDTH := 30  \\
on fort; \\
df(sin(x**3*y),x);           &         \begin{multilineoutput}{3cm}
      ANS=3.*COS(X
     . **3*Y)*X**2*
     . Y
\end{multilineoutput}
\end{Examples}

\begin{Comments}
\name{fort\_width} includes the usually blank characters at the beginning
of the card.  As you may notice above, it is conservative and makes the
lines even shorter than it was told.
\end{Comments}
\end{Variable}

\begin{Variable}[high_pow]{HIGH\_POW}
\index{polynomial}\index{degree}
The variable \name{high\_pow} is set by \nameref{coeff} to the highest power
of the variable of interest in the given expression.  You can access this
variable for use in further computation or display.

\begin{Examples}
coeff((x+1)^5*(x*(y+3)^2)^2,x); &
\begin{multilineoutput}{6cm}
\{0,
 0,
 Y^{4} + 12*Y^{3} + 54*Y^{2} + 108*Y + 81,
 5*(Y^{4} + 12*Y^{3} + 54*Y^{2} + 108*Y + 81),
 10*(Y^{4} + 12*Y^{3} + 54*Y^{2} + 108*Y + 81),
 10*(Y^{4} + 12*Y^{3} + 54*Y^{2} + 108*Y + 81),
 5*(Y^{4} + 12*Y^{3} + 54*Y^{2} + 108*Y + 81),
 Y^{4} + 12*Y^{3} + 54*Y^{2} + 108*Y + 81\}
\end{multilineoutput} \\
high_pow;                    &        7
\end{Examples}
\end{Variable}

\begin{Constant}{I}
\index{complex}
REDUCE knows \name{i} is the square root of -1,
 and that \IFTEX{$i^2 = -1$}{i^2 = -1}.

\begin{Examples}
(a + b*i)*(c + d*i);         &      A*C + A*D*I + B*C*I - B*D \\
i**2;                        &      -1
\end{Examples}

\begin{Comments}
\name{i} cannot be used as an identifier.  It is all right to use \name{i}
as an index variable in a \name{for} loop, or as a local (\name{scalar})
variable inside a \name{begin...end} block, but it loses its definition as
the square root of -1 inside the block in that case.

Only the simplest properties of \IFTEX{$i$}{i} are known by REDUCE unless
the switch \nameref{complex} is turned on, which implements full complex
arithmetic in factoring, simplification, and functional values.
\name{complex} is ordinarily off.
\end{Comments}
\end{Constant}

\begin{Constant}[infinity]{INFINITY}
The name \name{infinity} is used to represent the infinite positive number.
However, at the present time, arithmetic in terms of this operator reflects
finite arithmetic, rather than true operations on infinity.

\end{Constant}

\begin{Variable}[low\_pow]{LOW\_POW}
\index{degree}\index{polynomial}
The variable \name{low\_pow} is set by \nameref{coeff} to the lowest power
of the variable of interest in the given expression.  You can access this
variable for use in further computation or display.

\begin{Examples}
coeff((x+2*y)**6,y);        &
\begin{multilineoutput}{6cm}
\{X^{6},
 12*X^{5},
 60*X^{4},
 160*X^{3},
 240*X^{2},
 192*X,
 64\}
\end{multilineoutput}\\
low_pow;                    &      0 \\
coeff(x**2*(x*sin(y) + 1),x);
			    &      \{0,0,1,SIN(Y)\} \\
low_pow;                    &      2
\end{Examples}

\end{Variable}

\begin{Constant}[nil]{NIL}
\index{false}
\name{nil} represents the truth value {\it false} in symbolic mode, and is
a synonym for 0 in algebraic mode.  It cannot be used for any other
purpose, even inside procedures or \nameref{for} loops.
\end{Constant}

\begin{Constant}[pi]{PI}
The identifier \name{pi} is reserved for use as the circular constant.
Its value is given by 3.14159265358..., which REDUCE gives to the current
decimal precision when REDUCE is in a floating-point mode.

\begin{Comments}
\name{pi} may be used as a looping variable in a \nameref{for} statement,
or as a local variable in a \nameref{procedure}.  Its value in such cases
will be taken from the local environment.
\end{Comments}
\end{Constant}

\begin{Variable}[requirements]{REQUIREMENTS}
\index{solve}
After an attempt to solve an inconsistent equation system
with parameters, the variable \name{requirements} contains a list
of expressions. These expressions define a set of conditions implicitly
equated with zero. Any solution to this system defines a setting for
the parameters sufficient to make the original system consistent.
\begin{Examples}
solve({x-a,x-y,y-1},{x,y}); & \{\}\\
requirements;&\{a - 1\}
\end{Examples}
\end{Variable}

\begin{Variable}[root\_multiplicities]{ROOT\_MULTIPLICITIES}
\index{root}\index{solve}\index{polynomial}
The \name{root\_multiplicities} variable is set to the list of the
multiplicities of the roots of an equation by the \nameref{solve} operator.

\begin{Comments}
\nameref{solve} returns its solutions in a list.  The multiplicities of
each solution are put in the corresponding locations of the list
\name{root\_multiplicities}.
\end{Comments}
\end{Variable}

\begin{Constant}[t]{T}
The constant \name{t} stands for the truth value {\it true}.  It cannot be used
as a scalar variable in a \nameref{block}, as a looping variable in a
\nameref{for} statement or as an \nameref{operator} name.

\end{Constant}


\hypertarget{structIir_1_1Butterworth_1_1HighShelf}{}\doxysubsection{Iir\+::Butterworth\+::High\+Shelf$<$ Filter\+Order, State\+Type $>$ Struct Template Reference}
\label{structIir_1_1Butterworth_1_1HighShelf}\index{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$@{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$}}

{\ttfamily \#include $<$Butterworth.\+h$>$}

Inheritance diagram for Iir\+::Butterworth\+::High\+Shelf$<$ Filter\+Order, State\+Type $>$\+:\begin{figure}[H]
\begin{center}
\leavevmode
\includegraphics[height=2.400000cm]{structIir_1_1Butterworth_1_1HighShelf}
\end{center}
\end{figure}
\doxysubsubsection*{Public Member Functions}
\begin{DoxyCompactItemize}
\item
void \mbox{\hyperlink{structIir_1_1Butterworth_1_1HighShelf_a19a78cb96c9b2454ccb48745ed50500d}{setup}} (double sample\+Rate, double cutoff\+Frequency, double gain\+Db)
\item
void \mbox{\hyperlink{structIir_1_1Butterworth_1_1HighShelf_aa7fecdca7646acf8962c5d0106fb8b3c}{setup}} (int req\+Order, double sample\+Rate, double cutoff\+Frequency, double gain\+Db)
\item
void \mbox{\hyperlink{structIir_1_1Butterworth_1_1HighShelf_af63e4f43001ae2d9faf44ba6496db562}{setupN}} (double cutoff\+Frequency, double gain\+Db)
\item
void \mbox{\hyperlink{structIir_1_1Butterworth_1_1HighShelf_a7df553be87ce22541c6ffa8af7508898}{setupN}} (int req\+Order, double cutoff\+Frequency, double gain\+Db)
\end{DoxyCompactItemize}

\doxysubsubsection{Detailed Description}
\subsubsection*{template$<$int Filter\+Order = 4, class State\+Type = Direct\+Form\+II$>$\newline
struct Iir\+::\+Butterworth\+::\+High\+Shelf$<$ Filter\+Order, State\+Type $>$}

\mbox{\hyperlink{namespaceIir_1_1Butterworth}{Butterworth}} high shelf filter. Above the cutoff the filter has a specified gain and below it has 0 dB.
\begin{DoxyParams}{Parameters}
{\em Filter\+Order} & Reserves memory for a filter of the order Filter\+Order \\
\hline
{\em State\+Type} & The filter topology\+: \mbox{\hyperlink{classIir_1_1DirectFormI}{Direct\+FormI}}, \mbox{\hyperlink{classIir_1_1DirectFormII}{Direct\+Form\+II}}, ... \\
\hline
\end{DoxyParams}

\doxysubsubsection{Member Function Documentation}
\mbox{\Hypertarget{structIir_1_1Butterworth_1_1HighShelf_a19a78cb96c9b2454ccb48745ed50500d}\label{structIir_1_1Butterworth_1_1HighShelf_a19a78cb96c9b2454ccb48745ed50500d}}
\index{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$@{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$}!setup@{setup}}
\index{setup@{setup}!Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$@{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$}}
\doxyparagraph{\texorpdfstring{setup()}{setup()}\hspace{0.1cm}{\footnotesize\ttfamily [1/2]}}
{\footnotesize\ttfamily template$<$int Filter\+Order = 4, class State\+Type  = Direct\+Form\+II$>$ \\
void \mbox{\hyperlink{structIir_1_1Butterworth_1_1HighShelf}{Iir\+::\+Butterworth\+::\+High\+Shelf}}$<$ Filter\+Order, State\+Type $>$\+::setup (\begin{DoxyParamCaption}\item[{double}]{sample\+Rate,  }\item[{double}]{cutoff\+Frequency,  }\item[{double}]{gain\+Db }\end{DoxyParamCaption})\hspace{0.3cm}{\ttfamily [inline]}}

Calculates the coefficients with the filter order provided by the instantiation
\begin{DoxyParams}{Parameters}
{\em sample\+Rate} & Sampling rate \\
\hline
{\em cutoff\+Frequency} & Cutoff \\
\hline
{\em gain\+Db} & Gain in dB of the filter in the passband \\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{structIir_1_1Butterworth_1_1HighShelf_aa7fecdca7646acf8962c5d0106fb8b3c}\label{structIir_1_1Butterworth_1_1HighShelf_aa7fecdca7646acf8962c5d0106fb8b3c}}
\index{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$@{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$}!setup@{setup}}
\index{setup@{setup}!Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$@{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$}}
\doxyparagraph{\texorpdfstring{setup()}{setup()}\hspace{0.1cm}{\footnotesize\ttfamily [2/2]}}
{\footnotesize\ttfamily template$<$int Filter\+Order = 4, class State\+Type  = Direct\+Form\+II$>$ \\
void \mbox{\hyperlink{structIir_1_1Butterworth_1_1HighShelf}{Iir\+::\+Butterworth\+::\+High\+Shelf}}$<$ Filter\+Order, State\+Type $>$\+::setup (\begin{DoxyParamCaption}\item[{int}]{req\+Order,  }\item[{double}]{sample\+Rate,  }\item[{double}]{cutoff\+Frequency,  }\item[{double}]{gain\+Db }\end{DoxyParamCaption})\hspace{0.3cm}{\ttfamily [inline]}}

Calculates the coefficients
\begin{DoxyParams}{Parameters}
{\em req\+Order} & The actual order which can be less than the instantiated one \\
\hline
{\em sample\+Rate} & Sampling rate \\
\hline
{\em cutoff\+Frequency} & Cutoff \\
\hline
{\em gain\+Db} & Gain in dB of the filter in the passband \\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{structIir_1_1Butterworth_1_1HighShelf_af63e4f43001ae2d9faf44ba6496db562}\label{structIir_1_1Butterworth_1_1HighShelf_af63e4f43001ae2d9faf44ba6496db562}}
\index{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$@{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$}!setupN@{setupN}}
\index{setupN@{setupN}!Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$@{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$}}
\doxyparagraph{\texorpdfstring{setupN()}{setupN()}\hspace{0.1cm}{\footnotesize\ttfamily [1/2]}}
{\footnotesize\ttfamily template$<$int Filter\+Order = 4, class State\+Type  = Direct\+Form\+II$>$ \\
void \mbox{\hyperlink{structIir_1_1Butterworth_1_1HighShelf}{Iir\+::\+Butterworth\+::\+High\+Shelf}}$<$ Filter\+Order, State\+Type $>$\+::setupN (\begin{DoxyParamCaption}\item[{double}]{cutoff\+Frequency,  }\item[{double}]{gain\+Db }\end{DoxyParamCaption})\hspace{0.3cm}{\ttfamily [inline]}}

Calculates the coefficients with the filter order provided by the instantiation
\begin{DoxyParams}{Parameters}
{\em cutoff\+Frequency} & Normalised cutoff frequency (0..1/2) \\
\hline
{\em gain\+Db} & Gain in dB of the filter in the passband \\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{structIir_1_1Butterworth_1_1HighShelf_a7df553be87ce22541c6ffa8af7508898}\label{structIir_1_1Butterworth_1_1HighShelf_a7df553be87ce22541c6ffa8af7508898}}
\index{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$@{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$}!setupN@{setupN}}
\index{setupN@{setupN}!Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$@{Iir::Butterworth::HighShelf$<$ FilterOrder, StateType $>$}}
\doxyparagraph{\texorpdfstring{setupN()}{setupN()}\hspace{0.1cm}{\footnotesize\ttfamily [2/2]}}
{\footnotesize\ttfamily template$<$int Filter\+Order = 4, class State\+Type  = Direct\+Form\+II$>$ \\
void \mbox{\hyperlink{structIir_1_1Butterworth_1_1HighShelf}{Iir\+::\+Butterworth\+::\+High\+Shelf}}$<$ Filter\+Order, State\+Type $>$\+::setupN (\begin{DoxyParamCaption}\item[{int}]{req\+Order,  }\item[{double}]{cutoff\+Frequency,  }\item[{double}]{gain\+Db }\end{DoxyParamCaption})\hspace{0.3cm}{\ttfamily [inline]}}

Calculates the coefficients
\begin{DoxyParams}{Parameters}
{\em req\+Order} & The actual order which can be less than the instantiated one \\
\hline
{\em cutoff\+Frequency} & Normalised cutoff frequency (0..1/2) \\
\hline
{\em gain\+Db} & Gain in dB of the filter in the passband \\
\hline
\end{DoxyParams}

The documentation for this struct was generated from the following file\+:\begin{DoxyCompactItemize}
\item
iir/Butterworth.\+h\end{DoxyCompactItemize}


    \filetitle{dec2dat}{Convert decimal representation of date to IRIS serial date number}{dates/dec2dat}

	\paragraph{Syntax}\label{syntax}

\begin{verbatim}
Dat = dec2dat(Dec,Freq)
\end{verbatim}

\paragraph{Input arguments}\label{input-arguments}

\begin{itemize}
\item
  \texttt{Dec} {[} numeric {]} - Decimal numbers representing dates.
\item
  \texttt{Freq} {[} freq {]} - Date frequency.
\end{itemize}

\paragraph{Output arguments}\label{output-arguments}

\begin{itemize}
\itemsep1pt\parskip0pt\parsep0pt
\item
  Dat {[} numeric {]} - IRIS serial date numbers corresponding to the
  decimal representations \texttt{Dec}.
\end{itemize}

\paragraph{Description}\label{description}

\paragraph{Example}\label{example}


\section{Results}
\paragraph{Modeling Allele Frequency Trajectories in Small Populations.}
We first tested the goodness of fit of the discrete versus Brownian motion (a
continuous-state model) in modeling allele frequency trajectories, under
general E\&R
parameters.  For this purpose, we conducted $100$K simulations with
two time samples $\Tc=\{0,\tau\}$ where $\tau\in \{1,10,100\}$ is the
parameter controlling the density of sampling in time.  In addition,
we repeated simulations for different values of starting frequency
$\nu_0\in\{0.005,0.1\}$ (i.e., hard and soft sweep) and selection
strength $s\in\{0,0.1\}$ (i.e., neutral and selection). Then, given
initial frequency $\nu_0$, we computed the expected distribution of
the frequency of the next sample $\nu_\tau$ under two models to make a
comparison.  \ref{fig:markov}A-F shows that Brownian motion
(continuous model) is inadequate when $\nu_0$ is far from $0.5$, or
when sampling times are sparse ($\tau>1$). If the favored allele
arises from standing variation in a neutral population, it is unlikely
to have frequency close to $0.5$, and the starting frequencies are
usually much smaller (see \ref{fig:sfs}). Moreover, in typical \dmel
experiments for example, sampling is sparse. Often, the experiment is
designed so that $10\le\tau\le100$~\cite{kofler2013guide,
  orozco2012adaptation, zhou2011experimental,franssen2015patterns}.

% XXX Not sufficient to say 'in contrast to brownian motion, markov...
% Please check the rewrite of this part
In contrast to the Brownian motion approximation, discrete Markov
chain predictions (Eq.~\ref{eq:Qt}) are highly consistent with
empirical data for a wide range of simulation parameters
(\ref{fig:markov}A-M). Moreover, the discrete markov chain can be
modified to model the case when the the allele is under
selection.

\begin{figure*}
	\centering
	\includegraphics[width=\textwidth]{{markovDists}.pdf}
	\caption{{\bf Comparison of empirical distributions of allele
			frequencies (red) versus predictions from Brownian
			Motion (green), and Markov chain (blue).}\\
		Comparison of empirical and theoretical distributions under
		neutral evolution (panels A-F) and selection (panels G-M)
		with different starting frequencies $\nu_0\in\{0.005,0.1\}$
		and sampling times of $\Tc=\{0,\tau\}$, where $\tau \in
		\{1,10,100\}$ and $N=1000	$.  For each panel, the empirical
		distribution
		was computed over 100,000 simulations.  Brownian motion
		(Gaussian approximation) provides poor approximations when
		initial frequency is far from 0.5 (A) or sampling is sparse
		(B,C,E,F). In addition, Brownian motion can only provide
		approximations under neutral evolution. In contrast, Markov
		chain consistently provides a good approximation in all
		cases.}
	\label{fig:markov}
\end{figure*}

\paragraph{Detection Power.}
We compared the performance of \comale\ against other methods for
detecting selection. For each method we calculated detection power as
the percentage of true-positives identified with false-positive rate
$\le 0.05$. For each configuration (specified with values for
selection coefficient $s$, starting allele frequency $\nu_0$ and
coverage $\lambda$), power of each method is evaluated over $2000$
distinct simulations, half of which modeled neutral evolution and the
rest modeled positive selection.

We compared the power of \comale\ with Gaussian process
(GP)~\cite{Terhorst2015Multi}, FIT~\cite{feder2014Identifying}, and
CMH~\cite{agresti2011categorical} statistics.  FIT and GP convert read
counts to allele frequencies prior to computing the test statistic.
\comale\ shows the highest power in all cases and the power stays
relatively high even for low coverage (\ref{fig:power} and
\ref{tab:power}). In particular, the difference in performance of
\comale\ with other methods is pronounced when starting frequency is
low.  The advantage of \comale\ stems from the fact that favored
allele with low starting frequency might be missed by low coverage
sequencing. In this case, incorporating the signal from linked sites
becomes increasingly important. We note that methods using only two
time points, such as CMH, do relatively well for high selection values
and high coverage. However, the use of time-series data can increase
detection power in low coverage experiments or when starting frequency
is low. Moreover, time-series data provide means for estimating
selection parameters $s,h$ (see below). Finally, as \comale\ is robust
to change of coverage, our results (\ref{fig:power}B,C) suggest that
taking many samples with lower coverage is preferable to sparse
sampling with higher coverage. For comparison purposes, we also tested
\comale\ using the single locus statistic ($L=1$). For the most part,
\comale\ showed an improvement over other methods even with $L=1$, or
showed similar performance. The performance improved with higher $L$.

\begin{figure*}
	\centering
	\includegraphics[width=\textwidth]{power.pdf}
	\caption{ {\bf Power calculations for detection of selection.}\\
		Detection power for \comale ($\Hc$), Frequency Increment
		Test (FIT), Gaussian Process (GP), and CMH under hard (A-C)
		and soft sweep (D-F) scenarios. $\lambda$, $s$ denote the
		mean coverage and selection coefficient, respectively.
		Orange hexagons represent the performance of \comale\ when
		the maximum of the single-locus statistic is used to make a
		decision for the genomic region, while the red circle
		corresponds to the performance of \comale\ when single locus
		statistics are averaged over the region.  The $y$-axis
		measures power -- sensitivity with false positive rate FPR
		$\le 0.05$ -- for $2,000$ simulations with $N=1,000$,
		$L=50$Kbp. The horizontal line reflects the power of a
		random classifier.  In all simulations, 3 replicates are
		evolved and sampled at generations
		$\Tc=\{0,10,20,30,40,50\}$.}
	\label{fig:power}
\end{figure*}
\paragraph{Site-identification.}
In general, localizing the favored variant, using pool-seq data is a
nontrivial task due to extensive linkage
disequilibrium~\cite{tobler2014massive}.  To measure performance, we
sorted variants by their $H$ scores and computed rank of the favored
allele for each method. For each setting of $\nu_0$ and $s$, we
conducted $1000$ simulations and computed the rank of the favored
mutation in each simulation. The cumulative distribution of the rank
of the favored allele in 1000 simulation for each setting
(\ref{fig:rank}) shows that \comale\ outperforms other statistics.

An interesting observation is revisiting the contrast between
site-identification and
detection~\cite{long2013massive,tobler2014massive}.  When selection
strength is high, detection is easier (\ref{fig:power}A-F), but
site-identification is harder, due to the high LD between flanking
variants and the favored allele (\ref{fig:rank}A-F).  Moreover,
site-identification becomes more difficult whenever the initial
frequency of the favored allele is low, i.e., at the onset of
selection, LD between favored allele and its nearby variants is
high. For example, when coverage $\lambda=100$ and selection
coefficient $s=0.1$, the detection power is 75\% for hard sweep, but
100\% for soft sweep (\ref{fig:power}B-E). In contrast, the favored
site was ranked as the top in 14\% of hard sweep cases, compared to
and 95\% of soft sweep simulations.

\begin{figure*}
	\centering
	\includegraphics[trim=.2in 0 .2in 0,
	clip,width=\textwidth]{{rank100.0}.pdf}
	\caption{{\bf Ranking performance for 100$\times$ coverage.}\\
		Cumulative Distribution Function (CDF) of the distribution
		of the rank of the favored allele in 1000 simulations for
		\comale\ ($H$), Gaussian Process (GP), CMH, and Frequency
		Increment Test (FIT), for different values of selection
		coefficient $s$ and initial carrier frequency. Note that the
		individual variant \comale\ score ($H$) is used to rank
		variants.  The Area Under Curve (AUC) is computed as an overall
		quantitative measure to compare the performance of methods
		for each configuration. In all simulations, 3 replicates with $N=1000$
		are evolved and
		sampled at generations
		$\Tc=\{0,10,20,30,40,50\}$.}
	\label{fig:rank}
\end{figure*}

\paragraph{Estimating Parameters.}
\comale\ estimates effective population size $\hN$ and selection
parameters, $\hat{s}$ and $\hat{h}$, as a byproduct of the hypothesis
testing. We computed bias of selection fitness ($s-\hat{s}$) and
dominance ($h-\hat{h}$) for of \comale\ and GP for 1000 simulations in
each setting. The distribution of the error (bias) for 100$\times$
coverage is presented in \ref{fig:bias100} for different
configurations.  \ref{fig:bias30} and \ref{fig:biasinf} provide the
distribution of estimation errors for 30$\times$, and 300$\times$
coverage, respectively.  For hard sweep, \comale\ provides estimates
of $s$ with lower variance of bias (\ref{fig:bias100}A and
\ref{fig:biasNull}). In soft sweep, GP and \comale\ both provide unbiased
estimates of $s$ with low variance
(\ref{fig:bias100}B). \ref{fig:bias100}~C-D shows that \comale\
provides unbiased estimates of $h$ as well when $h\in\{0,0.5,1,2\}$
and $s=0.1$.  We also tested if \comale\ provide unbiased estimates of
$N$, by estimating population size on 1000 simulations when $N\in
\{200,600,1000\}$. As shown in~\ref{fig:estimateNMLE}-A
and~\ref{fig:estimateN}A-C, maximum
likelihood is attained at true value of the parameter.

\begin{figure*}
	\centering
	\includegraphics[width=0.7\textwidth]{{bias.100}.pdf}
	\caption{{\bf Distribution of bias for 100$\times$ coverage.}\\ The
		distribution of bias ($s-\hat{s}$) in estimating selection
		coefficient over 1000 simulations using Gaussian Process (GP) and
		\comale\ ($H$) is shown for a range of choices for the selection
		coefficient $s$ and starting carrier frequency $\nu_0$, when
		coverage $\lambda=100$ (Panels A,B). GP and \comale\ have similar
		variance in estimates of $s$ for soft sweep, while \comale\ provides
		lower variance in hard sweep. Also see \ref{tab:biasdist}. Panels C,D
		show the variance in the estimation of $h$.
		In all simulations, 3 replicates are evolved and sampled at generations
		$\Tc=\{0,10,20,30,40,50\}$.}
	\label{fig:bias100}
\end{figure*}

\paragraph{Running Time.}
As \comale\ does not compute exact likelihood of a region (i.e., does
not explicitly model linkage between sites), the complexity of
scanning a genome is linear in number of polymorphisms.  Calculating
score of each variant requires and $\Oc(TRN^3)$ computation
for $\Hc$. However, most of the operations
are can be vectorized for all replicates to make the effective running
time for each variant.  We
conducted $1000$ simulations and measured running times for computing site
statistics $H$, FIT, CMH and GP with different number of linked-loci.  Our
analysis reveals (\ref{fig:runTime}) that \comale\ is orders of
magnitude faster than GP, and comparable to FIT. While slower than CMH
on the time per variant, the actual running times are comparable after
vectorization and broadcasting over variants (see below).

These times can have a practical consequence. For instance, to run GP
in the single locus mode on the entire pool-seq data of the \dmel genome from a
small sample ($\approx$1.6M variant sites), it would take 1444 CPU-hours
($\approx$ 1 CPU-month). In contrast, after vectorizing and
broadcasting operations for all variants operations using
\texttt{numba} package, \comale\ took 75 minutes to perform an
scan, including precomputation, while the fastest method, CMH, took 17 minutes.

\begin{figure*}
	\centering
	\includegraphics[width=0.75\textwidth]{{runTime.pdf}}
	\caption{{\bf Running time.}\\ Box plots of running time per
		variant (CPU-secs.) of \comale ($\Hc$), CMH, FIT, and
		GP with single, 3, 5, 7, and 10 loci over 1000 simulations
		conducted on a workstation with Intel Core i7
		processor. The average running time for each method is shown
		on the x-axis.
		In all simulations, 3 replicates are evolved and sampled at generations
		$\Tc=\{0,10,20,30,40,50\}$.}
	\label{fig:runTime}
\end{figure*}

\subsection{Analysis of a \dmel Adaptation to Alternating
Temperatures}\label{sec:dmel}
We applied \comale\ to the
\datadm~\cite{orozco2012adaptation,franssen2015patterns}, where
3 replicate samples were chosen from a population of \dmel for 59
generations under alternating 12-hour cycles of  hot stressful (28$^{\circ}$C)
and non-stressful (18$^{\circ}$C) temperatures and sequenced.  In this dataset,
sequencing coverage is different across replicates and generations
(see S2 Fig of~\cite{Terhorst2015Multi}) which makes variant depths
highly heterogeneous (\ref{fig:depthHetero}).

We first filtered out heterochromatic, centromeric and telomeric
regions~\cite{fiston2010drosophila}, and those variants that have
collective coverage of more that 1500 in all 13 populations: three
replicates at the base population, two replicates at generation 15,
one replicate at generation 23, one replicate at generation 27, three
replicates at generation 37 and three replicates at generation
59. After filtering, we ended up with 1,605,714 variants.

Next, we estimated genome-wide population size $\hN=250$
(\ref{fig:estimateNMLE}-B and \ref{fig:estimateN}-E) which is consistent with
previous
studies~\cite{orozco2012adaptation,jonas2016estimating}. The
likelihood curves of \comale\ are sharper around the optimum compared
to that of Bollback et. al~\cite{bollback2008estimation}'s method (see
Supplementary Fig. 1 in~\cite{orozco2012adaptation}).  Also,
chromosomes 3L and 3R appear to have smaller population
size, $\hN=200,150$, respectively.
Others have
made similar observations on this data. In particular,
J\'{o}n\'{a}s~\emph{et al.}~\cite{jonas2016estimating} shown that the
chromosome-wise population
size varies even more when it is computed for each replicate
separately (see Table 1 in~\cite{jonas2016estimating}). For instance,
$\hN$ is 131 for chromosome 3R replicate 1, while it is 328 for chromosome X
replicate 2.

\begin{figure*}
	\centering
	\includegraphics[width=\textwidth]{estimateNMLE.pdf}
	\caption{{\bf Estimating population size.}  (A) Distribution
		of bias in estimating $N$, computed on 1000 neutral
		simulations for each $N\in\{200,600,1000\}$ when $W=10$Mbp and
		$r=2\times10^{-8}$. (B)
		Estimates
		of population size for \datadm. For each case, the
		distribution of estimator is computed by 100 bootstrap
		computations using 1000 variants each. The multiple modes
		are an artifact of grid search used to speed up
		computation. (C) Distribution of the population 	size
		estimates on the yeast dataset.  Despite large census
		population size ($10^6-10^7$~\cite{burke2014standing}), this
		dataset exhibits much smaller effective population size
		($\hN=2000$). }
	\label{fig:estimateNMLE}
\end{figure*}

While it would be ideal to compute \comale\ statistic for each
replicate and chromosome separately, computing empirical $p$-values
and significant regions become computationally intensive as empirical
null distribution of each replicate and each chromosome needs to be
computed.  Hence, we use a single genome-wide estimate $\hN=250$ in
all analyses, but we normalize statistic $\Hc^*$ separately for each
chromosome.

We use a heuristic calculation (See~\ref{sec:winSize}) to choose the
sliding window size $L$ as the distance where the LD between the
favored mutation and a site $L/2$bp away remains strong. For \dmel
parameters, we obtained $L=30$Kbp. We computed the normalized test
statistic $\Hc^*$ on sliding windows of size of 30Kbp and step size of
5Kbp over the genome (See~\ref{fig:man-dmel-region}-A).

Empirical null distribution of $\Hc^*$ was estimated by creating 100
whole genome simulations (400K statistic values) as described in
Section~\ref{sec:sims}. Then, $p$-value of the test statistic in each
region in the experimental data was calculated as the fraction of the
null statistic values that are greater than or equal to the test
statistic(see~\ref{fig:null-alt}).  After correcting for multiple
testing, we identified $5$ contiguous
intervals~(\ref{fig:man-dmel-region}) satisfying FDR$\le0.05$, and
covering $2,829$ polymorphic sites. We further performed single-locus
hypothesis testing on the $2,829$ sites to identify $174$ individual
variants with FDR $\le0.01$~(\ref{fig:man-dmel-region}-B).

The final set of 174 variants fall within 32 genes(\ref{tab:genes})
including many Serine inhibitory proteases (serpins), and other genes
involved in endocytosis. Recycling of synaptic vesicles is seen to be
blocked at high temperature in temperature sensitive Drosophila
mutants~\cite{kosaka1983reversible}. This is also supported by GO
enrichment analysis, where a single GO term `inhibition of
proteolysis' is found to enriched (corrected $p$-value:0.0041).  To
test for dominant selection, we computed $D$ statistic on simulated
neutral and experimental data, and computed $p$-values accordingly.
After correcting for multiple testing, 96 variants were discovered
with FDR$\le 0.01$~(\ref{fig:man-dmel-snp}).

\subsection{Analysis of Outcrossing Yeast Populations}
We also applied \comale\ to  $12$ replicate samples of
outcrossing yeast populations~\cite{burke2014standing}, where samples are
taken at
generations $\Tc=\{0,180,360,540\}$. We observed a significant
variation in the genome-wide site frequency spectrum of certain
populations over different time points for some
replicates~(\ref{fig:yeast-sfs}). The variation does not have an
easily identifiable cause. Therefore, we focused analysis on seven
replicates $r\in\{3,7,8,9,10,11,12\}$ with genome-wide site-frequency
spectrum over the time range~(\ref{fig:yeast-pca}).

We estimated population size to be $\hN=2000$ haplotypes
(\ref{fig:estimateNMLE}-C and \ref{fig:estimateN}-F), and computed
$\hs$, $\hh$ and $H$ statistic accordingly. To compute $p$-values, we
created 1M single-locus neutral simulations according to experimental
data's initial frequency and coverage. By setting FDR cutoff to
$0.05$, only 18 and 16 variants show significant signal for
directional and dominant selection,
respectively~(\ref{fig:man-dmel-snp}).  Selected variants for
directional selection are clustered in two regions, which match $2$ of
the $5$ regions (regions C and E in Fig. 2-a
in~\cite{burke2014standing}) identified by Burke~\emph{et al.} in
their preliminary analysis.

\begin{figure*}
	\centering
	\begin{tabular}{c}
		(A)\\
		\includegraphics[trim=0.4in 0.in 0.6in
		0in,clip,width=0.9\textwidth]{man-dmel-region.pdf}\\
		(B)\\
		\includegraphics[trim=0.3in 0.in 0.6in
		.0in,clip,width=0.9\textwidth]{{topVariants.dmel.dir}.pdf}
	\end{tabular}
	\caption{{\bf Scan of \comale\ statistic on \datadm.}
		(A)         Manhattan plot of scan for $\Hc^*$ statistic using sliding
		window of
		size $L=3000$ over the
		genome.  The dashed line represents cutoff for genome-wide
		FDR$\le0.05$, and identifies 5 contiguous intervals, I1-I5,
		which are shaded in blue. (B) Trajectories of the selected
		variants within
		intervals I1-I5.}
	\label{fig:man-dmel-region}
\end{figure*}

\begin{figure*}
	\centering
	\begin{tabular}{cc}
		\includegraphics[trim=0.4in 0.in 0.6in
		0.0in,clip,width=0.65\textwidth]{man-yeast-snp.pdf}&
		\raisebox{0.2in}{
			\includegraphics[trim=0in 0.in 0in
			0.0in,clip,width=0.35\textwidth]{{topVariants.yeast}.pdf}}
	\end{tabular}
	\caption{{\bf Single locus analysis of the yeast outcrossing
			populations.}\\ Manhattan plot
		of scan single locus \comale\ statistic ($L=1$) for testing directional
		selection (A) and dominant
		selection
		(C).
		The dashed line represents cutoff for  genome-wide FDR$\le0.05$.
		Trajectories of the selected variants are depicted in panels (B) and
		(D).}
	\label{fig:man-yeast-snp}
\end{figure*}