\documentclass[11pt,english,BCOR10mm,DIV12,bibliography=totoc,parskip=false,smallheadings
    headexclude,footexclude,oneside,dvips,UKenglish]{pst-doc}
\usepackage[T1]{fontenc}
%\usepackage{lmodern}
  \usepackage[tt=false]{libertine} %override beramono (doesn't look like tt font)
  \usepackage{libertinust1math}
  %\usepackage[scaled=0.83]{luximono} %override beramono (doesn't look like tt font)
\usepackage{attachfile2}
\attachfilesetup{date={},color=1 0 0}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{pst-3dplot}
\usepackage{pst-plot}
\usepackage{pstricks-add}
\usepackage{pst-ode}
\usepackage[ocgcolorlinks]{ocgx2}
\let\pstFV\fileversion
\let\belowcaptionskip\abovecaptionskip

\makeatletter
\renewcommand*\l@subsection{\bprot@dottedtocline{2}{1.5em}{3.6em}}
\renewcommand*\l@subsubsection{\bprot@dottedtocline{3}{3.8em}{4.5em}}
\makeatother

\def\bgImage{%
\pstVerb{
  /alpha 10 def
  /beta 28 def
  /gamma 8 3 div def
}%
\pstODEsolve[algebraic,dt0=0.05]{lorenzXYZ}{0 1 2}{0}{25}{2501}{10 10 30}{
  alpha*(x[1]-x[0]) |
  x[0]*(beta-x[2]) - x[1] |
  x[0]*x[1] - gamma*x[2]
}
\begin{pspicture}(-8,-4)(6,12)
\psset{unit=0.17cm,Alpha=160,Beta=15}
\listplotThreeD{lorenzXYZ}
\psset{unit=0.425cm,linestyle=dashed}
\pstThreeDNode(0,0,0){O}
\pstThreeDNode(0,0,5){Z}
\pstThreeDNode(5,0,0){X}
\pstThreeDNode(0,5,0){Y}
\pstThreeDNode(-10,-10,0){A}
\pstThreeDNode(-10,-10,20){B}
\pstThreeDNode(-10,10,20){C}
\pstThreeDNode(-10,10,0){D}
\pstThreeDNode(10,-10,0){E}
\pstThreeDNode(10,-10,20){F}
\pstThreeDNode(10,10,20){G}
\pstThreeDNode(10,10,0){H}
\pspolygon(A)(B)(C)(D)
\pspolygon(E)(F)(G)(H)
\psline(A)(E)
\psline(B)(F)
\psline(D)(H)
\psline(C)(G)
\psset{linestyle=solid,linecolor=red}
\psline{->}(O)(X)
\psline{->}(O)(Y)
\psline{->}(O)(Z)
\end{pspicture}
}
\lstset{explpreset={pos=l,width=-99pt,overhang=0pt,hsep=\columnsep,vsep=\bigskipamount,rframe={}},
    escapechar=?}
\def\textat{\char064}%
\let\verbI\texttt

\def\parsedate#1/#2/#3\relax{
  \def\year{#1}
  \def\month{#2}
  \def\day{#3}
}

\begin{document}
%\author{Alexander Grahn}
\author{Alexander Grahn}
\expandafter\parsedate\filedate\relax %set current date to package date
\title{pst-ode\\[4ex]}
\subtitle{A PSTricks package for solving initial value problems for sets of Ordinary Differential Equations (ODE),  v\pstFV\\[2ex]\url{https://github.com/agrahn/pst-ode}}
\maketitle

%\clearpage
\begin{abstract}
\noindent The \LPack{pstricks-add} package already provides \Lcs{psplotDiffEqn} for solving ODEs. However, as its name suggests, the macro always produces a plot of the computed result. While any number of coupled differential equations can be integrated simultaneously, only two-dimensional plots are supported. The user has to select the two components of the computed state vectors to be used in the plot.

Package \LPack{pst-ode} separates solving the equations from plotting the result. The result is stored as a \PS{} object and can be plotted later using macros from other PSTricks packages, such as \Lcs{listplot} (\LPack{pst-plot}) and \Lcs{listplotThreeD} (\LPack{pst-3dplot}), or be further processed by user-defined \PS{} procedures. Optionally, the computed state vectors can be written as a table to a text file.

Package \LPack{pst-ode} uses the Runge-Kutta-Fehlberg (RKF45) method with automatic step size control for integrating the differential equations. Thus, the precision of the result does not depend on the number of plot points specified, as it would be the case with the classical Runge-Kutta (RK4) method.
\end{abstract}

\tableofcontents

\section{Introduction}
An initial value problem involves finding the solution $\mathbf{x}(t)$ of a set of first order differential equations
\begin{equation}
    \frac{\mathrm{d}\mathbf{x}}{\mathrm{d}t}=\mathbf{f}(t,\mathbf{x})
\end{equation}
by integrating them with respect to the independent variable $t$ starting at $t_0$ up to $t_\mathrm{e}$. If the set consists of $n$ differential equations,
a vector of initial conditions
\begin{equation}
    \mathbf{x}(t_0)=\mathbf{x}_0
\end{equation}
of the same length $n$ is required. For $n=1$ the initial value problem is one-dimensional:
\begin{gather}
    \frac{\mathrm{d}x}{\mathrm{d}t}=f(t,x)\quad\text{for}\ t \in [t_0, t_\mathrm{e}]\text{, where}\label{eq:1dode}\\
    x(t_0) = x_0.\label{eq:1ini}
\end{gather}

Instead of producing analytical expressions of the solution functions $\mathbf{x}(t)$, the numerical method gives only approximate values $\mathbf{x}_i$ at $N$ discrete points $t_i$ of the integration interval $I=[t_0, t_\mathrm{e}]$:
\begin{equation}
\mathbf{x}_i\approx\mathbf{x}(t_i).
\end{equation}
The computed approximations $\mathbf{x}_i$ of the solution as well as the initial condition vector $\mathbf{x}_0$ are called `state vectors'. In the case of a single equation problem, Eqs.~\eqref{eq:1dode}, \eqref{eq:1ini}, the state vectors have only one component.

\section{Commands}
\begin{BDef}
    \Lcs{pstODEsolve}\OptArgs\Largb{result}\Largb{output format}\Largb{$t_0$}\Largb{$t_\mathrm{e}$}\Largb{$N$}\Largb{$\mathbf{x}_0$}\Largb{$\mathbf{f}(t,\mathbf{x})$}
\end{BDef}
is the main user command for solving initial value problems.

The first mandatory argument \Larg{result} is a simple identifier composed of letters and possibly numbers. It is the name of a \PS{} object that takes the computed state vectors $\mathbf{x}_i$, formatted according to the second argument \Larg{output format}, as a long list of values. \Larg{result} can be directly used as the \Larg{data} argument of \Lcs{listplot}\Largb{data} (package \LPack{pst-plot}) or \Lcs{listplotThreeD}\Largb{data} (package \LPack{pst-3dplot}). When put on the \PS{} operand stack, \Larg{result} is immediately executed, that is, the list of values contained in \Larg{result} is pushed onto the operand stack. The scope of \Larg{result} is global and thus its content survives page breaks.

The second argument \Larg{output format} determines which of the components of the state vectors $\mathbf{x}_i$ and possibly the independent variable $t$ are stored into \Larg{result}. \Larg{output format} can be specified in two different formats, depending on the setting of the command option \Lkeyword{algebraicOutputFormat}.
If \Lkeyword{algebraicOutputFormat} is set, calculations can be made on the components of the computed state vectors before writing them to \Larg{result}. Without option \Lkeyword{algebraicOutputFormat} the following applies: The keyword \Lkeyword{(t)} (parentheses required) inserts the integration parameter value $t_i$ into the result list; numbers (\Lkeyword{0}, \Lkeyword{1}, \Lkeyword{2}, \dots, $n-1$) in arbitrary order specify the components of vector $\mathbf{x}_i$ to be inserted, as well as their order of insertion. The elements of \Larg{output format} are to be separated by spaces. If option \Lkeyword{algebraicOutputFormat} is set, \Larg{output format} is a \Lkeyword{|}-separated list of algebraic expressions (infix notation) according to which the components of the output vector are to be calculated. In these algebraic expressions, the $n$ current state vector components can be referred to as \Lkeyword{x[0]}, \Lkeyword{x[1]}, \dots, \Lkeyword{x[}$n-1$\Lkeyword{]} or \Lkeyword{y[0]}, \Lkeyword{y[1]}, \dots, \Lkeyword{y[}$n-1$\Lkeyword{]}, and the current independent variable value as `\Lkeyword{t}'. In either case, there is no upper limit of the output vector length. It must have at least one element though.

Arguments $t_0$ and $t_\mathrm{e}$ define the interval of integration $I=[t_0, t_\mathrm{e}]$. Both arguments accept expressions in infix or \PS{} (postfix, reverse polish) notation. Infix notation requires option \Lkeyword{algebraicT}.

$N$ is the number of \emph{equally} spaced output points, including $t_0$ and $t_\mathrm{e}$; it must be $\ge 2$. In order to divide the interval of integration into $K$ output steps, $N$ must be set to $K+1$. Note that the precision of the solution does \emph{not} depend on $N$; internal integration steps are automatically inserted and resized according to the changes in the solution.

$\mathbf{x}_0$ is a list of $n$ space separated initial values, one for each differential equation. Alternatively, $\mathbf{x}_0$ can be given as a \PS{} procedure pushing the initial values on the stack, or as an algebraic expression in infix notation where the elements are separated by `\Lkeyword{|}'. Infix notation requires option \Lkeyword{algebraicIC}. This argument can be left empty. In that case, the last computed state vector of a preceding \Lcs{pstODEsolve} call. Of course, the number of equations $n$ must be the same as in the preceding calculation.

$\mathbf{f}(t,\mathbf{x})$ is the right-hand side of the differential equations. Equations can be entered in either infix or \PS{} (postfix, reverse polish) notation. Infix notation requires option \Lkeyword{algebraic}, and equations have to be separated by `\Lkeyword{|}'. The $n$ current state vector components can be referred to as \Lkeyword{x[0]}, \Lkeyword{x[1]}, \dots, \Lkeyword{x[}$n-1$\Lkeyword{]} or \Lkeyword{y[0]}, \Lkeyword{y[1]}, \dots, \Lkeyword{y[}$n-1$\Lkeyword{]}, and the current independent variable value as `\Lkeyword{t}'. If given in \PS{} notation, the provided procedure must first pop the current state vector components in reverse order(!) from the operand stack and then push the first derivatives in regular order back to it. Again, the independent variable value can be accessed using `\Lkeyword{t}'.%\\

\newpage
\noindent\Lcs{pstODEsolve} accepts a few \OptArgs:\\% \Lkeyword{dt0}, \Lkeyword{append}, \Lkeyword{saveData}, \Lkeyword{algebraicOutputFormat}, \Lkeyword{algebraicT}, \Lkeyword{algebraicIC}, \Lkeyword{algebraic}, \Lkeyword{algebraicAll}, \Lkeyword{silent} and \Lkeyword{varsteptol}.\\

\noindent\OptArg*{dt0=<number>}\\
\noindent By default, the output step $(t_\mathrm{e}-t_\mathrm{0})/(N-1)$ is used as the intitial, tentative integration step size. A large initial step may cause the integration to crash early by numerical overflow, in particular if the right-hand side evaluates to large values. With option \Lkeyword{dt0}, an arbitrary value of the initial step size can be specified.\\

\noindent\OptArg*{append}\\
If the initial condition argument $\mathbf{x}_0$ of \Lcs{pstODEsolve} is left empty, integration of an ODE continues from an already existing state, which was obtained by the most recent use of \Lcs{pstODEsolve} or which was re-instated from a previously saved state (\Lcs{pstODEsaveState}) by calling \Lcs{pstODErestoreState}. Keyword \Lkeyword{append} tells \Lcs{pstODEsolve} to append the computed result to \Larg{result} which must already exist.\\

\noindent\OptArg*{saveData}\\
If option \Lkeyword{saveData} is set, the formatted state vectors are written as a table to a textfile named `\Larg{result}\Lkeyword{.dat}'. Note that \Lkeyword{ps2pdf} must be called with option \Lkeyword{-dNOSAFER} to enable writing of external files.\\

\noindent\OptArg*{algebraicOutputFormat}\\
With \Lkeyword{algebraicOutputFormat}, the command argument \Larg{output format} is a \Lkeyword{|}-separated list of algebraic expressions in infix notation, according to which the output vector components are to be assembled before storing them into \Larg{result}. Default is to  \emph{not} use algebraic infix expressions. For details, see the description of \Larg{output format} above.\\

\noindent\OptArg*{algebraicT}\\
With \Lkeyword{algebraicT}, the integration interval limits $t_0$ and $t_\mathrm{e}$ can be entered as algebraic expressions in infix notation, otherwise \PS{} (postfix, reverse polish) notation must be used. Of course, single rational numbers for  $t_0$ and $t_\mathrm{e}$ always work.\\

\noindent\OptArg*{algebraicIC}\\
With \Lkeyword{algebraicIC}, the initial condition vector $\mathbf{x}_0$ can be given in algebraic infix notation. Vector components have to be separated by `\Lkeyword{|}'. Default is \PS{} notation, i.\,e. space separated postfix expressions or rational numbers.\\

\noindent\OptArg*{algebraic}\\
With \Lkeyword{algebraic}, the right-hand side of differential equations $\mathbf{f}(t,\mathbf{x})$ can be given in infix notation. Algebraic infix expressions are to be separated by `\Lkeyword{|}'. Default is \PS{} notation.\\

\noindent\OptArg*{algebraicAll}\\
Option \Lkeyword{algebraicAll} is equivalent to setting all of \Lkeyword{algebraicOutputFormat}, \Lkeyword{algebraicT}, \Lkeyword{algebraicIC}, \Lkeyword{algebraic}.\\

\noindent\OptArg*{silent}\\
Option \Lkeyword{silent} suppresses the terminal output of stepping information.\\

\noindent\OptArg*{varsteptol=<number>}\\
The tolerance for automatic calculation of the integration step size can be set with \Lkeyword{varsteptol}. The default value is \Lkeyword{1e-6}. Sometimes, it may be helpful to relax this value in order to cope with situations where integration stops with step size underflow. The occurence of step size underflow is indicated by writing `\Lkeyword{!}' to the terminal and integration stops prematurely before reaching $t_\mathrm{e}$. The current value of $t$ and the current state vector $\mathbf{x}$ are written to the terminal. Step size underflow may happen for stiff ODEs at some point along the integration interval $[t_0, t_\mathrm{e}]$.\\[1ex]

\begin{BDef}
\Lcs{pstODEsaveState}\Largb{state}
\end{BDef}
is a user command to save the state of an integration at the end of a \Lcs{pstODEsolve} call. The saved state can be restored later, using \Lcs{pstODErestoreState}\Largb{state}, in order to continue the integration of an ODE. \Larg{state} is an identifier composed of letters and possibly numbers.\\[1ex]

\begin{BDef}
\Lcs{pstODErestoreState}\Largb{state}
\end{BDef}
is a user command to restore a previously saved state (\Lcs{pstODEsaveState}\Largb{state}). After restoring a state, \Lcs{pstODEsolve} can be called with an empty initial condition argument in order to continue integration of the ODE. Of course, the number of differential equations of the current and of the saved \Lcs{pstODEsolve} calls must be the same.

\section{Examples}
Complete and compilable example files are located in the \Verb+{TEXMFDIST}/doc/generic/pst-ode/examples+ directory.

\subsection[Lorenz Attractor]{Lorenz Attractor \textattachfile{examples/lorenz.tex}{($\nearrow$lorenz.tex)}}
The Lorenz Attractor depicted on the title page is governed by
\begin{align*}
  \frac{\mathrm{d}x}{\mathrm{d}t}& = \alpha (y-x)\\
  \frac{\mathrm{d}y}{\mathrm{d}t}& = x(\beta-z)-y\\
  \frac{\mathrm{d}z}{\mathrm{d}t}& = x y - \gamma z.
\end{align*}
This system of differential equations is known to display chaotic behaviour due to the non-linear combination (products) of the dependent functions $x(t)$, $y(t)$ and $z(t)$. The trajectory of solution is susceptible to slight changes in the initial conditions and hence to slight discrepancies in the computed intermediate state vectors, which in turn can be regarded as initial conditions for the continuation of the solution. This is known as the `butterfly effect', a term coined by Lorenz. Although an adaptive stepping algorithm is used, the solution of this initial problem \emph{does} therefore depend on the number of output points chosen. To some extent, this fact contrasts with the statement made in the abstract of this documentation. However, for linear problems which only know one distinct solution it still holds. In the present case, the values $\alpha=10$, $\beta=28$, $\gamma=8/3$ and the initial condition $\mathbf{x}_0=(10,10,30)$ where chosen. The integration parameter $t$ is running from  $0$ to $25$ and the state vector is output at $2501$ points of the integration interval.

\begin{verbatim}
\pstVerb{
  /alpha 10 def
  /beta 28 def
  /gamma 8 3 div def
}
\pstODEsolve[algebraic]{lorenzXYZ}{0 1 2}{0}{25}{2501}{10 10 30}{
  alpha*(x[1]-x[0]) |
  x[0]*(beta-x[2]) - x[1] |
  x[0]*x[1] - gamma*x[2]
}
\listplotThreeD{lorenzXYZ}
\end{verbatim}
As the plot is three-dimensional, all three components of the state vectors are stored in the \PS{} variable \Lkeyword{lorenzXYZ} by setting the \Larg{output format} argument to `\Lkeyword{0 1 2}'.

\subsection[Charged particle movement in a vertical electrical field]{Charged particle movement in a vertical electrical field \textattachfile{examples/particle.tex}{($\nearrow$particle.tex)}}
The trajectory $\mathbf{x}(t)$ of the particle shown below is governed by a set of three second order differential equations:
\begin{subequations}
\begin{align}
\ddot{x} &= \omega\dot{y}-\dfrac{\dot{x}}{\tau}\\
\ddot{y} &= -\omega\dot{x}-\dfrac{\dot{y}}{\tau}\\
\ddot{z} &= -\dfrac{\dot{z}}{\tau},
\end{align}
\end{subequations}
where $\omega$ and $\tau$ are constants. An initial value problem of this type needs $3\times2=6$ initial conditions. These are given as the initial position $\mathbf{x}_0=(x_0, y_0, z_0)$ and the initial velocity $\dot{\mathbf{x}}_0=(\dot{x}_0, \dot{y}_0, \dot{z}_0)=(u_0, v_0, w_0) = \mathbf{v}_0$ of the particle.

In order to solve the equations above numerically, they have to be rewritten as a set of six first order differential equations:
\begin{subequations}
\begin{align}
\dot{x} &= u\\
\dot{y} &= v\\
\dot{z} &= w\\
\dot{u} &= \omega v-\frac{u}{\tau}\\
\dot{v} &= -\omega u-\dfrac{v}{\tau}\\
\dot{w} &= -\dfrac{w}{\tau}.
\end{align}
\end{subequations}

Here, $\omega$ and $\tau$ are both set to the value of $5$, the initial position of the particle is defined as $\mathbf{x}_0=(0, 0, 0)$ and its initial velocity vector as $\mathbf{v}_0=(20, 0, 2)$.  The integration parameter $t$ is running from  $0$ to $25$ and the state vector is output at $1000$ points of the integration interval.
\begin{verbatim}
\pstVerb{
  /wc 5 def
  /tau 5 def
}
\pstODEsolve[algebraic]{particleXYZ}{0 1 2}{0}{25}{1000}{0 0 0 20 0 2}{
  x[3] | x[4] | x[5] | wc*x[4] - x[3]/tau | -wc*x[3] - x[4]/tau | -x[5]/tau
}
\listplotThreeD{particleXYZ}
\end{verbatim}
Since we are interested in plotting the particle positions, only the first three components of the state vectors are stored in \Lkeyword{particleXYZ}.
\begin{center}
\psset{unit=0.75cm,Alpha=40,Beta=20}
\begin{pspicture}(-10,-2)(6,13)
\newpsstyle{vecteurA}{arrowinset=0.1,arrowsize=0.15,linecolor={[rgb]{0 0.5 1}}}
\pstVerb{
  /wc 5 def
  /tau 5 def
  /vx 20 def
  /vz 2 def
}
\pstODEsolve[algebraic]{particleXYZ}{0 1 2}{0}{25}{1000}{0 0 0 vx 0 vz}{
  y[3] | y[4] | y[5] | wc*y[4] - y[3]/tau | -wc*y[3] - y[4]/tau | -y[5]/tau
}
\listplotThreeD{particleXYZ}
\pstThreeDNode(0,0,0){O}
\pstThreeDNode(0,0,1){Z}
\pstThreeDNode(1,0,0){X}
\pstThreeDNode(0,1,0){Y}
\pstThreeDNode(-5,-9,0){A}
\pstThreeDNode(-5,-9,10){B}
\pstThreeDNode(-5,2,10){C}
\pstThreeDNode(-5,2,0){D}
\pstThreeDNode(5,-9,0){E}
\pstThreeDNode(5,-9,10){F}
\pstThreeDNode(5,2,10){G}
\pstThreeDNode(5,2,0){H}
\pstThreeDNode(0,0,0){M0}
\pstThreeDNode(vx 5 div,0,vz 5 div){V}
\pstThreeDNode(vx 5 div,0,0){Vx}
{\psset{linestyle=dashed}
\pspolygon(A)(B)(C)(D)
\pspolygon(E)(F)(G)(H)
\psline(A)(E)
\psline(B)(F)
\psline(D)(H)
\psline(C)(G)}%
\psline[linecolor=red]{->}(M0)(V)
\psline[linecolor=cyan]{->}(M0)(Vx)
\uput{0.1}[l](V){\red$\overrightarrow{v}_0$}
{\psset{linestyle=solid,linecolor=red}
\psline[style=vecteurA]{->}(O)(X)
\psline[style=vecteurA]{->}(O)(Y)
\psline[style=vecteurA]{->}(O)(Z)}%
\uput[u](Z){$z$}
\uput[dl](X){$x$}
\uput[r](Y){$y$}
\end{pspicture}
\end{center}

\subsection[One more first order differential equation]{One more first order differential equation \textattachfile{examples/ode.tex}{($\nearrow$ode.tex)}}
The aim of the last example is to demonstrate that precision does not depend on the number of output points. We set only five output points and plot the analytical solution against the numerical one for comparison.

The ODE to be solved reads
\begin{equation}
  y'=-2y t.\label{eq:ode}
\end{equation}
It should be noted that the right-hand side also depends the integration parameter $t$. % as well as in the output format description, since the solution $y$ shall be plotted against $t$.
With the initial condition
\begin{equation}
  y(-1)=1/e\label{eq:initcond}
\end{equation}
the analytical solution of Eq.~\eqref{eq:ode} is
\begin{equation}
y(t)=e^{-t^2}.
\end{equation}
\begin{verbatim}
\pstODEsolve[algebraicIC,algebraic]{TY}{(t) 0}{-1}{3}{5}{1/Euler}{-2*t*y[0]}
\listplot[plotstyle=dots]{TY}
\end{verbatim}
Note that in \Lcs{pstODEsolve}, `\Lkeyword{x[..]}' and `\Lkeyword{y[..]}' can be used interchangeably for representing the state vector in algebraic notation. The initial condition~\eqref{eq:initcond} is given as an algebraic expression, which requires option \Lkeyword{algebraicIC}; in \PS{} notation it would read `\Lkeyword{1 Euler div}'. The integration parameter and the one available state vector component are stored into the \PS{} object `\Lkeyword{TY}' by setting \Larg{output format} to `\Lkeyword{(t) 0}'.
\begin{center}
\psset{unit=3cm}
\begin{pspicture}(-0.3,-0.4)(.2,1)%\psgrid
  \psset{xAxisLabel=$t$,xAxisLabelPos={c,-6ex},yAxisLabelPos={-3ex,c}}
  \begin{psgraph}[axesstyle=frame,Ox=-1,](0,0)(0,0)(4,1){10cm}{2.5cm}
  \rput(1,0){\psplot[algebraic]{-1}{3}{Euler^(-x^2)}}
  \pstODEsolve[algebraicIC,algebraic]{TY}{(t) 0}{-1}{3}{5}{1/Euler}{-2*t*y[0]}
  \rput(1,0){\listplot[plotstyle=dots,dotsize=0.05,linecolor=red]{TY}}
  \end{psgraph}
\end{pspicture}
\end{center}
The plot contains the analytical solution and the five output points of the numerical solution as red dots. They lie exactly on the analytic solution.

\section{Acknowledgements}
I'd like to thank Manuel Luque for the inspiring examples on his site \url{http://pstricks.blogspot.fr}, some of which I used as a basis for this documentation.

\section{License}
This package can be redistributed and/or modified under the terms
of the \LaTeX Project Public License Distributed from CTAN archives:
\url{http://mirrors.ctan.org/tex-archive/macros/latex/base/lppl.txt}

\end{document}


\chapter{Exact intensity for the two-faceted cup}\label{app:boundariescup}
For very simple optical systems, the \textit{exact} target intensity of light can be calculated. Here we explain how this is done for the two-faceted cup with a Lambertian source described in Chapter \ref{chap:raytracing}. We remind the reader that, for this system, the intensity in a given direction $\variabile{p}$ in PS is defined as:
\begin{equation}\label{eq:eta_appendix}
I_{\textrm{PS}}(\variabile{p}) = \sum_{\Pi}\int_{\variabile{q}^\textrm{\,min}(\Pi, \variabile{p})}^{\variabile{q}^\textrm{\,max}(\Pi,\variabile{p})}L(\variabile{q}, \variabile{p})\textrm{d}\variabile{q} = \sum_{\Pi}\big (\variabile{q}^\textrm{max}(\Pi,\variabile{p})-\variabile{q}^\textrm{\,min}(\Pi,\variabile{p})\big )\,,
\end{equation}
where the sum is over all the possible paths, $\variabile{q}^\textrm{\,min}(\Pi,\variabile{p})$ and $\variabile{q}^\textrm{\,max}(\Pi,\variabile{p})$ are of the intersection points between the line $\variabile{p}=\textrm{const}$ and $\partial$\insieme{R}$_\textrm{t}(\Pi)$, and the second equation holds as we assume $L=1$ in \insieme{R}$_\textrm{t}(\Pi)$.
Therefore, if we are able to provide an analytic expression for the boundaries $\partial$\insieme{R}$_\textrm{t}(\Pi)$ we can calculated the position coordinates $\variabile{q}^\textrm{\,min}(\Pi,\variabile{p})$ and $\variabile{q}^\textrm{\,max}(\Pi,\variabile{p})$ analytically and we can compute the exact intensity for every direction $\variabile{p}$ is obtained using (\ref{eq:eta_appendix}). The procedure used for such purpose is explained next.
\section{Analytic approach}
The idea is to rotate the cup to determine the maximum number of reflections between a ray and the optical lines before reaching the target. The rays are considered to be straight lines instead of broken lines. Hence it is sufficient to find only one intersection point between the ray and a line segment (also in the case where more than one reflection occurs). Finally transforming (rotating or reflecting) back these points we obtain the corresponding coordinates at the target.\\ \indent
The two-faceted cup is defined in the $(\variabile{x}, \variabile{z})$-plane as in Chapter \ref{chap:raytracing}.
Let $\gamma\in(0, \pi/2)$ be the angle that the left and right reflector make with the normal to the source.
%\begin{figure}[t]
%\label{fig:cup}
%  \begin{center}
%%\vspace{-1.5cm}
%  \includegraphics[width=6.7cm]{cup.pdf}
%  \end{center}
%%\vspace{-2cm}
%  \caption{\textbf{Shape of the two-faceted cup.}  Each line of the system is labeled with a number.
%   The source \point{S}$= [-2,2]$ (line number $1$) is located on the $\variabile{x}$-axis.
%   The target \point{T}$= [-17, 17]$ (line $4$) is parallel to the source and is located at a height $\variabile{z}= 40$.
%   The left and right reflectors (line $2$ and $3$) connect the source with the target.}
%  \label{fig:cup}
%\end{figure}
The maximum $\variabile{z}$-coordinate that the two-faceted cup can reach during the rotation is defined by the $\variabile{z}$-coordinate of the point $\point{P}=(0,Z)$:
\begin{equation}\label{rotation}\begin{tabular}{llll}
$Z$ & $=$ & $ \big(h+\frac{\variabile{a}}{\tan\gamma}\big)\frac{1}{\cos\gamma}-\frac{\variabile{a}}{\tan\gamma}$ \\ $ \quad$ & $ \quad $ & $ \quad $ \\$ \quad$ &  $=$ & $\frac{h}{\cos\gamma}+\frac{\variabile{a}(1-\cos\gamma)}{\sin\gamma},$\end{tabular}
\end{equation} and $\point{R}=(0,-\frac{\variabile{a}}{\tan\gamma})$ is the rotation point. We define $\point{B}_k$ as the clockwise ($k<0$) or counterclockwise ($k\geq 0$) rotation image of $\point{P}$ around the point $\point{R}$ over an angle $\alpha_k=(2k+1)\gamma$, with $k$ an integer number (Figure \ref{fig:twofaced} is illustrative).
\begin{figure}[t]%\label{fig:twofaced}
 \centering
  \includegraphics[width=\textwidth]{rotated_cup.pdf}
 \caption{\textbf{The two-faceted cup rotated twice on both sides.} The line segment with end points $B_{k-1}$ and $B_{k}$ is the $|k|$ times rotated target. The coordinates $(q,h)$ on the target $B_{-1}B_{0}$ are obtained by transforming the coordinates $(u,v)$ of the intersection point between a ray and the segment $B_0B_1$ . The point $\point{R} = \big(0,-\frac{a}{\tan{\gamma}}\big)$ is the center of the circle described by rotating the cup (dashed line).}
  \label{fig:twofaced}
  \end{figure}
  %as the notation used in equation ($\ref{Bk}$) could suggest.
The position coordinates of points $\point{B}_k = (B_{k,x}, B_{k,z})$ are given by:
\begin{equation}
 \begin{pmatrix} B_{k,x}  \\  B_{k,z}\end{pmatrix}= -
  \begin{pmatrix} 0  \\  \frac{a}{\tan\gamma}\end{pmatrix}+
 \left(\begin{split}  & \cos\alpha_k  & -\sin\alpha_k \\  & \sin\alpha_k & \cos\alpha_k\end{split}\right).
 \begin{pmatrix}  0 \\  Z+\frac{a}{\tan\gamma}\end{pmatrix},
\end{equation}
The maximum number of reflections $r_{\textrm{max}}$ a ray can undergo before arriving at the target is:
\begin{equation}
r_{\textrm{max}}=\max\{k\in\mathbb{N} \;| \; B_{k-1,z}\geq 0\}.
\end{equation}
For example, for the two-faceted cup depicted in Figure \ref{fig:cup}, we found $r_{\textrm{max}}=2$.\\ \indent
Given the coordinates $(\variabile{x}_1, \variabile{z}_1)$ and the angular coordinate $\optangle_1$ of a ray at the source, we can calculate the corresponding position $(\variabile{x}, \variabile{z})$ and direction coordinate $\optangle$ at the target as explained in the following. \\ \indent We compute the coordinates $(u,v)$ of the intersection point between the ray parametrization and the $|\variabile{k}|$ times rotated or reflected target $\point{B}_{\variabile{k}-1}\point{B}_\variabile{k}$ for which the intersection with the forward ray is not empty, for $\variabile{k}=-\variabile{r}_{\textrm{max}}-1, \cdots, \variabile{r}_{\textrm{max}}$. Next, if $\variabile{k}$ is even, the corresponding coordinates $(\variabile{x},\variabile{z})$ at the target are found by rotating back the coordinates $(\variabile{u},\variabile{v})$, otherwise a reflection is applied. Therefore, the ray coordinates $(\variabile{x},\variabile{z})$ at the target are given by:
\begin{equation} \label{rotation_target}\begin{pmatrix} \variabile{x}\\ \variabile{z}
\end{pmatrix} = \left(\begin{array}{cc}(-1)^k & 0  \\ 0 & 1\end{array}\right)
\left(\begin{array}{cc}\cos(-2\variabile{k}\gamma) & -\sin(-2\variabile{k}\gamma) \\\sin(-2\variabile{k}\gamma) & \cos(-2\variabile{k}\gamma)\end{array}\right)\begin{pmatrix} \variabile{u} \\
 \variabile{v}+\frac{a}{\tan(\gamma)}\end{pmatrix}-\begin{pmatrix}0 \\ \frac{a}{\tan\gamma}\end{pmatrix}.
\end{equation} We observe that the sign in the first matrix depends on the parity of $\variabile{k}$. When $\variabile{k}=0$, i.e., the ray does not reflect, the first matrices become the identity matrix and the cup is not rotated nor reflected. When $\variabile{k}$ is even, the determinant of the matrix given by the product between the first and the second matrix (\ref{rotation_target}) is equal to $1$ and we obtained a rotation matrix, while when $\variabile{k}$ is odd the determinant of the product matrix is $-1$ and we have a reflection matrix.
\\ \indent
The method of transforming the cup instead of the rays allows us to determine the positive luminance regions $\mbox{\insieme{R}}_1(\Pi_{\variabile{j}})$ and $\mbox{\insieme{R}}(\Pi_{\variabile{j}})$ in source and target PS, where every path $(\Pi_{\variabile{j}})_{\variabile{j}=1, \cdots, 2\variabile{r}_{\textrm{max}}+1}$ corresponds to $|\variabile{k}|$ reflections. The corresponding boundaries only consist of rays that either leave the extremes of the source or hit one of the points $\point{B}_\variabile{k}$.
%At the boundaries a small change in the position or direction ray coordinate can cause a difference in the number of the reflections.

Rays that leave the interior of \point{S} and hit $\point{B}_\variabile{k}$ have as position coordinates in source PS $\variabile{q}_1 = \variabile{x}_1\in(-\variabile{a}, \variabile{a})$, the corresponding target PS coordinates are $\variabile{q} = \variabile{x} = B_{\variabile{k}, \variabile{x}}$.
The direction coordinates of these rays at the source PS are $\variabile{p}_1 = \sin(\optangle_1)$ where $\optangle_1$ is given by:
\begin{equation}\label{anglesource}
\optangle_1 = \arctan\bigg(\frac{\variabile{x}_1-B_{k,x}}{B_{k,z}}\bigg).
\end{equation}
The corresponding direction coordinates at the target PS are $\variabile{p}=\sin(\optangle)$ where $\optangle$ is given by:
\begin{equation}\label{teta}
\optangle=(-1)^\variabile{k}(\optangle_1-2\variabile{k}\gamma).
\end{equation}

Rays emitted from the end points of the source have a constant position coordinate $\variabile{q}_1 = \variabile{x}_1 = \textrm{const}$ in source PS and varying a direction coordinate $\variabile{p}_1 = \sin(\optangle_1)\in[-1, 1]$ where $\optangle_1\in[-\pi/2, \pi/2]$. The corresponding target position coordinate $\variabile{x}$ is obtained from (\ref{rotation_target}) while the direction coordinate in the target PS is $\variabile{p} = \sin(\optangle)$, where $\optangle$ is given by Equation (\ref{teta}).
Note that the rays emitted from the end points of the source form vertical lines in source PS as $\variabile{q}_1= \textrm{const}$ and $\variabile{p}_1\in[-1,1]$ varies.
On the other hand, rays that hit points $\point{B}_k$ form vertical lines in target PS as $\variabile{q} = \textrm{const}$.
\\ \indent
%In Figure \ref{fig:raggi} are shown some rays that compose the boundaries of $M_{\textrm{s},k}$ which coordinates are:
%$$ \begin{array}{cc}ADE = \Bigg(-a, \arctan\Big(\frac{-a+b_{-1,x}}{b_{-1,z}}\Big)\Bigg),\; ACE = \big(-a, \sin(\gamma)\big),\; AF = \big(-a, -\sin(\delta)\big), \\
% BCF = \Bigg(a, \arctan\Big(\frac{a-b_{1,x}}{b_{1,z}}\Big)\Bigg), BDF = \big(a, - \sin(\gamma)\big) \, \;\mbox{and} \,\; BE = \big(a, \sin(\delta)\big).\end{array} $$
%\begin{figure}
%\includegraphics[scale=0.55]{raggi6.jpg}
%\caption{\footnotesize{Rays that leave the corner points of the source. The rays $AF$, $BE$, $ACE$, $BDF$ are rays that do not hit the reflectors of the system.
%They constitute rays on the boundaries of the regions $M_{\textrm{s},0}$, $M_{\textrm{s},1}$ and $M_{\textrm{s},-1}$.
% The rays $ADE$ and $BCF$ are rays that hit once the reflectors of the system. They constitute rays on the boundaries of the regions
% $M_{\textrm{s},-1}$, $M_{\textrm{s},-2}$, and $M_{\textrm{s},1}$ or $M_{\textrm{s},2}$, respectively.}}
%\label{fig:raggi}
%
%\end{figure}
%$$ \begin{array}{cc}ADE = \big(-b, -(t_1+2\gamma)\big)),\; ACE = \big(-b, \sin(\gamma)\big),\; AF = \big(-b, -\sin(\delta)\big), \\
% BCF = \big(b, -(t_2-2\gamma)\big), BDF = \big(b, - \sin(\gamma)\big) \, \;\mbox{and} \,\; BE = \big(b, \sin(\delta)\big).\end{array} $$
% where $t_1 = \arctan(\frac(-a+b_{-1,x}{b_{-1}}))$ and $t_2 = \arctan(\frac(a-b_{-1,x}{b_{-1}}))$.
The boundaries at the source and target PS are shown in red in Figures \ref{fig:boundary} and \ref{boundaries_target}, respectively.
\begin{figure}[htbp]
\centering
%\begin{minipage}[t]{.40\textwidth}
\includegraphics[width = 0.8 \textwidth]{analytic_boundaries_source}
\caption{Regions in source PS formed by rays that reflect $|k|$ times, for the two-faceted cup in Figure \ref{fig:cup}.}
\label{fig:boundary}
%\end{minipage} \qquad \qquad
%\begin{minipage}[t]{.40\textwidth}
\end{figure}
\begin{figure}[htbp]
\centering
%\begin{minipage}[t]{.40\textwidth}
\includegraphics[width = 0.8 \textwidth]{analytic_boundaries_target}
\caption{Regions in target PS formed by rays that reflect $|k|$ times, for the two-faceted cup in Figure \ref{fig:cup}.}
\label{boundaries_target}
%\end{minipage} \qquad \qquad \qquad
\end{figure}
%\noindent
%Figure \ref{fig:boundary} and \ref{boundaries_target} show also the symmetry of the regions $M_{\textrm{s},k}$ and $M_{\textrm{t},k}$.
%Finally we note that, since $k = 1$ is odd, the position of the regions $M_{\textrm{t},1}$ and $ M_{\textrm{t},-1}$ are exchanged with respect to the position of $ M_{\textrm{s},1}$ and $ M_{\textrm{s},-1}$.
Once the boundaries at the target are determined, the coordinates of the intersection points between line $\variabile{p}=\textrm{const}$ and $\partial$\insieme{R}$(\Pi_{\variabile{j}})$ are found for every path $(\Pi_\variabile{j})_{\variabile{j}=1, \cdots, 2\variabile{r}_{\textrm{max}}+1}$ along every direction $\variabile{p}$. The target intensity is computed using Equation (\ref{eq:eta_appendix}). The intensity profile is depicted in Figure \ref{fig:intensity_cup_analytic}.
\begin{figure}[t]
\centering
%\begin{minipage}[t]{.40\textwidth}
\includegraphics[width = 0.7\textwidth]{Exact_intensity}
\caption{Profile of the exact intensity at the target of the two-faceted cup.}
\label{fig:intensity_cup_analytic}
%\end{minipage} \qquad \qquad \qquad
\end{figure}
Since the boundaries are computed analytically, the intensity $I(\variabile{p})$ found is the exact intensity.

The exact intensity found as described above was taken as reference intensity in Chapters \ref{chap:triangulation} and \ref{chap:raymapping1}.


\documentclass{article}
\usepackage{graphicx}
\usepackage{titletoc}
\usepackage{titlesec}
\usepackage{geometry}
\usepackage{fontspec, xunicode, xltxtra}
\usepackage{float}
\usepackage{cite}
\usepackage{amsmath}
\usepackage{listings}
\usepackage{titletoc}
\usepackage{bm}

\geometry{left=3cm,right=3cm,top=3cm,bottom=3cm}
\DeclareMathOperator*{\argmin}{argmin}
\DeclareMathOperator*{\argmax}{argmax}
\DeclareMathOperator*{\var}{var}
\DeclareMathOperator*{\expec}{E}

\begin{document}
\title{\textsf{Homework 6 for Pattern Recognition}}
\author{Fan JIN\quad (2015011506)}
\maketitle

\section*{Question 1.1}
{
    Note that
    $$\varepsilon_B(x) = h_B(x) - y(x) = \left[ \frac{1}{m} \sum_{i=1}^{m} {h_i(x)} \right] - y(x)$$
    $$= \frac{1}{m} \sum_{i=1}^{m} {[h_i(x) - y(x)]} = \frac{1}{m} \sum_{i=1}^{m} {\varepsilon_i(x)}.$$
    It follows that
    $$E_{h_B} = \frac{1}{n} \sum_{j=1}^{n}{[\varepsilon_B (x_j)]^2} = \frac{1}{m^2 n} \sum_{j=1}^{n}{ \left[ \sum_{i=1}^{m}{\varepsilon_i(x_j)} \right]^2 }$$
    $$= \frac{1}{m^2 n} \sum_{j=1}^{n}{ \left[ \sum_{i=1}^{m}{(\varepsilon_i(x_j))^2} + 2 \sum_{i=1}^{m}{ \sum_{k=1, k\neq i}^{m}{\varepsilon_i(x_j) \varepsilon_k(x_j)}} \right] }$$
    $$= \frac{1}{m^2 n} \left[ \sum_{i=1}^{m}\sum_{j=1}^{n}{(\varepsilon_i(x_j))^2} + 2 \sum_{i=1}^{m}{ \sum_{k=1, k\neq i}^{m} \sum_{j=1}^{n} {\varepsilon_i(x_j) \varepsilon_k(x_j)}} \right]$$
    $$= \frac{1}{m^2 n} \left[ \sum_{i=1}^{m}\sum_{j=1}^{n}{(\varepsilon_i(x_j))^2} + 2 \sum_{i=1}^{m}{ \sum_{k=1, k\neq i}^{m} 0 } \right]$$
    $$= \frac{1}{m^2 n} \left[ \sum_{i=1}^{m}\sum_{j=1}^{n}{(\varepsilon_i(x_j))^2} \right]$$
    $$= \frac{1}{m} \frac{1}{m} \sum_{i=1}^{m} \left[ \frac{1}{n}\sum_{j=1}^{n}{(\varepsilon_i(x_j))^2} \right] = \frac{1}{m} E_h.$$
}

\section*{Question 1.2}
{
    By Cauchy Inequality, we have
    $$\left[ \sum_{i=1}^{m}{(\varepsilon_i(x_j) \cdot 1)} \right]^2 \leq \left[ \sum_{i=1}^{m}{(\varepsilon_i(x_j))^2} \right] \cdot \left[ \sum_{i=1}^{m}{1^2} \right] = m \sum_{i=1}^{m}{(\varepsilon_i(x_j))^2}.$$
    It follows that
    $$E_{h_B} = \frac{1}{n} \sum_{j=1}^{n}{[\varepsilon_B (x_j)]^2} = \frac{1}{m^2 n} \sum_{j=1}^{n}{ \left[ \sum_{i=1}^{m}{\varepsilon_i(x_j)} \right]^2 }$$
    $$\leq \frac{1}{m^2 n} \sum_{j=1}^{n}{ \left[ m \sum_{i=1}^{m}{(\varepsilon_i(x_j))^2} \right] }$$
    $$= \frac{1}{m n} \sum_{j=1}^{n}{ \left[ \sum_{i=1}^{m}{(\varepsilon_i(x_j))^2} \right] }$$
    $$= \frac{1}{m} \sum_{i=1}^{m} \left[ \frac{1}{n}\sum_{j=1}^{n}{(\varepsilon_i(x_j))^2} \right] = E_h.$$
}

\section*{Question 2.1}
{
    \textbf{Lemma:}\quad With all weights $w_i$, $d$ and $j$ fixed, there exists $k$ such that the following quantity
    $$\sum_{i=1}^{n}{w_i 1\{ h_{a,d,j}(x_i) \neq y_i \}},$$ as a function of $a$,
    is minimized at $a = x_{k,j}$, where $x_{k,j}$ is the $j$-th feature of the $k$-th sample.

    \textbf{Proof:}\quad This quantity, with all weights $w_i$, $d$ and $j$ fixed, is a linear combination of many sign functions $$1\{ h_{a,d,j}(x_i) \neq y_i \} $$ with respect to $a$. Therefore, it is a staircase function, which can be minimized at one of those steps. By definition, the threshold for $1\{ h_{a,d,j}(x_i) \neq y_i \} $ is $a = x_{k,j}$, and the lemma is thus proved.

    With this lemma, we only need to find the optimal $a$, $d$, $j$ from a finite set, i.e., to find $k$, $d$ and $j$ such that
    $$a = x_{k,j} ,$$
    $$d = 1 \mathrm{\quad or\quad } d = -1 ,$$
    $$1 \leq k \leq n ,$$
    $$1 \leq j \leq p.$$
    The size of this finite set is merely $2np$.

    \textbf{Note:}\quad For this dataset, the images are nearly binary: the gray-scale values are very close to either 0 or 1. In such cases, we can speed up calculations by neglecting the repeating values in $X$, i.e., doing a ``unique'' operation.

    \begin{table}[!hbp]
        \centering
        \begin{tabular}{|c|c|c|}
        \hline
        Iterations & Training error & Testing error \\
        \hline
        30.0000  &  0.0180  &  0.0753 \\
        \hline
        100.0000    &     0  &  0.0653 \\
        \hline
        200.0000   &      0  &  0.0598 \\
        \hline
        \end{tabular}
        \caption{Error rates through training}
    \end{table}

    \begin{figure}[H]
        \centering
        \includegraphics[width = 1\linewidth]{stump-AdaBoost/error.png}
        \caption{Error rates through training}
    \end{figure}
}

\section*{Questions 2.2 \& 2.3}
{
    Keep using 5-fold cross validation through training.

    \begin{table}[!hbp]
        \centering
        \begin{tabular}{|c|c|c|}
        \hline
        Model & Validation error & Testing error \\
        \hline
        Fine Tree  &  0.122000  &  0.084380 \\
        \hline
        Medium Tree  &   0.126000  & 0.084380 \\
        \hline
        Coarse Tree   &  0.124000  &  0.098443 \\
        \hline
        Bagged Trees 30   &    0.044000 &  0.047715 \\
        \hline
        Bagged Trees 100   &  0.038000  &  0.037670 \\
        \hline
        Bagged Trees 300   &   0.042000  & 0.035660 \\
        \hline
        \end{tabular}
        \caption{Error rates of the 6 tree models}
    \end{table}

    All 6 models have been saved to ``models.mat'' automatically.

    For the 3 tree models, the FineTree (max division number = 4) and MediumTree (max division number = 20) give the best performance on both validation set and testing set, while the CoarseTree (max division number = 100) has much higher error rate, especially on the testing set.

    For the 3 bagged trees, it attains the lowest error rate when the number of classifiers, the hyperparamter, is tuned at 30.
}

\section*{Question 2.4}
{
    \textbf{Briefly speaking:}\quad
    ``Boosting'' and ``random forest'' are both useful workarounds to the problem that single decision trees are easily overfitting.

    \textbf{Detailed comparison:}
    \begin{itemize}
        \item Judging from the output, ensembled models like bagged trees models attain the lowest error rate (around 4\%), the AdaBoost the medium (around 6\%), and single tree models the highest (around 12\%). This means it is possible to improve the performance by ensembling multiple models. Ensembling contributes to better performance, makes the model robust against noise, and fits paralell computation as well.

        \item The idea of boosting is useful in that it assigns weights to different samples, and allows the classifier to concentrate on the samples in which it classifies wrong. It makes the training faster, and a bit more robust. The weights and the parameters are updated iteratively. Sometimes it also employs multiple trees and makes decision by taking a vote, as shown in AdaBoost.

        \item Hyperparamter tuning is cricial to our model. This not only applies in a single decision tree (where we can adjust the max division number), but it is also seen in bagged trees (where we can adjust the number of classifiers). More divisions and more sub-classifiers do not always bring better performance, as shown in Table 2.

        \item It is necessary to identify overfitting. From Figure 1, we see it starts to overfit after 60 iterations. It is better to stop at 60 iterations than to continue training.
    \end{itemize}
}

\section*{Source Code}
{
    Please download the souece code from http://39.106.23.58/files/PR6\_2015011506.7z

    For Question 2, please run ``main.m''. It may take \emph{less than a minute} to train the network, but the result is reproducible because of the random seed.

    For each model, I clicked ``Generate code'' button to transcript my operations into MATLAB codes, and stored each of them in the corresponding ``.m'' file. These files include:
    \begin{itemize}
        \item trainClassifierFineTree.m
        \item trainClassifierMediumTree.m
        \item trainClassifierCoarseTree.m
        \item trainClassifierBaggedTrees\_30.m
        \item trainClassifierBaggedTrees\_100.m
        \item trainClassifierBaggedTrees\_300.m
    \end{itemize}
    Thus, the steps above can be easily reproduced without using the GUI of the toolbox.

}

\clearpage
\end{document}


%!TEX root = ../main.tex

\subsection{Tau}
360 is nice enough number.  It divides evenly by 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 18, 20, 24, 30,
36, 40, 45, 60, 72, 90, and 180.  No other number under 1000 even comes close.  But it
is still arbitrary.  Why are there 60 seconds in a minute, 60 minutes in an hour, 360 degrees
in a full rotation?  Because Babylonian mathematicians wanted numbers that were easier
division!

A far more natural system exists and is indeed the only one used in calculus and higher
mathematics today.  Rather than assigning an arbitrary number to the complete
circle, we ask instead, what fraction of a full rotation have you turned?  One full rotation
will correspond with the entire circumference of the circle.  And again, this will be
done on the Unit Circle, so that an angle's measure is defined as the arc length
divided by the radius.  Because this is length divided by length, angles in this system
(called radians) have no units.  Turning all the way around one time is the same as
laying the radius of any circle out in a curved piece $6.28\dots$ times.  Rather than
write this irrational number to some arbitrary number of decimals, we use the symbol
$\tau$, called TAU.

There are no calculators with the number $\tau$ on them (yet), so we must use
the fact that $\tau=2\pi$.

\subsection{Unit Circle}
This all culminates in the single figure that most embodies trigonometry: the completed
Unit Circle.  Because your education up to this point has utilized degrees, they are included
but you should concentrate on using radians, as they will be the main system used
from now on.

\begin{figure}
\begin{center}
\begin{tikzpicture} [scale=1.7,
% Toggle commenting on the next four lines for the completed unit circle:
angle/.style={draw,text=white,fill=white,minimum height=1cm, minimum width=1cm},
point/.style={white},
angle/.style={fill=white},
point/.style={},
]
    \draw [white] (-3.6,-3.6) rectangle (3.6,3.6);
    \draw [thick,fill=white] (0,0) circle (3cm);
    \draw [thick, ] (-3.3,0) -- (3.3,0);
    \draw [thick, ] (0,-3.3) -- (0,3.3);
    \draw (0,0) --  node [angle] {$\frac{\tau}{4}$} (90:3)
                node[point, above right] {$ \left(0,1\right)  d.n.e.$};
    \draw (0,0) --  node [angle] {$\frac{\tau}{2}$} (180:3)
                node[point, above left] {$ \left(-1,0\right) 0$};
    \draw (0,0) --  node [angle] {$\frac{3\tau}{4}$} (270:3)
                node[point, below right] {$ \left(0,-1\right) d.n.e.$};
    \draw (0,0) --  node [angle] {$\tau$} (0:3)
                node[point, above right] {$ \left(1,0\right) 0$};
    \draw (0,0) --  node [angle] {$\frac{\tau}{8}$} (45:3)
                node [point, above right] {$ \left( \frac{\sqrt2}{2} , \frac{\sqrt2}{2}  \right) 1$};
    \draw (0,0) --  node [angle] {$\frac{3\tau}{8}$} (135:3)
                node [point, above left] {$ \left( -\frac{\sqrt2}{2} , \frac{\sqrt2}{2}  \right ) -1$};
    \draw (0,0) --  node [angle] {$\frac{5\tau}{8}$} (225:3)
                node [point, below left] {$ \left( -\frac{\sqrt2}{2} , -\frac{\sqrt2}{2}  \right) 1$};
    \draw (0,0) --  node [angle] {$\frac{7\tau}{8}$} (315:3)
                node [point, below right] {$ \left( \frac{\sqrt2}{2} , -\frac{\sqrt2}{2}  \right) -1$};
    \draw (0,0) --  node [near end, angle] {$\frac{\tau}{12}$} (30:3)
                node [point, above right] {$ \left( \frac{\sqrt3}{2} , \frac{1}{2}  \right) \frac{\sqrt{3}}{3}$};
    \draw (0,0) --  node [near end, angle] {$\frac{\tau}{6}$} (60:3)
                node [point, above right] {$ \left( \frac{1}{2} , \frac{\sqrt3}{2}  \right) \sqrt{3} $};
    \draw (0,0) --  node [near end, angle] {$\frac{\tau}{3}$} (120:3)
                node [point, above left] {$ \left( -\frac{1}{2} , \frac{\sqrt3}{2}  \right) -\sqrt{3} $};
    \draw (0,0) --  node [near end, angle] {$\frac{5\tau}{12}$} (150:3)
                node [point, above left] {$ \left(- \frac{\sqrt3}{2} , \frac{1}{2}  \right) \frac{\sqrt{3}}{3} $};
    \draw (0,0) --  node [near end, angle] {$\frac{7\tau}{12}$} (210:3)
                node [point, below left] {$ \left(- \frac{\sqrt3}{2} , -\frac{1}{2}  \right) \frac{\sqrt{3}}{3}$};
    \draw (0,0) --  node [near end, angle] {$\frac{2\tau}{3}$} (240:3)
                node [point, below left] {$ \left( -\frac{1}{2} , -\frac{\sqrt3}{2}  \right) \sqrt{3}$};
    \draw (0,0) --  node [near end, angle] {$\frac{5\tau}{6}$} (300:3)
                node [point, below right] {$ \left( \frac{1}{2} , -\frac{\sqrt3}{2}  \right) -\sqrt{3}$};
    \draw (0,0) --  node [near end, angle] {$\frac{11\tau}{12}$} (330:3)
                node [point, below right] {$ \left( \frac{\sqrt3}{2} , -\frac{1}{2}  \right) -\frac{\sqrt{3}}{3}$};

    \foreach \n in {1,2,3,4}
        \foreach \t in {0,30,45,60}
            \fill (\n*90+\t:3) circle (0.03cm);
    \foreach \t in {30,45,60, 120,135,150, 210,225,240, 300,315,330}
        \node [font=\tiny, fill=white,inner sep=1pt] at (\t:.75) {$ \t^\circ $};
\end{tikzpicture}
\caption{The full unit circle, with $x$, $y$, and $m$, radians and degrees, for your careful study.}
\end{center}
\end{figure}

It may be helpful to think of conversion to and from radians as dimension analysis,
as in the sciences.  A full circle is 1 $\tau$, which is the same as $360^\circ$, so these
numbers can be put in a fraction equalling one.  Multiplying by one does not change
anything.

\begin{example}{Conversion}
\exProblem
Convert $215^\circ$ into radians and $\frac{5\tau}{6}$ into degrees

\exSolution
$$
215^\circ \cdot \frac{\tau}{360^\circ} = \frac{215\tau}{360} = \frac{43\tau}{72}
$$
and
$$
\frac{5\tau}{6} \cdot \frac{360^\circ}{\tau} = \frac{1800^\circ}{6} = 300^\circ
$$
\end{example}

\subsection{Derivative}
We have already said that sine is y, cosine is x, and tangent is m, but m (slope)
is y over x, so tangent is sine over cosine.  Recall that the reciprocals of the
standard trigonometric functions have names, specifically that 1 over sine
is cosecant, 1 over cosine is secant, and 1 over tangent is cotangent.  You are asked
to find the derivatives of each in the exercises.

While it is not the formal proof for the derivative of sine we will present in chapter
\ref{ch:identities}, we can now build a geometric proof.  Sine is the signed vertical
displacement of a point on the unit circle, after we have traversed $\theta$ units of
arc.  For every tiny nudge $d\theta$, there is a similar triangle created that
highlights the additional change brought about to the height, or $\sin\theta$.  The
figure below shows how on the smaller triangle, the ratio of the adjacent side
to the hypotenuse -- cosine -- is tiny change in the height.  All these values
become more accurate the smaller the triangle becomes.

\begin{figure}[h]
\begin{centering}
\begin{tikzpicture}[line cap=round,line join=round,x=2cm,y=2cm,
     spy using outlines={rectangle,lens={scale=12}, size=8cm, connect spies}]
	\coordinate (A) at (30:2);
	\coordinate (B) at (1.73205,0);
	\coordinate (C) at (1.672,1.1000);
	\coordinate (D) at (1.672,1.0000);
	\draw[->] (-0.5,0) -- (2.2,0) node[anchor=west] {$x$};
	\draw[->] (0,-0.3) -- (0,2.1) node[anchor=west] {$y$};
	\draw(0,0) ++ (-10:2) arc (-10:100:2.01);
	\draw(0,0) -- (A) -- (B);
	\draw(C) -- (D) -- (A);
	\draw[ultra thin](0,0) ++ (0:2.2) arc (0:30:2.2) ;

	\node at (2.3,0.5) {$\theta$};
	\spy [blue] on (1.7,1.05)
             in node [left] at (6.5,1);
	\draw[decorate, decoration={brace},xshift=0.5cm,yshift=0.4cm] (4.2,1.6) -- (4.9,0.4) node[midway,xshift=0.5cm,yshift=0.2cm] {$d\theta$};
	\draw (4.2,1.6) ++ (-90:.5) arc (-90:-60:0.5) node[midway,yshift=-0.2cm] {$\theta$};
	\draw[decorate, decoration={brace},xshift=-0.5cm] (4.2,0.4) -- (4.2,1.6) node[midway,xshift=-0.6cm] {$\cos\theta$};
\end{tikzpicture}
\caption{Zoom in on $\theta$ plus a tiny $d\theta$'s effect on $\sin\theta$.}
\end{centering}
\end{figure}


\newcommand{\raul}{Ra\'ul}
\section{Tutorial 5: \raul{} Typesetting An Exam Paper}
One task of the department is to elucidate the past exam papers of those math courses. In this tutorial, we will see how \raul{} takes advantage of the package xjtluexam to typeset an exam paper.

\subsection{The exampaper Environment}
To begin an exam paper, \raul{} uses the exampaper environment. The environment itself gives no output, but provides several commands\footnote{In fact, the commands are not \emph{provided} by this environment. It merely does some initialization works so that these commands can function normally.}.

Then, \raul{} types \verb=\question= to start a question.
\begin{miniexammar}{.5\textandmarginlen}{
\begin{exampaper}
\question Justify whether $\infseries{n}{1}$ converges or not when $a_n \to 0$.
\question Evaluate
\[
\int x^5 e^{x^2} \dx
\]
\end{exampaper}
}
\begin{lstlisting}
\begin{exampaper}
\question Justify whether $\infseries{n}{1}$ converges or not if $a_n \to 0$.
\question Evaluate
\[
\int x^5 e^{x^2} \dx
\]
\end{exampaper}
\end{lstlisting}
\end{miniexammar}

The question counter can be referenced normally.
\begin{miniexammar}{.5\textandmarginlen}{
\begin{exampaper}
\question Justify whether $\infseries{n}{1}$ converges or not when $a_n \to 0$.
\question \label{ques:examques} Evaluate
\[
\int x^5 e^{x^2} \dx
\]
\end{exampaper}
A solution to Question \ref{ques:examques} is ...
}
\begin{lstlisting}
\begin{exampaper}
\question Justify whether $\infseries{n}{1}$ converges or not when $a_n \to 0$.
\question \label{ques:examques} Evaluate
\[
\int x^5 e^{x^2} \dx
\]
\end{exampaper}
A solution to Question \ref{ques:examques} is ...
\end{lstlisting}
\end{miniexammar}

Subquestions may be given, and the numbering for them is alphabetical.
\begin{miniexammar}{.5\textandmarginlen}{
\begin{exampaper}
\question Given the function $f=...$

\hspace{1.5em}(a) Evaluate $f(3)$

\hspace{1.5em}(b) Prove a proposition about $f$.
\end{exampaper}
}
\begin{lstlisting}
\begin{exampaper}
\question Given the function $f=...$
\subquestion Evaluate $f(3)$
\subquestion Prove a proposition about $f$.
\end{exampaper}
\end{lstlisting}
\end{miniexammar}

\subsection{Multiple Choice Questions}
Multiple choice questions (MCQs) appear in exam papers quite often. xjtluexam package designs several environments and commands just for them.

To introduce the choices of a MCQ, \raul{} begins a choice environment. There are two choice environments: \emph{shortchoices} and \emph{longchoices}. As their name suggest, they are used to introduce short choices (multiple choices are in one line) and long choices (one choice occupies one line), respectively.

Inside one of the environments, a choice number is given by the \verb=\choicenumber= command. The space after a choice is given by the command \verb=\choicespace=. \raul{} doesn't want a space at the end of the last choice, so he only uses the command between choices.
\begin{miniexammar}{.55\textandmarginlen}{
\begin{exampaper}
\question Evaluate
\[
\int_{-1}^1 x^2\cosh{x} \dx
\]
\begin{shortchoices}
\choicenumber $\frac{2\sinh{1}}{3}$ \choicespace
\choicenumber $-\frac{2\sinh{1}}{3}$ \choicespace
\choicenumber $\frac{2\cosh{1}}{3}$ \choicespace
\choicenumber $-\frac{2\cosh{1}}{3}$
\end{shortchoices}
\end{exampaper}
}
\begin{lstlisting}
\begin{exampaper}
\question Evaluate
\[\int_{-1}^1 x^2\cosh{x} \dx\]
\begin{shortchoices}
\choicenumber $\frac{2\sinh{1}}{3}$ \choicespace \choicenumber $-\frac{2\sinh{1}}{3}$ \choicespace \choicenumber $\frac{2\cosh{1}}{3}$ \choicespace \choicenumber $-\frac{2\cosh{1}}{3}$
\end{shortchoices}
\end{exampaper}
\end{lstlisting}
\end{miniexammar}

If \raul{} feels that the space is too tight, he can freely break the lines
\begin{miniexammar}{.42\textandmarginlen}{
\begin{exampaper}
\question Evaluate
\[
\int_{-1}^1 x^2\cosh{x} \dx
\]
\begin{shortchoices}%
\choicenumber $\frac{2\sinh{1}}{3}$\choicespace%
\choicenumber $-\frac{2\sinh{1}}{3}$\\
\choicenumber $\frac{2\cosh{1}}{3}$\choicespace%
\choicenumber $-\frac{2\cosh{1}}{3}$%
\end{shortchoices}
\end{exampaper}
}
\begin{lstlisting}
\begin{exampaper}
\question Evaluate
\[\int_{-1}^1 x^2\cosh{x} \dx\]
\begin{shortchoices}%
\choicenumber $\frac{2\sinh{1}}{3}$\choicespace \choicenumber $-\frac{2\sinh{1}}{3}\\ \choicenumber $\frac{2\cosh{1}}{3}$\choicespace \choicenumber $-\frac{2\cosh{1}}{3}$%
\end{shortchoices}
\end{exampaper}
\end{lstlisting}
\end{miniexammar}
Here, \raul{} uses the comment sign \verb=%= to eliminate the line break character, which would be treated as a white space by \LaTeX{} if not removed.

For longchoices environment, the usage is similar, except that \raul{} doesn't need to care about the line breaks, as one choice itself begins a new line at its end.
\begin{miniexammar}{.42\textandmarginlen}{
\begin{exampaper}
\question Which of the following functions satisfy Laplace's Equation
\[\frpdt[^2 f]{x^2} + \frpdt[^2 f]{y^2} = 0\]
\begin{longchoices}%
\choicenumber $f(x,y):=x^3y-xy^3$\choicespace%
\choicenumber $f(x,y):=\log{(4x^2+4y^2)}$\choicespace%
\choicenumber $f(x,y):=3 x^4 y^5 - 2 x^2 y^3$\choicespace%
\choicenumber $f(x,y):=\cos{(2x^2-2y^2)}$%
\end{longchoices}
\end{exampaper}
}
\begin{lstlisting}
\begin{exampaper}
\question Which of the following functions satisfy Laplace's Equation
\[\frpdt[^2 f]{x^2} + \frpdt[^2 f]{y^2} = 0\]
\begin{longchoices}%
\choicenumber $f(x,y):=x^3y-xy^3$\choicespace%
\choicenumber $f(x,y):=\log{(4x^2+4y^2)}$\choicespace%
\choicenumber $f(x,y):=3 x^4 y^5 - 2 x^2 y^3$\choicespace%
\choicenumber $f(x,y):=\cos{(2x^2-2y^2)}$%
\end{longchoices}
\end{exampaper}
\end{lstlisting}
\end{miniexammar}

\subsection{Space And Rules}
It is conventional to leave a vertical space after a comprehensive question is given. To add a certain amount of vertical space, \raul{} uses command \verb=\vspace=.
\begin{miniexammar}{.5\textandmarginlen}{
\begin{exampaper}
\question Find ...
\vspace{.8cm}
\question Prove ...
\end{exampaper}
}
\begin{lstlisting}
\question Find ...
\vspace{.8cm}
\question Prove ...
\end{lstlisting}
\end{miniexammar}

He is quite satisfied with this result, though he wonders how to evenly distribute questions on a page. The command \verb=\stretch=, when used in \verb=\vspace=, gives a space with respect to the number given to it. For example, if \raul{} wants to place three questions evenly on a page, he writes:
\begin{miniexammar}{.5\textandmarginlen}{
\begin{exampaper}
\question Find ...
\vspace{.5cm}
\question Prove ...
\vspace{.5cm}
\question Evaluate ...
\end{exampaper}
}
\begin{lstlisting}
\question Find ...
\vspace{\stretch{1}}
\question Prove ...
\vspace{\stretch{1}}
\question Evaluate ...
\end{lstlisting}
\end{miniexammar}
The number can be changed for a relatively larger space. For example, if \raul{} writes
\begin{lstlisting}
\question Find ...
\vspace{\stretch{2}}
\question Prove ...
\vspace{\stretch{1}}
\question Evaluate ...
\end{lstlisting}
, then the empty space left will be evenly divided into $2+1=3$ pieces. Two of them are given to the place where \verb=\stretch{2}= is given, and the other one is given to the place where \verb=\stretch{1}= is given.

To create questions that require a student to fill in the blanks, \raul{} has to draw the blanks, that is, to draw a line under each of the blanks. In \LaTeX{}, a horizontal line can be drawn by the command
\begin{verbatim}
\rule[lift]{width}{height}
\end{verbatim}
, where lift is with respect to the baseline.

To simplify the work, xjtluexam provides the command \verb=\blankline= to draw a line with a given width (default 1cm).
\begin{miniexammar}{.5\textandmarginlen}{
\begin{exampaper}
\question $(3\vec{i}-9\vec{j}) \times (2\vec{i}+1\vec{j}) = $ \blankline
\question $\frdt[\cos^2 x \sin x]{x} = $ \blankline[1.5cm]
\end{exampaper}
}
\begin{lstlisting}
\begin{exampaper}
\question $(3\vec{i}-9\vec{j}) \times (2\vec{i}+1\vec{j}) = $ \blankline
\question $\frdt[\cos^2 x \sin x]{x} = $ \blankline[1.5cm]
\end{exampaper}
\end{lstlisting}
\end{miniexammar}

Now \raul{} has everything he needs to know, and an exam paper will be ready soon...


\section{Classifying spaces and bundles}
Let $\pi:Y\to X$ be a map of spaces. This defines a ``descent category''
$\cCC(\pi)$ whose objects are the points of $Y$, whose morphisms are points of
$Y\times_X Y$, and whose structure morphisms are the obvious maps. Let $cX$
denote the category whose objects and morphisms are both given by points of
$X$, so that the nerve $NcX$ is the constant simplicial object with value $X$.
There is a functor $\cCC(\pi)\to cX$ specified by the map $\pi$.

Let $\cU$ be a cover of $X$. Let $\cCC(\cU)$ denote the descent category
associated to the obvious map $\epsilon:\coprod_{U\in \cU} U\to X$. It is easy
to see that $\epsilon:B\cCC(\cU) \simeq X$ if $\cU$ is numerable. The morphism
determined by $x\in U\cap V$ is denoted $x_{U,V}$. Suppose $p:P\to X$ is a
principal $G$-bundle.  Then $\cU$ trivializes $p$ if there are homeomorphisms
$t_U:p^{-1}(U)\xrightarrow{\simeq} U\times G$ over $U$. Specifying such
homeomorphisms is the same as a trivialization of the pullback bundle
$\epsilon^\ast P$.

This, in turn, is the same as a functor $\theta_P:\cCC(\cU)\to G$. To
see this, we note that the $G$-equivariant composite $t_V\circ t_U^{-1}:(U\cap
V)\times G\to (U\cap V)\times G$ is determined by the value of $(x,1)\in (U\cap
V)\times G$. The map $U\cap V\to G$ is denoted $f_{U,V}$. Then, the functor
$\theta_P:\cCC(\cU)\to G$ sends every object of $\cCC(\cU)$ to the point, and
$x_{U,V}$ to $f_{U,V}(x)$.

On classifying spaces, we therefore get a map $X\xleftarrow{\simeq}
B\cCC(\cU)\xrightarrow{\theta_P} BG$, where the map on the left is given by
$\epsilon$.
\begin{exercise}
    Prove that $\theta_P^\ast EG \simeq \epsilon^\ast P$.
\end{exercise}
This suggests that $BG$ is a classifying space for principal $G$-bundles (in
the sense of \S \ref{grassmannmodel}). To make this precise, we need to prove
that two principal $G$-bundles are isomorphic if and only if the associated
maps $X\to BG$ are homotopic.

To prove this, we will need to vary the open cover. Say that $\cV$
\emph{refines} $\cU$ if for any $V\in \cU$, there exists $U\in\cU$ such that
$V\subseteq U$. A \emph{refinement} is a function $p:\cV\to\cU$ such that
$V\subseteq p(V)$. A refinement $p$ defines a map $\coprod_{V\in \cV} V\to
\coprod_{U\in\cU} U$, denoted $\rho$.

As both $\coprod_{V\in \cV} V$ and $\coprod_{U\in\cU} U$ cover $X$, we get a
map $\cCC(\cV)\to \cCC(\cU)$ over $cX$. Taking classifying spaces begets a
diagram:
$$
\xymatrix{
    B\cCC(\cV)\ar[r]\ar[dr] & B\cCC(\cU)\ar[d]\\
    & X
}
$$
Let $t$ be trivialization of $P$ for the open cover $\cU$. The construction
described above begets a functor $B\cCC(\cU)\to BG$, so we get a trivialization
$s$ for $\cV$. This is a homeomorphism $s_V:p^{-1}(V)\to V\times G$ which fits
into the following diagram:
\begin{equation*}
    \xymatrix{
	p^{-1}(V)\ar[r]^{s_V}_\sim\ar[d] & V\times G\ar[d]\\
	p^{-1}(\rho(V))\ar[r]_{t_{\rho(V)}}^\sim & \rho(V)\times G
    }
\end{equation*}
By construction, there is a large commutative diagram:
\begin{equation*}
\xymatrix{
    B\cCC(\cV)\ar[r]\ar[dr]^\sim\ar@/^0.135in/[rr] &
    B\cCC(\cU)\ar[d]^\sim\ar[r] & BG\\
    & X.
}
\end{equation*}
This justifies dropping the symbol $\cU$ in the notation for the map
$\theta_P$.

Consider two principal $G$-bundles over $X$:
\begin{equation*}
    \xymatrix{
	P\ar[r]^{\simeq} \ar[dr] & Q\ar[d]\\
	& X,
    }
\end{equation*}
and suppose I have trivializations $(\cU, t)$ of $P$ and $(\cW, s)$ of $Q$.
Let $\cV$ be a common refinement, so that there is a diagram:
\begin{equation*}
    \xymatrix{
	& \cCC(\cU)\ar[dr]^{\theta^\cU_{P}} & \\
	\cCC(\cV)\ar[ur]\ar[dr] \ar@/^/[rr]^{\theta^\cV_P}
	\ar@/_/[rr]_{\theta^\cV_Q} & & G\\
	& \cCC(\cW)\ar[ur]_{\theta^\cW_Q}
    }
\end{equation*}
Included in the diagram is a mysterious natural transformation
$\beta:\theta^\cV_P\to \theta^\cV_Q$, whose construction is left as an exercise
to the reader\todo{Should we describe this? It's rather technical...}. Its
existence combined with Lemma \ref{nat-trans-htpy} implies that the two maps
$\theta_P,\theta_Q:B\cCC(\cV)\simeq X\to BG$ are homotopic, as desired.

\subsection{Topological properties of $BG$}\label{loops-bg}
Before proceeding, let us summarize the constructions discussed so far. Let $G$
be some topological group (assumed to be an absolute neighborhood retract of a
Lie group). We constructed $EG$, which is a contractible space with $G$ acting
freely on the right (this works for any topological group). There is an orbit
projection $EG\to BG$, which is a principal $G$-bundle under our assumption on
$G$. The space $BG$ is universal, in the sense that there is a bijection
$$\Bun_G(X)\xleftarrow{\simeq} [X, BG]$$
given by $f\mapsto [f^\ast EG]$.

Let $E$ be a space such that $G$ acts on $E$ from the left. If $P\to B$ is any
principal $G$-bundle, then $P\times E\to P\times_G E$ is another principal
$G$-bundle. In the case $P = EG$, it follows that if $E$ is a contractible
space on which $G$ acts, then the quotient $EG\times_G E$ is a model for $BG$.
Recall that $EG$ is contractible. Therefore, if $E$ is a contractible space on
which $G$ acts freely, then the quotient $G\backslash E$ is a model for $BG$.
Of course, one can run the same argument in the case that $G$ acts on $E$ from
the right. Although the construction with simplicial sets provided us with a
very concrete description of the classifying space of a group $G$, we could
have chosen any principal action on a contractible space in order to obtain a
model for $BG$.

Suppose $X$ is a pointed path connected space. Remember that $X$ has a
contractible path space $PX = X^I_\ast$. The canonical map $PX\to X$ is a
fibration, with fiber $\Omega X$.

Consider the case when $X = BG$. Then, we can compare the above fibration with
the fiber bundle $EG\to BG$:
\begin{equation*}
    \xymatrix{
	G\ar[r]\ar[d] & \Omega BG\ar[d]\\
	\ast \simeq EG\ar[d]\ar@{-->}[r] & PBG\simeq \ast \ar[d]\\
	BG\ar@{=}[r] & BG
    }
\end{equation*}
The map $EG\to BG$ is nullhomotopic; a choice of a nullhomotopy is exactly a
lift into the path space. Therefore, the dotted map $EG\to PBG$ exists in the
above diagram. As $EG$ and $PBG$ are both contractible, we conclude that
$\Omega BG$ is weakly equivalent to $G$. In fact, this weak equivalence is a
$H$-map, i.e., it commutes up to homotopy with the multiplication on both
sides.
\begin{remark}[Milnor]
    If $X$ is a countable CW-complex, then $\Omega X$ is not a CW-complex, but
    it is \emph{homotopy} equivalent (not just weakly equivalent) to one.
    Moreover, $\Omega X$ is weakly equivalent to a topological group $GX$ such
    that $BGX\simeq X$.
\end{remark}
\subsection{Examples}
We claim that $BU(n)\simeq \Gra_n(\cC^\infty)$. To see this, let
$V_n(\cC^\infty)$ is the contractible space of complex $n$-frames in
$\cC^\infty$, i.e., isometric embeddings of $\cc^n$ into $\cc^\infty$. The
Lie group $U(n)$ acts principally on $V_n(\cC^\infty)$ by precomposition, and the
quotient $V_n(\cC^\infty)/U(n)$ is exactly the Grassmannian
$\Gra_n(\cC^\infty)$. As $\Gra_n(\cC^\infty)$ is the quotient of a principal action
of $U(n)$ on a contractible space, our discussion in the previous section
implies the desired claim.

Let $G$ be a compact Lie group (eg finite).
\begin{theorem}[Peter-Weyl]
    There exists an embedding $G\hookrightarrow U(n)$ for some $n$.
\end{theorem}
Since $U(n)$ acts principally on $V_n(\cC^\infty)$, it follows $G$ also acts
principally on $V_n(\cc^\infty)$. Therefore $V_n(\cc^\infty)/G$ is a model for
$BG$. It is not necessarily that this the most economic description of $BG$.

For instance, in the case of the symmetric group $\Sigma_n$, we have a much
nicer geometric description of the classifying space. Let
$\mathrm{Conf}_n(\RR^k)$ denote embeddings of $\{1,\cdots,n\}\to \RR^k$
(ordered distinct $n$-tuples). This space is definitely \emph{not}
contractible! However, the classifying space $\mathrm{Conf}_n(\RR^\infty)$ is
contractible. The symmetric group obviously acts freely on this (for finite
groups, a principal action is the same as a free action). It follows that
$B\Sigma_n$ is the space of \emph{un}ordered configurations of $n$ distinct
points in $\RR^\infty$. Using Cayley's theorem from classical group theory, we
find that if $G$ is finite, a model for $BG$ is the quotient
$\mathrm{Conf}_n(\RR^\infty)/G$.

We conclude this chapter with a construction of Eilenberg-Maclane spaces via
classifying spaces. If $A$ is a topological abelian group, then the
multiplication $\mu:A\times A\to A$ is a homomorphism. Applying the classifying
space functor begets a map $m:BA\times BA\to BA$. If $G$ is a finite group, then
$BA = K(A, 1)$. The map $m$ above gives a topological abelian group model for
$K(A, 1)$. There is nothing preventing us from iterating this construction: the
space $B^2 A$ sits in a fibration
$$BA \to EBA\simeq \ast \to B^2 A.$$
It follows from the long exact sequence in homotopy that the homotopy groups of
$B^2 A$ are the same as that of $BA$, but shifted up by one. Repeating this
procedure multiple times gives us an explicit model for $K(A,n)$:
$$B^n A = K(A, n).$$


\subsection{Accuracy Measures}
\label{mase}

Choosing an error measure for both model selection and evaluation is not
    straightforward when working with intermittent demand, as shown, for
    example, by \cite{syntetos2005}, and one should understand the trade-offs
    between measures.
\cite{hyndman2006} provide a study of measures with real-life data taken from
    the popular M3-competition and find that most standard measures degenerate
    under many scenarios.
They also provide a classification scheme for which we summarize the main
    points as they apply to the UDP case:
\begin{enumerate}
\item \textbf{Scale-dependent Errors}:
The error is reported in the same unit as the raw data.
Two popular examples are the root mean square error (RMSE) and mean absolute
    error (MAE).
They may be used for model selection and evaluation within a pixel, and are
    intuitively interpretable; however, they may not be used to compare errors
    of, for example, a low-demand pixel (e.g., at the UDP's service
    boundary) with that of a high-demand pixel (e.g., downtown).
\item \textbf{Percentage Errors}:
The error is derived from the percentage errors of individual forecasts per
    time step, and is also intuitively interpretable.
A popular example is the mean absolute percentage error (MAPE) that is the
    primary measure in most forecasting competitions.
Whereas such errors could be applied both within and across pixels, they
    cannot be calculated reliably for intermittent demand.
If only one time step exhibits no demand, the result is a divide-by-zero
    error.
This often occurs even in high-demand pixels due to the slicing.
\item \textbf{Relative Errors}:
A workaround is to calculate a scale-dependent error for the test day and
    divide it by the same measure calculated with forecasts of a simple
    benchmark method (e.g., na\"{i}ve method).
An example could be
    $\text{RelMAE} = \text{MAE} / \text{MAE}_\text{bm}$.
Nevertheless, even simple methods create (near-)perfect forecasts, and then
    $\text{MAE}_\text{bm}$ becomes (close to) $0$.
These numerical instabilities occurred so often in our studies that we argue
    against using such measures.
\item \textbf{Scaled Errors}:
\cite{hyndman2006} contribute this category and introduce the mean absolute
    scaled error (MASE).
It is defined as the MAE from the actual forecasting method on the test day
    (i.e., "out-of-sample") divided by the MAE from the (seasonal) na\"{i}ve
    method on the entire training set (i.e., "in-sample").
A MASE of $1$ indicates that a forecasting method has the same accuracy
    on the test day as the (seasonal) na\"{i}ve method applied on a longer
    horizon, and lower values imply higher accuracy.
Within a pixel, its results are identical to the ones obtained with MAE.
Also, we acknowledge recent publications, for example, \cite{prestwich2014} or
    \cite{kim2016}, showing other ways of tackling the difficulties mentioned.
However, only the MASE provided numerically stable results for all
    forecasts in our study.
\end{enumerate}
Consequently, we use the MASE with a seasonal na\"{i}ve benchmark as the
    primary measure in this paper.
With the previously introduced notation, it is defined as follows:
$$
\text{MASE}
:=
\frac{\text{MAE}_{\text{out-of-sample}}}{\text{MAE}_{\text{in-sample}}}
=
\frac{\text{MAE}_{\text{forecasts}}}{\text{MAE}_{\text{training}}}
=
\frac{\frac{1}{H} \sum_{h=1}^H |y_{T+h} - \hat{y}_{T+h}|}
     {\frac{1}{T-k} \sum_{t=k+1}^T |y_{t} - y_{t-k}|}
$$
The denominator can only become $0$ if the seasonal na\"{i}ve benchmark makes
    a perfect forecast on each day in the training set except the first seven
    days, which never happened in our case study involving hundreds of
    thousands of individual model trainings.
Further, as per the discussion in the subsequent Section \ref{decomp}, we also
    calculate peak-MASEs where we leave out the time steps of non-peak times
    from the calculations.
For this analysis, we define all time steps that occur at lunch (i.e., noon to
    2 pm) and dinner time (i.e., 6 pm to 8 pm) as peak.
As time steps in non-peak times typically average no or very low order counts,
    a UDP may choose to not actively forecast these at all and be rather
    interested in the accuracies of forecasting methods during peaks only.

We conjecture that percentage error measures may be usable for UDPs facing a
    higher overall demand with no intra-day down-times in between but have to
    leave that to a future study.
Yet, even with high and steady demand, divide-by-zero errors are likely to
    occur.


%!TEX root = kPtx_paper.tex
\section*{Discussion}
\subsection*{Summary}
A small-tip-angle k-space domain parallel transmit pulse design algorithm was proposed
that divides up the calculation of a matrix relating a target excitation pattern to the pulses that produce it
into a set of independent problems for patches of target excitation k-space locations,
each of which is influenced by a local neighborhood of points on the excitation k-space trajectory.
The division of the problem into patches of target locations creates an opportunity for fine parallelization,
while the limited neighborhood sizes lead to small problem sizes for each patch.
Compared to the original k-space-based algorithm of Ref. \cite{Katscher:2003:Magn-Reson-Med:12509830},
the L-curve and matrix size results showed that
the new algorithm produces much smaller matrix sizes that can be calculated more quickly,
with the tradeoff of increased excitation error or RF power.
Results showed that the algorithm also enables compensation of off-resonance
which has not previously been described in a k-space domain design.
Compared to widely-used spatial domain method of Ref. \cite{Grissom:2006:MRM},
the new algorithm is non-iterative and can be finely parallelized to achieve shorter design times,
and results showed that it can use coarser target grid sizes while avoiding Gibbs ringing,
again with the tradeoff of increased excitation error or RF power.
The performance of off-resonance-compensated spatial domain and k-space domain pulse designs was similar,
and the methods were similarly sensitive to excitation k-space undersampling.

\subsection*{Applications and Extensions}
This work was initially motivated by the observation that spatial domain parallel pulse designs can be very slow
for 3D problems with large grid sizes,
requiring both many iterations and considerable computation per iteration.
It is anticipated that the proposed k-space domain algorithm will be most useful for these types of large $>$2D problems,
which include 3D spatial designs \cite{malik2012tailored} and 2D and 3D spatial-spectral designs \cite{stenger2000three,yang2010four,davids2016fast}
where full matrix construction and inversion is infeasible due to the problem size,
and an iterative design can require several minutes to solve.
Furthermore, unlike an iterative spatial domain design the proposed algorithm does not need to be repeated if the target pattern changes.
This means that it could have a considerable computational speed advantage for magnitude least-squares designs \cite{setsompop2008magnitude,malik:mrm:2015}.
The method could also be used to initialize spatial-domain designs to reduce the number of iterations required to reach a target cost;
Finally, while simple Tikhonov RF power regularization was used in the designs presented here,
more sophisticated regularization could be incorporated to, e.g., control peak RF power via adaptive regularization \cite{Yip:2005:Magn-Reson-Med:16155881},
or to enforce array compression by projecting the weights into the null space of a compression matrix \cite{cao2016array}.
In such designs, it would be beneficial to pre-compute and store the lower triangular elements of the $\bm{S}^H\bm{S}$ matrices
so they need not be re-computed as the regularization changes over iterations.

\section*{Conclusion}
The proposed k-space domain algorithm accelerates and finely parallelizes parallel transmission pulse design,
with a modest tradeoff of excitation error and RMS RF amplitude.


% Activate the following line by filling in the right side. If for example the name of the root file is Main.tex, write
% "...root = Main.tex" if the chapter file is in the same directory, and "...root = ../Main.tex" if the chapter is in a subdirectory.

%!TEX root =

\chapter[Processor Instructions]{Processor Instructions}

\section{Processor Instructions}

\subsection*{AAA}
ASCII Adjust after Addition

\begin{tabular}{l l l l}
Opcode & Instruction & Clocks & Description\\
37 & AAA & 4 & ASCII adjust AL after addition\\
\end{tabular}

\subsubsection{Operation}
\begin{verbatim}
IF ((AL AND 0FH) > 9) OR (AF = 1) THEN
  AL := AL + 6;
  AH := AH +1;
  AF := 1;
  CF := 1;
ELSE
  CF := 0;
  AF := 0;
ENDIF
AL := AL AND 0FH;
\end{verbatim}

\subsubsection{Discussion}
Code AAA only following an ADD instruction that leaves a byte result in the AL register. The lower nibbles of the ADD operands should be in the range 0 through 9 (BCD digits) so that AAA adjusts AL to contain the correct decimal digit result. If ADD produced a decimal carry, AAA increments the AH register and sets the carry (CF) and auxiliary carry (AF) flags to 1. If ADD produced no decimal carry, AAA clears the carry and auxiliary flags (0) and leaves AH unchanged. In either case, AL is left with its upper nibble set to 0. To convert AL to an ASCII result, follow the AAA instruction with OR AL, 30H.

\subsubsection{Flags Affected}
AF and CF as described in the Discussion section; OF, SF, ZF, and PF are undefined.

\subsubsection{Exceptions by Mode}

Protected

None

Real Address

None

Virtual 8086

None

\subsection*{AAD}

ASCII Adjust AX before Division

\begin{tabular}{l l l l}
Opcode & Instruction & Clocks & Description\\
D5 0A & AAD & 19 & ASCII adjust AX before division\\
\end{tabular}

\subsubsection{Operation}
\begin{verbatim}
  AL := AH * 0AH + AL;
  AH := 0;
\end{verbatim}

\subsubsection{Discussion}

AAD prepares 2 unpacked BCD digits (the least significant digit in AL, the most significant digit in AH) for a division operation that will yield an unpacked result. This is done by setting AL to AL + (10 * AH), and then setting AH to 0. AX is then equal to the binary equivalent of the original unpacked 2-digit number.

\subsubsection{Flags Affected}
SF, ZF, and PF as described in Appendix A; OF, AF, and CF are undefined

\subsubsection{Exceptions by Mode}

Protected

None

Real Address

None

Virtual 8086

None

\subsection*{AAM}

ASCII adjust AX after multiply

\begin{tabular}{l l l l}
Opcode & Instruction & Clocks & Description\\
D4 0A & AAM & 17 & ASCII adjust AX after multiply\\
\end{tabular}

\subsubsection{Operation}
\begin{verbatim}
  AH := AL / 0AH;
  AL := AL MOD 0AH;
\end{verbatim}

\subsubsection{Discussion}

Code AAM only following a MUL instruction on two unpacked BCD digits that leaves the result in the AX register. AL contains the MUL result, because it is always less than 100. AAM unpacks this result by dividing AL by 10, leaving the quotient (most significant digit) in AH and the remainder (least significant digit) in AL.

\subsubsection{Flags Affected}
F, ZF, and PF as described in Appendix A; OF, AF, and CF are undefined

\subsubsection{Exceptions by Mode}

Protected

None

Real Address

None

Virtual 8086

None

\subsection*{AAS}

ASCII Adjust AL after Subtraction

\begin{tabular}{l l l l}
Opcode & Instruction & Clocks & Description\\
3F & AAS & 4 & ASCII adjust AL after subtraction\\
\end{tabular}

\subsubsection{Operation}
\begin{verbatim}
IF (AL AND 0FH) > 9 OR AF = 1 THEN
  AL := AL - 6;
  AH := AH -1;
  AF := 1;
  CF := 1;
ELSE
  CF := 0;
  AF := 0;
ENDIF
AL := AL AND 0FH;
\end{verbatim}

\subsubsection{Discussion}
Code AAS only following a SUB instruction that leaves the byte result in the AL register. The lower nibbles of the SUB operands should be in the range 0 through 9 (BCD digits) so that AAS adjusts AL to contain the correct decimal digit result. If SUB produced a decimal carry, AAS decrements the AH register and sets the carry (CF) and auxiliary carry (AF) flags to 1. If SUB produced no decimal carry, AAS clears the carry and auxiliary carry flags (0) and leaves AH unchanged. In either case, AL is left with its upper nibble set to 0. To convert AL to an ASCII result, follow the AAS with OR AL, 30H.

\subsubsection{Flags Affected}

AF and CF as described in the Discussion section; OF, SF, ZF, and PF are undefined

\subsubsection{Exceptions by Mode}

\subsubsection{Protected}

None

\subsubsection{Real Address}

None

\subsubsection{Virtual 8086}

None


\chapter{Controlling the code generation}
Several options of the \faust compiler allow to control the generated C++ code. By default the computations are done sample by sample in a single loop. But the compiler can also generate \textit{vector} and \textit{parallel} code.

\section{Vector code generation}
Modern C++ compilers are able to do autovectorization, that is to use SIMD instructions to speedup the code. These instructions can typically operate in parallel on short vectors of 4 simple precision floating point numbers thus leading to a theoretical speedup of $\times4$.
Autovectorization of C/C++ programs is a difficult task. Current compilers are very sensitive to the way the code is arranged. In particular too complex loops can prevent autovectorization. The goal of the vector code generation is to rearrange the C++ code in a way that facilitates the autovectorization job of the C++ compiler. Instead of generating a single sample computation loop, it splits the computation into several simpler loops that communicates by vectors.

The vector code generation is activated by passing the \lstinline!--vectorize! (or \lstinline!-vec!) option to the \faust compiler. Two additional options are available:  \lstinline!--vec-size <n>! controls the size of the vector (by default 32 samples) and \lstinline!--loop-variant 0/1! gives some additional control on the loops.

To illustrate the difference between scalar code and vector code, let's take the computation of the RMS (Root Mean Square) value of a signal.  Here is the \faust code that computes the Root Mean Square of a sliding window of 1000 samples:
\label{rms}
\begin{lstlisting}
// Root Mean Square of n consecutive samples
RMS(n) = square : mean(n) : sqrt;

// Square of a signal
square(x) = x * x;

// Mean of n consecutive samples of a signal
// (uses fixpoint to avoid the accumulation of
// rounding errors)
mean(n) = float2fix : integrate(n) :
          fix2float : /(n);

// Sliding sum of n consecutive samples
integrate(n,x) = x - x@n : +~_;

// Convertion between float and fix point
float2fix(x) = int(x*(1<<20));
fix2float(x) = float(x)/(1<<20);

// Root Mean Square of 1000 consecutive samples
process = RMS(1000);
\end{lstlisting}

The compute() method generated in scalar mode is the following:

\begin{lstlisting}
virtual void compute (int count,
                      float** input,
                      float** output)
{
  float* input0 = input[0];
  float* output0 = output[0];
  for (int i=0; i<count; i++) {
    float fTemp0 = input0[i];
    int iTemp1 = int(1048576*fTemp0*fTemp0);
    iVec0[IOTA&1023] = iTemp1;
    iRec0[0] = ((iVec0[IOTA&1023] + iRec0[1])
                    - iVec0[(IOTA-1000)&1023]);
    output0[i] = sqrtf(9.536744e-10f *
                       float(iRec0[0]));
    // post processing
    iRec0[1] = iRec0[0];
    IOTA = IOTA+1;
  }
}
\end{lstlisting}

The \lstinline!-vec! option leads to the following reorganization of the code:
\begin{lstlisting}
virtual void compute (int fullcount,
                      float** input,
                      float** output)
{
  int iRec0_tmp[32+4];
  int* iRec0 = &iRec0_tmp[4];
  for (int index=0; index<fullcount; index+=32)
  {
    int count = min (32, fullcount-index);
    float* input0 = &input[0][index];
    float* output0 = &output[0][index];
    for (int i=0; i<4; i++)
      iRec0_tmp[i]=iRec0_perm[i];
    // SECTION : 1
    for (int i=0; i<count; i++) {
      iYec0[(iYec0_idx+i)&2047] =
               int(1048576*input0[i]*input0[i]);
    }
    // SECTION : 2
    for (int i=0; i<count; i++) {
      iRec0[i] = ((iYec0[i] + iRec0[i-1]) -
               iYec0[(iYec0_idx+i-1000)&2047]);
    }
    // SECTION : 3
    for (int i=0; i<count; i++) {
      output0[i] = sqrtf((9.536744e-10f *
                 float(iRec0[i])));
    }
    // SECTION : 4
    iYec0_idx = (iYec0_idx+count)&2047;
    for (int i=0; i<4; i++)
      iRec0_perm[i]=iRec0_tmp[count+i];
  }
}
\end{lstlisting}

While the second version of the code is more complex, it turns out to be much easier to vectorize efficiently by the C++ compiler. Using Intel icc 11.0, with the exact same compilation options: \texttt{-O3 -xHost -ftz -fno-alias -fp-model fast=2}, the scalar version leads to a throughput performance of 129.144  MB/s, while the vector version achieves 359.548  MB/s, a speedup of x2.8 !

\begin{figure}[htb]
  \centering
  \includegraphics[scale=0.75]{images/compiler-stack}
  \caption{\faust's stack of code generators}
  \label{fig:stack}
\end{figure}

The vector code generation is built on top of the scalar code generation (see figure \ref{fig:stack}). Every time an expression needs to be compiled, the compiler checks if it requires a separate loop or not. It applies some simple rules for that. Expressions that are shared (and are complex enough) are good candidates to be compiled in a separate loop, as well as recursive expressions and expressions used in delay lines.

The result is a directed graph in which each node is a computation loop (see Figure \ref{fig:loopgraph}). This graph is stored in the klass object and a topological sort is applied to it before printing the code.

\begin{figure}[htb]
  \centering
  \includegraphics[scale=0.75]{graphs/loopgraph2}
  \caption{The result of the -vec option is a directed acyclic graph (DAG) of small computation loops}
  \label{fig:loopgraph}
\end{figure}

\section{Parallel code generation}

The parallel code generation is activated by passing either the \lstinline!--openMP! (or \lstinline!-omp!) option or the \lstinline!--scheduler! (or \lstinline!-sch!) option. It implies the \lstinline!-vec! options as the parallel code generation is built on top of the vector code generation.

\subsection{The OpenMP code generator}

\begin{figure}[htb]
  \centering
  \includegraphics[scale=0.5,angle=-90]{images/openmp-model}
  \caption{OpenMP is based on a fork-join model}
  \label{fig:openmp}
\end{figure}

The \lstinline!--openMP! (or \lstinline!-omp!) option given to the \faust compiler will insert appropriate OpenMP directives in the C++ code. OpenMP (http://wwww.openmp.org) is a well established API that is used to explicitly define direct multi-threaded, shared memory parallelism. It is based on a fork-join model of parallelism (see figure \ref{fig:openmp}).
Parallel regions are delimited by \lstinline!#pragma omp parallel! constructs. At the entrance of a parallel region a team of parallel threads is activated. The code within a parallel region is executed by each thread of the parallel team until the end of the region.

\begin{lstlisting}
#pragma omp parallel
{
  // the code here is executed simultaneously by
  // every thread of the parallel team
  ...
}
\end{lstlisting}

In order not to have every thread doing redundantly the exact same work, OpemMP provides specific \textit{work-sharing} directives. For example \lstinline!#pragma omp sections! allows to break the work into separate, discrete sections, each section being executed by one thread:

\begin{lstlisting}
#pragma omp parallel
{
  #pragma omp sections
  {
    #pragma omp section
    {
      // job 1
    }
    #pragma omp section
    {
      // job 2
    }
    ...
  }

  ...
}
\end{lstlisting}

\subsection{Adding OpenMP directives}
As said before the parallel code generation is built on top of the vector code generation. The graph of loops produced by the vector code generator is topologically sorted in order to detect the loops that can be computed in parallel. The first set $S_0$ (loops $L1$, $L2$ and $L3$ in the DAG of Figure \ref{fig:loopgraph}) contains the loops that don't depend on any other loops, the set $S_1$ contains the loops that only depend on loops of $S_0$, (that is loops $L4$ and $L5$), etc..

As all the loops of a given set $S_n$ can be computed in parallel, the compiler will generate a \lstinline!sections! construct with a \lstinline!section! for each loop.
\begin{lstlisting}
  #pragma omp sections
  {
    #pragma omp section
    for (...) {
      // Loop 1
    }
    #pragma omp section
    for (...) {
      // Loop 2
    }
    ...
  }
\end{lstlisting}

If a given set contains only one loop, then the compiler checks to see if the loop can be parallelized (no recursive dependencies) or not. If it can be parallelized, it generates:
\begin{lstlisting}
  #pragma omp for
  for (...) {
   // Loop code
  }
\end{lstlisting}
otherwise it generates a \lstinline!single! construct so that only one thread will execute the loop:
\begin{lstlisting}
  #pragma omp single
  for (...) {
   // Loop code
  }
\end{lstlisting}

\subsection{Example of parallel OpenMP code}
To illustrate how \faust uses the OpenMP directives, here is a very simple example, two 1-pole filters in parallel connected to an adder (see figure \ref{fig:parfilter} the corresponding block-diagram):

\begin{lstlisting}
filter(c) = *(1-c) : + ~ *(c);
process = filter(0.9), filter(0.9) : +;
\end{lstlisting}

\begin{figure}[htb]
  \centering
  \includegraphics[width=8cm]{images/filter2}
  \caption{two filters in parallel connected to an adder}
  \label{fig:parfilter}
\end{figure}

The corresponding compute() method obtained using the \lstinline!-omp! option is the following:
\begin{lstlisting}

virtual void compute (int fullcount,
                      float** input,
                      float** output)
{
  float   fRec0_tmp[32+4];
  float   fRec1_tmp[32+4];
  float*  fRec0 = &fRec0_tmp[4];
  float*  fRec1 = &fRec1_tmp[4];
  #pragma omp parallel firstprivate(fRec0,fRec1)
  {
    for (int index = 0; index < fullcount;
                                index += 32)
    {
      int count = min (32, fullcount-index);
      float* input0 = &input[0][index];
      float* input1 = &input[1][index];
      float* output0 = &output[0][index];
      #pragma omp single
      {
        for (int i=0; i<4; i++)
          fRec0_tmp[i]=fRec0_perm[i];
        for (int i=0; i<4; i++)
          fRec1_tmp[i]=fRec1_perm[i];
      }
      // SECTION : 1
      #pragma omp sections
      {
        #pragma omp section
        for (int i=0; i<count; i++) {
          fRec0[i] = ((0.1f * input1[i])
                   + (0.9f * fRec0[i-1]));
        }
        #pragma omp section
        for (int i=0; i<count; i++) {
          fRec1[i] = ((0.1f * input0[i])
                   + (0.9f * fRec1[i-1]));
        }
      }
      // SECTION : 2
      #pragma omp for
      for (int i=0; i<count; i++) {
        output0[i] = (fRec1[i] + fRec0[i]);
      }
      // SECTION : 3
      #pragma omp single
      {
        for (int i=0; i<4; i++)
          fRec0_perm[i]=fRec0_tmp[count+i];
        for (int i=0; i<4; i++)
          fRec1_perm[i]=fRec1_tmp[count+i];
      }
    }
  }
}

\end{lstlisting}

This code requires some comments:

\begin{enumerate}
\item The parallel construct \lstinline!#pragma omp parallel! is the fundamental construct that starts parallel execution. The number of parallel threads is generally the number of CPU cores but it can be controlled in several ways.

\item Variables external to the parallel region are shared by default. The pragma \lstinline!firstprivate(fRec0,fRec1)! indicates that each thread should have its private copy of fRec0 and fRec1. The reason is that accessing shared variables requires an indirection and is quite inefficient compared to private copies.

\item The top level loop \lstinline!for (int index = 0;...)...! is executed by all threads simultaneously. The subsequent work-sharing directives inside the loop will indicate how the work must be shared between the threads.

\item Please note that an implied barrier exists at the end of each work-sharing region. All threads must have executed the barrier before any of them can continue.

\item The work-sharing directive \lstinline!#pragma omp single! indicates that this first section will be executed by only one thread (any of them).

\item The work-sharing directive \lstinline!#pragma omp sections! indicates that each corresponding \lstinline!#pragma omp section!, here our two filters, will be executed in parallel.

\item The loop construct \lstinline!#pragma omp for! specifies that the iterations of the associated loop will be executed in parallel. The iterations of the loop are distributed across the parallel threads. For example, if we have two threads, the first one can compute indices between 0 and count/2 and the other one between count/2 and count.

\item Finally \lstinline!#pragma omp single!  in section 3 indicates that this last section will be executed by only one thread (any of them).

\end{enumerate}

\subsection{The scheduler code generator}
 With the \lstinline!--scheduler! (or \lstinline!-sch!) option given to the \faust compiler, the computation graph is cut into separated computation loops (called "tasks"), and a "Work Stealing Scheduler" is used to activate and execute them following their dependencies. A pool of worked threads is created and each thread uses it's own local WSQ (Work Stealing Queue) of tasks. A WSQ is a special queue with a Push operation, a "private" LIFO Pop operation and a "public" FIFO Pop operation.

Starting from a ready task, each thread follows the dependencies, possibly pushing ready sub-tasks into it's own local WSQ. When no more tasks can be activated on a given computation path, the thread pops a task from it's local WSQ. If the WSQ is empty, then the thread is allowed to "steal" tasks from other threads WSQ.

The local LIFO Pop operation allows better cache locality and the FIFO steal Pop "larger chuck" of work to be done. The reason for this is that many work stealing workloads are divide-and-conquer in nature, stealing one of the oldest task implicitly also steals a (potentially) large subtree of computations that will unfold once that piece of work is stolen and run.

Compared to the OpenMP model (\lstinline!-omp!) the new model is worse for simple \faust  programs and usually starts to behave comparable or sometimes better for "complex enough" \faust  programs. In any case, since OpenMP does not behave so well with GCC compilers (only quite recent versions like GCC 4.4 start to show some improvements), and is unusable on OSX in real-time contexts, this new scheduler option has it's own value.  We plan to improve it adding a "pipelining" idea in the future.

\subsection{Example of parallel scheduler code}
To illustrate how \faust generates the scheduler code, here is a very simple example, two 1-pole filters in parallel connected to an adder (see figure \ref{fig:parfilter} the corresponding block-diagram):

\begin{lstlisting}
filter(c) = *(1-c) : + ~ *(c);
process = filter(0.9), filter(0.9) : +;
\end{lstlisting}

When \lstinline!-sch! option is used, the content of the additional \textit{architecture/scheduler.h} file is inserted in the generated code. It contains code to deal with WSQ and thread management. The \lstinline'compute()' and \lstinline'computeThread()' methods are the following:
\begin{lstlisting}

virtual void compute (int fullcount,
                      float** input,
                      float** output)
{
	GetRealTime();
	this->input = input;
	this->output = output;
	StartMeasure();
	for (fIndex = 0; fIndex < fullcount; fIndex += 32) {
		fFullCount = min (32, fullcount-fIndex);
		TaskQueue::Init();
		// Initialize end task
		fGraph.InitTask(1,1);
		// Only initialize tasks with inputs
		fGraph.InitTask(4,2);
		fIsFinished = false;
		fThreadPool.SignalAll(fDynamicNumThreads - 1);
		computeThread(0);
		while (!fThreadPool.IsFinished()) {}
	}
	StopMeasure(fStaticNumThreads,
		fDynamicNumThreads);
}
void computeThread (int cur_thread) {
	float* 	fRec0 = &fRec0_tmp[4];
	float* 	fRec1 = &fRec1_tmp[4];
	// Init graph state
	{
		TaskQueue taskqueue;
		int tasknum = -1;
		int count = fFullCount;
		// Init input and output
		FAUSTFLOAT* input0 = &input[0][fIndex];
		FAUSTFLOAT* input1 = &input[1][fIndex];
		FAUSTFLOAT* output0 = &output[0][fIndex];
		int task_list_size = 2;
		int task_list[2] = {2,3};
		taskqueue.InitTaskList(task_list_size, task_list, fDynamicNumThreads, cur_thread, tasknum);
		while (!fIsFinished) {
			switch (tasknum) {
				case WORK_STEALING_INDEX: {
					tasknum = TaskQueue::GetNextTask(cur_thread);
					break;
				}
				case LAST_TASK_INDEX: {
					fIsFinished = true;
					break;
				}
				// SECTION : 1
				case 2: {
					// LOOP 0x101111680
					// pre processing
					for (int i=0; i<4; i++) fRec0_tmp[i]=fRec0_perm[i];
					// exec code
					for (int i=0; i<count; i++) {
						fRec0[i] = ((1.000000e-01f * (float)input1[i]) + (0.9f * fRec0[i-1]));
					}
					// post processing
					for (int i=0; i<4; i++) fRec0_perm[i]=fRec0_tmp[count+i];

					fGraph.ActivateOneOutputTask(taskqueue, 4, tasknum);
					break;
				}
				case 3: {
					// LOOP 0x1011125e0
					// pre processing
					for (int i=0; i<4; i++) fRec1_tmp[i]=fRec1_perm[i];
					// exec code
					for (int i=0; i<count; i++) {
						fRec1[i] = ((1.000000e-01f * (float)input0[i]) + (0.9f * fRec1[i-1]));
					}
					// post processing
					for (int i=0; i<4; i++) fRec1_perm[i]=fRec1_tmp[count+i];

					fGraph.ActivateOneOutputTask(taskqueue, 4, tasknum);
					break;
				}
				case 4: {
					// LOOP 0x101111580
					// exec code
					for (int i=0; i<count; i++) {
						output0[i] = (FAUSTFLOAT)(fRec1[i] + fRec0[i]);
					}

					tasknum = LAST_TASK_INDEX;
					break;
				}
			}
		}
	}
}

\end{lstlisting}