\subsection{Boltzmann Machine}

% --- Lucas

\begin{figure}[htbp]
	\begin{center}
		\includegraphics[width=0.5\textwidth]{inc/boltzmann_machine.png}
		\caption{Illustration of a Boltzmann Machine. The blue units represents three hidden units, while the four white units represents four visible units.\protect\footnotemark}
		\label{fig:boltzmann_machine}
	\end{center}
\end{figure}
\footnotetext{Original image (Public Domain): \url{https://en.wikipedia.org/wiki/File:Boltzmannexamplev1.png}}

The ``Boltzmann Machine'' (BM) is a form of ``parallel constraint satisfaction network'' \cite{ackley1985learning}. It is capable of learning the underlying constraints of a domain by only being shown examples of it. The BM is composed of units (also known as nodes) forming a complete graph where the connection between two units are symmetric; meaning that the weight on the connection is the same in either direction. No unit has a connection to itself. The units are binary, in the meaning that they can only assume one of two states, on or off. The state of a unit is determined by a probabilistic function based on the states of the units neighbours. A strong connection (high weight value) between two units indicates that if either of these two units are active, the other one should probably be active as well. While a weak connection (low weight value) indicates that these should probably not be active at the same time. This is analogous to Hebbian learning.

The BM is notably similar to the Hopfield network in that it also defines a global energy state of the system, utilizing the same equation that determines the global energy value. Each global state can be identified by the energy of the system in that state. By forcing the values of the visible units to represent a training set the system attempts to find an energy configuration that is compatible with the given input. The resulting energy state can then be interpreted as to how well the given data fulfils the constraints of the domain. Thus by minimizing the energy the system learns an interpretation of the problem that increasingly satisfies the constraints of the domain.

The simplest way to minimize the energy into a local minimum of the system is to change each units state into a value that results in a lower energy state. The data needed to determine this change is locally accessible to each unit, and is dependent on the current state of the units neighbours. If the sum of all values for a given units neighbour exceeds the threshold of that unit, the resulting state of the unit should be on. Otherwise it should be off. This is the usual algorithm for binary units.

Because of this deterministic algorithm it suffers from the usual weaknesses of gradient descent algorithms, namely, it gets stuck in local minima if its initial state is close to one. In order to alleviate the algorithm of this problem, noise is introduced in the training. This allows the network to ``jump'' out of these minima into configurations of higher energy. The algorithm used for noise introduction is a variation of the ``Metropolis algorithm'' \cite{metropolis1953equation} that was used to study thermodynamic systems. This modified version introduces a concept of temperature to the machine, which then tries to reach ``thermal equilibrium'' during training. Meaning that the machine is allowed to run repeatedly until the global energy of the system converges to a fixed state over a temperature that is initially high and then slowly decreased over the runtime of the system. The probability of finding the system in a global state after it has reached thermal equilibrium follows a Boltzmann distribution. If the temperature feed into the machine is equal to zero the stochastic nature of it is removed, the machine becomes deterministic and can be seen as a regular Hopfield network.

%TODO discuss the usage of Hebbian learning in Boltzmann
%TODO write more about this temperature thing
%TODO write more about the probabilistic features of the BM as well as the Boltzmann distribution that gives the system its name.

Training is conducted in two phases, in the first phase the visible units of the machine are set to the values of the training set. In the next phase the machine is allowed to run freely, independent of the training set. The machine is iteratively switched between these two phases for the duration of the training until it reaches thermal equilibrium. The goal of the training is for the machine to be able to generate the input vector with a high probability of success.

% --- NOTES
%The difference between the BM and the Hopfield network is mainly that the nodes (or units as they are referred to in the original paper) of the Boltzmann Machine are stochastic by nature.
%The BM can be used for constraint satisfaction problems that involve a large amount of weak constraints.


\input{preamble}

\begin{document}

\header{1}{Volumetric Path Tracing}

\begin{figure}[h]
    \includegraphics[width=\linewidth]{imgs/colored_smoke.png}
    \caption{A heterogeneous volume with spectrally varying density over space, rendered with multiple-scattering. Smoke data generated using Wenzel Jakob's \href{http://www.mitsuba-renderer.org/misc.html}{fsolver}.}
    \label{fig:gallery}
\end{figure}

In this homework, we will build a volumetric path tracers that can handle scattering and absorption inside participating media inside lajolla. We will split the development into 6 steps and build 6 volumetric path tracers, each has more features than the previous ones.\footnote{This approach is inspired by Steve Marschner's \href{https://www.cs.cornell.edu/courses/cs6630/2015fa/notes/10volpath.pdf}{course note} on volumetric path tracing.} Your $n$-th volumetric path tracer should be able to render all scenes the $(n-1)$-th one can handle. If you want, you can only submit the final volumetric path tracer and let all the rest call the final code. This process is for helping you to slowly and steadily build up your rendering algorithm.

Participating media are volumes with many infinitesimal particles absorbing and scattering lights. Given a ray inside the volume parametrized by distance $\mathbf{p}(t)$, the radiance along the ray is modelled by the \emph{radiative transfer equation}:
\begin{equation}
\frac{\mathrm{d}}{\mathrm{d}t} L(\mathbf{p}(t), \omega) = -(\sigma_a(\mathbf{p}(t)) + \sigma_s(\mathbf{p}(t))) L(\mathbf{p}(t), \omega) + \sigma_a L_e(\mathbf{p}(t), \omega) + \sigma_s(\mathbf{p}(t)) \int_{S^2} \rho(\mathbf{p}(t), \omega, \omega') L(\mathbf{p}(t), \omega') \mathrm{d}\omega',
\label{eq:rte}
\end{equation}
where $L$ is the radiance, $\sigma_a$ is the \emph{absorption coefficient}, $\sigma_s$ is the \emph{scattering coefficient}, $L_e$ is the (volumetric) emission, $\rho$ is the \emph{phase function} that is skin to BSDF in surface rendering, and $S^2$ is the spherical domain.

This looks a bit scary, so let's break it down. From now on we'll drop the arguments for $\sigma_a$ and $\sigma_s$, but in general they can still be spatially varying. The radiative transfer equation is made of four components: \textbf{absorption}, \textbf{emission}, \textbf{in-scattering}, and \textbf{out-scattering}. Absorption and emission handles particles that absorb and emit lights:
\begin{equation}
\frac{\mathrm{d}}{\mathrm{d}t} L_a(\mathbf{p}(t), \omega) = -\sigma_a L_a(\mathbf{p}(t), \omega) + \sigma_a L_e(\mathbf{p}(t), \omega).
\end{equation}
Notice how this is just a simple linear ordinary differential equation $x' = ax + b$, where $\sigma_a$ attenuates lights and $L_e$ is the gain.

The in-scattering accounts for all the lights bounces between the particles along the ray, just like the surface rendering equation:
\begin{equation}
\frac{\mathrm{d}}{\mathrm{d}t} L_{is}(\mathbf{p}(t), \omega) = \sigma_s \int_{S^2} \rho(\mathbf{p}(t), \omega, \omega') L(\mathbf{p}(t), \omega') \mathrm{d}\omega'.
\end{equation}

However, the light does not just bounce \emph{into} the ray, it also bounces \emph{out}. That's what the out-scattering considers:
\begin{equation}
\frac{\mathrm{d}}{\mathrm{d}t} L_{os}(\mathbf{p}(t), \omega) = -\sigma_s L_{os}(\mathbf{p}(t)).
\end{equation}

Combining all these three components, we get the full radiative transfer equation (Equation~\ref{eq:rte}). Notice that the full radiative transfer equation is also like a linear ODE: $-(\sigma_a + \sigma_s) L$ attenuates light, and $L_e$ and the spherical integral are the gain that makes things brighter. For this reason, we often let $\sigma_t = \sigma_a + \sigma_s$ and call it the \emph{extinction coefficient}.

We'll start from a very simplified version of the radiative transfer equation, then slowly handle more complex situations. To make things simpler, we will throughout assume our medium does not emit light itself: it will receive lighting from other surfaces in the scene.

Before that, let's introduce lajolla's data structures for storing the participating media.

\section{Lajolla's participating media data structures and interfaces}
\begin{figure}
    \includegraphics[width=\linewidth]{imgs/media.pdf}
    \caption{Lajolla assumes that media are separated by closed surface boundaries. At the object surface, we store the ID of the interior and exterior media (if either of them is vaccum, set the ID to \lstinline{-1}). The outmost medium is specified at the camera (and can be accessed through \lstinline{camera.medium_id}). A surface can be \emph{index-matching} meaning that light just pass through without changing direction or losing energy. In this case, the \lstinline{material_id} of the surface is set to \lstinline{-1}. A surface can also be transmissive. In this case, it is assigned a transmissive material like \lstinline{roughdielectric}.}
    \label{fig:data_structure}
\end{figure}

\paragraph{The Medium struct in lajolla.} Lajolla's medium interface is for querying the media parameters $\sigma_a$, $\sigma_s$, phase function $\rho$, and the \emph{majorant} which is the upper bound of the extinction coefficient $\sigma_t = \sigma_a + \sigma_s$ -- we will need the majorant in our final renderer.
\begin{lstlisting}[language=c++]
struct MediumBase {
    PhaseFunction phase_function;
};

struct HomogeneousMedium : public MediumBase {
    Spectrum sigma_a, sigma_s;
};

struct HeterogeneousMedium : public MediumBase {
    VolumeSpectrum albedo, density;
};

using Medium = std::variant<HomogeneousMedium, HeterogeneousMedium>;

/// the maximum of sigma_t = sigma_s + sigma_a over the whole space
Spectrum get_majorant(const Medium &medium, const Ray &ray);
Spectrum get_sigma_s(const Medium &medium, const Vector3 &p);
Spectrum get_sigma_a(const Medium &medium, const Vector3 &p);

inline PhaseFunction get_phase_function(const Medium &medium) {
    return std::visit([&](const auto &m) { return m.phase_function; }, medium);
}
\end{lstlisting}
You will need these functions to obtain the necessary quantities in the homeworks.

A \lstinline{HomogeneousMedium} should be straightforward: it contains constant $\sigma_a$ and $\sigma_s$.
We will talk more about \lstinline{HeterogeneousMedium} and \lstinline{PhaseFunction} later.

Lajolla assumes that the media are separated by surface boundaries (Figure~\ref{fig:data_structure}). It's up to the upstream user to make sure they are consistent to each other and the surfaces are closed (if they are not, the results are undefined).\footnote{Modern production volume renderers have paid special attention to make sure the renderers can handle all sorts of inputs, including nested volumes. See \href{here}{https://graphics.pixar.com/library/ProductionVolumeRendering/index.html} for more information.}

In the scene file, each objects are marked with corresponding exterior and interior media:
\begin{lstlisting}[language=xml]
    <medium type="homogeneous" id="medium">
        <rgb name="sigmaA" value="0.5 0.5 0.5"/>
        <rgb name="sigmaS" value="0.0 0.0 0.0"/>
        <float name="scale" value="3"/>
    </medium>

    <shape type="sphere">
        <!-- ...  -->
        <ref name="exterior" id="medium"/>
    </shape>

    <sensor type="perspective">
        <!-- ... -->

        <ref id="medium"/>
    </sensor>
\end{lstlisting}

The \lstinline{Medium}s are stored in \lstinline{scene.media} which you can access through \lstinline{scene.media[medium_id]}. The \lstinline{intersection} routine in lajolla returns a \lstinline{PathVertex} object which contains relevant information of the intersection:
\begin{lstlisting}[language=c++]
struct PathVertex {
    Vector3 position;
    Vector3 geometry_normal;
    // ...
    int shape_id = -1;
    int primitive_id = -1; // For triangle meshes. This indicates which triangle it hits.
    int material_id = -1;

    // If the path vertex is inside a medium, these two IDs
    // are the same.
    int interior_medium_id = -1;
    int exterior_medium_id = -1;
};
\end{lstlisting}

\section{Single absorption-only homogeneous volume}
\begin{figure}
\includegraphics[width=\linewidth]{imgs/absorption_medium.pdf}
\caption{The setup of our first volumetric renderer.}
\label{fig:volpath1_illustration}
\end{figure}
\begin{figure}
\caption{Our first volume rendering.}
\label{fig:volpath1}
\end{figure}

Our first volume renderer will make four assumptions:
\begin{itemize}
    \item There is only a single, homogeneous ($\sigma_a$ and $\sigma_s$ are constants over space) volume.
    \item The volume does not scatter light: $\sigma_s = 0$.
    \item The surfaces in the scene only emit lights (with intensity $L_e$) and do not reflect/transmit lights.
\end{itemize}

Under these assumptions, the radiative transfer equation becomes
\begin{equation}
\frac{\mathrm{d}}{\mathrm{d}t} L_a(\mathbf{p}(t), \omega) = -\sigma_a L_a(\mathbf{p}(t), \omega),
\end{equation}
and we know $L_a(\mathbf{p}(t_{\text{hit}}), \omega) = L_e$ where $t_{\text{hit}}$ is the distance between the origin of the ray and the emissive surface.

This ordinary differential equation has a simple closed form:
\begin{equation}
L_a(\mathbf{p}(0), \omega) = \exp\left(-\sigma_a t_{\text{hit}} \right) L_e.
\end{equation}
Figure~\ref{fig:volpath1_illustration} illustrates the setup. In volume rendering the exponential term
$\exp\left(-\sigma_a t_{\text{hit}} \right)$ is often called the ``transmittance''.

Our rendering algorithm is as follows (in Python-style pseudo code).
\begin{lstlisting}[language=python]
def L(screen_pos):
  camera_ray = sample_primary(camera, screen_pos)
  isect = intersect(scene, camera_ray)
  if isect:
    transmittance = exp(-sigma_a * t)
    Le = 0
    if is_light(isect):
      Le = isect.Le
    return transmittance * Le
  return 0
\end{lstlisting}

\paragraph{Task (15\%).} You will implement the algorithm above in the \lstinline{vol_path_tracing_1} function in \lstinline{vol_path_tracing.h}. You might want to first look at the surface path tracing code in \lstinline{path_tracing.h} to understand lajolla's API better.

\end{document}


\section{Introduction}

I was lately thinking about fixed points, more or less.

A new version of
\href{https://hackage.haskell.org/package/data-fix}{\texttt{data-fix}}
was released recently, and also corresponding version
of \href{https://hackage.haskell.org/package/recursion-schemes}{\texttt{recursion-schemes}}.

Also I wrote a \href{https://www.well-typed.com/blog/2020/06/fix-ing-regular-expressions/}{Fix-ing regular expressions} post,
about adding fixed points to regular expression.

This post is another exploration: \emph{Fixed points of Indexed functors}.
This is not novel idea at all,
but I'm positively surprised this works out quite nicely in modern GHC Haskell.
I define a |IxFix| type and illustrate it with three examples.

\emph{Note:} The
\href{https://hackage.haskell.org/package/multirec-0.7.9/docs/Generics-MultiRec-HFix.html}{|HFix| in \texttt{multirec} package} is the same as |IxFix|
in this post. I always forget about the existence of \texttt{multirec}.

In the following, the "modern GHC Haskell" is quite conservative,
only eight extensions:

\begin{code}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
\end{code}

And this literate Haskell script is warning free, with \texttt{-Wall}
\begin{code}
{-# OPTIONS_GHC -Wall #-}
\end{code}

On this trip
\begin{code}
module IxFix where
\end{code}

we need a handful of imports

\begin{code}
-- Type should be added to Prelude
import Data.Kind (Type)

-- Few newtypes
import Data.Functor.Identity (Identity (..))
import Data.Functor.Compose (Compose (..))
import Data.Functor.Const (Const (..))

-- dependently typed programming!
import Data.Fin      (Fin)
import Data.Type.Nat
import Data.Vec.Lazy (Vec (..))

-- magic
import Data.Coerce (coerce)
\end{code}

Before we go further, let me remind you about ordinary fixed points,
as defined in
\href{https://hackage.haskell.org/package/data-fix}{\texttt{data-fix}}
package.

\begin{code}
newtype Fix f = Fix { unFix :: f (Fix f) }

foldFix :: Functor f => (f a -> a) -> Fix f -> a
foldFix f = go where go = f . fmap go . unFix
\end{code}

Using |Fix| we can define recursive types using non-recursive \emph{base functors},
e.g. for a list we'd have

\begin{code}
data ListF a rec = NilF | ConsF a rec
\end{code}

We then use |foldFix| (or |cata| and other recursion schemes in \texttt{recursion-schemes}) to
decouple "how we recurse" and "what we do at each step".
I won't try to convince you why this separation of concerns might be useful.

Instead I continue directly to the topic: define indexed fixed points.
Why we need them? Because |Fix| is not powerful enough to allow
working with |Vec| or polymorphically recursive types.

\begin{code}
-- hello dependently typed world.
data Vec (n :: Nat) (a :: Type) where
    VNil  :: Vec 'Z a
    (:::) :: a -> Vec n a -> Vec ('S n) a
\end{code}

\section{Fixed points of indexed functors}

Before talking about fixed points, we need to figure out what
are indexed functors. Recall a normal functor
is a thing of kind |Type -> Type|:

\begin{code}
class Functor f where
    fmap :: (a -> b) -> (f a -> f b)
\end{code}

Indexed version is the one with |Type| replaced with |k -> Type|,
for some index |k| (it is still a functor, but in different category).
We want morphisms to work for all indices,
and preserve them. Thus we define a commonly used type alias\footnote{I'm sorry that tilde |~>| and dash |->| arrows look so similar.}
\begin{code}
-- natural, or parametric, transformation
type f ~> g = forall (j :: k). f j -> g j
\end{code}
Using it we can define a |Functor| variant\footnote{
Note that |FFunctor| in \url{https://hackage.haskell.org/package/hkd-0.1/docs/Data-HKD.html} (which is defined with different names in other packages as well)
is of different kind.
|IxFunctor| in \url{https://hackage.haskell.org/package/indexed-0.1.3/docs/Data-Functor-Indexed.html}
is again different.
Sorry for proliferation of various functors.
And for confusing terminology.
Dominic Orchard et al uses terms graded (|k -> Type|, this post) and parameterised (|k -> k -> Type|, \texttt{indexed}-package) in \url{https://arxiv.org/abs/2001.10274v2}.
There is no monad-name for \texttt{hkd}-package variant, as that cannot be made into monad-like thing.
}:
it looks almost the same.
\begin{code}
class IxFunctor (f :: (k -> Type) -> (k -> Type)) where
    ixmap :: (a ~> b) -> (f a ~> f b)
\end{code}

With |IxFunctor| in our toolbox, we can define an |IxFix|,
note how the definition is again almost the same as for unindexed |Fix| and |foldFix|:
\begin{code}
newtype IxFix f i = IxFix { unIxFix :: f (IxFix f) i }

foldIxFix :: IxFunctor f => (f g ~> g) -> IxFix f ~> g
foldIxFix alg = alg . ixmap (foldIxFix alg) . unIxFix
\end{code}

Does this work?
I hope that following examples will convince that |IxFix|
is usable (at least in theory).

\section{Example: length indexed lists, Vec}

The go to example of recursion schemes is a folding a list,
The go to example of dependent types is length indexed list, often called |Vec|.
I combine these traditions by defining |Vec| as an indexed fixed point:

\begin{code}
data VecF (a :: Type) rec (n :: Nat) where
    NilF  ::               VecF a rec 'Z
    ConsF :: a -> rec n -> VecF a rec ('S n)
\end{code}

|VecF| is an |IxFunctor|:

\begin{code}
instance IxFunctor (VecF a) where
    ixmap _ NilF         = NilF
    ixmap f (ConsF x xs) = ConsF x (f xs)
\end{code}

And we can define |Vec| as fixed point of |VecF|, with constructors:

\begin{code}
type Vec' a n = IxFix (VecF a) n

nil :: Vec' a 'Z
nil = IxFix NilF

cons :: a -> Vec' a n -> Vec' a ('S n)
cons x xs = IxFix (ConsF x xs)
\end{code}

Can we actually use it? Of course!
Lets define concatenation\footnote{You may wonder why function name is |append|, but operation is concatenation? This is similar to having |plus| for addition.}
|Vec' a n -> Vec' a m -> Vec' a (Plus n m)|.
We cannot use |foldIxFix| directly, as |Plus n m| is not the same
index as |n|, so we need to define an auxiliary |newtype|
to plumb the indices. Another way to think about these kind of |newtype|s,
is that they work around the lack of type-level anonymous functions in nowadays Haskell.

\begin{code}
newtype Appended m a n =
    Append { getAppended :: Vec' a m -> Vec' a (Plus n m) }
\end{code}

\begin{code}
append :: forall a n m. Vec' a n -> Vec' a m -> Vec' a (Plus n m)
append xs ys = getAppended (foldIxFix alg xs) ys where
    alg :: VecF a (Appended m a) j -> Appended m a j
    alg NilF          = Append id
    alg (ConsF x rec) = Append $ \zs -> cons x (getAppended rec zs)
\end{code}

We can also define a refold function, which doesn't mention
|IxFix| at all.

\begin{code}
ixrefold :: IxFunctor f => (f b ~> b) -> (a ~> f a) -> a ~> b
ixrefold f g = f . ixmap (ixrefold f g) . g
\end{code}

And then, using |ixrefold| we can define concatenation for |Vec| from
\href{https://hackage.haskell.org/package/vec}{\texttt{vec}} package,
which isn't defined using |IxFix|.
Here we need auxiliary |newtype|s as well.

\begin{code}
newtype Swapped f a b =
    Swap { getSwapped :: f b a }
newtype Appended2 m a n =
    Append2 { getAppended2  :: Vec m a -> Vec (Plus n m) a }

append2 :: forall a n m. Vec n a -> Vec m a -> Vec (Plus n m) a
append2 xs ys = getAppended2 (ixrefold f g (Swap xs)) ys where
    -- same as alg in 'append'
    f :: VecF a (Appended2 m a) j -> Appended2 m a j
    f NilF          = Append2 id
    f (ConsF z rec) = Append2 $ \zs -> z :::  (getAppended2 rec zs)

    -- 'project'
    g :: Swapped Vec a j -> VecF a (Swapped Vec a) j
    g (Swap VNil)       = NilF
    g (Swap (z ::: zs)) = ConsF z (Swap zs)
\end{code}

You may note that one can implement |append| as induction over length,
that's how |vec| implements them.
Theoretically it is not right, and |IxFix| formulation highlights it:

\begin{code}
append3 :: forall a n m. SNatI n
        => Vec' a n -> Vec' a m -> Vec' a (Plus n m)
append3 xs ys = getAppended3 (induction caseZ caseS) xs where
    caseZ :: Appended3 m a 'Z
    caseZ = Append3 (\_ -> ys)

    caseS :: Appended3 m a p -> Appended3 m a ('S p)
    caseS rec = Append3 $ \(IxFix (ConsF z zs)) ->
        cons z (getAppended3 rec zs)

-- Note: this is different than Appended!
newtype Appended3 m a n =
    Append3 { getAppended3 :: Vec' a n -> Vec' a (Plus n m) }
\end{code}

Here we \emph{pattern match} on |IxFix| value.
If we want to treat it as least fixed point, the only valid elimination
is to use |foldIxFix|!

However, the induction over length is the right approach if |Vec| is defined
as a data or type family:

\begin{code}
type family VecFam (a :: Type) (n :: Nat) :: Type where
    VecFam a 'Z     = ()
    VecFam a ('S n) = (a, VecFam a n)
\end{code}

Whether you want to have data or type-family or GADT depends on the application.
(Even in Agda or Coq). Family variant doesn't intristically know its length,
which is sometimes a blessing, sometimes a curse.
For what it's worth, \texttt{vec} package provides both variants,
with almost the same module interface.

\section{Example: Polymorphically recursive type}

The |IxFix| can also be used to define polymorphically recursive types like

\begin{code}
data Nested a = a :<: (Nested [a]) | Epsilon
infixr 5 :<:

nested :: Nested Int
nested = 1 :<: [2,3,4] :<: [[5,6],[7],[8,9]] :<: Epsilon
\end{code}

A length function defined over this datatype will be polymorphically recursive,
as the type of the argument changes from Nested a to Nested [a] in the recursive call:

\begin{code}
-- >>> nestedLength nested
-- 3
nestedLength :: Nested a -> Int
nestedLength Epsilon    = 0
nestedLength (_ :<: xs) = 1 + nestedLength xs
\end{code}

We cannot represent |Nested| as |Fix| of some functor,
and we can not use \texttt{recursion-schemes} either.
However, we can redefine |Nested| as indexed fixed point.

An important observation is that we (often or always?) use polymorphic recursion
as a solution to the lack indexed types.
My favorite example is de Bruijn indices for well-scoped terms.
Compare
\begin{code}
data Expr1 a
    = Var1 a
    | App1 (Expr1 a) (Expr1 a)
    | Abs1 (Expr1 (Maybe a))
\end{code}
and
\begin{code}
data Expr2 a n
    = Free2 a                -- split free and bound variables
    | Bound2 (Fin n)
    | App2 (Expr2 a n) (Expr2 a n)
    | Abs2 (Expr2 a ('S n))  -- extend bound context by one
\end{code}
Which one is \emph{simpler} is a really good discussion,
but for another time.

In |Nested| example the single argument is also used for two
purposes: the type of an base element (|Int|) and container type
(starts with |Identity| and increases with extra list layer).

One approach is just use |Nat| index and have a type family%
\footnote{Here one starts to wish that GHC had unsaturated type families, so we wouldn't need to use newtypes...}
\begin{code}
type family Container (n :: Nat) :: Type -> Type where
    Container 'Z     = Identity
    Container ('S n) = Compose [] (Container n)
\end{code}

or

\begin{code}
data NestedF a rec f
    = f a :<<: rec (Compose [] f)
    | EpsilonF

instance IxFunctor (NestedF a) where
    ixmap _ EpsilonF    = EpsilonF
    ixmap f (x :<<: xs) = x :<<: f xs
\end{code}

We can convert from |Nested a| to |IxFix (NestedF a) Identity| and back.
We use |coerce| to help with |newtype| plumbing.

\begin{code}
convert :: Nested a -> IxFix (NestedF a) Identity
convert = aux . coerce where
    aux :: Nested (f a) -> IxFix (NestedF a) f
    aux Epsilon    = IxFix EpsilonF
    aux (x :<: xs) = IxFix (x :<<: aux (coerce xs))

-- back left as an exercise
\end{code}

And then we can write |nestedLength| as a fold.

\begin{code}
-- >>> nestedLength2 (convert nested)
-- 3
nestedLength2 :: IxFix (NestedF a) f -> Int
nestedLength2 = getConst . foldIxFix alg where
    alg :: NestedF a (Const Int) ~> Const Int
    alg EpsilonF         = Const 0
    alg (_ :<<: Const n) = Const (n + 1)
\end{code}

\section{Non-example: ListF}

In the introduction I mentioned an ordinary list, which is a fixed point

\begin{align*}
  \mathsf{List} \coloneqq \lambda (A : \mathsf{Type}).\; \mu (r : \mathsf{Type}).\; 1 + A \times r
\end{align*}

where I use $\mu (r : X).\, F\, r$ notation to represent least fixed points:
$\mu (r : X). F\, r \cong F\, (\mu (r : X). F\, r)$.
Note that we first introduce a type parameter $A$ with $\lambda$, and then make
a fixed point with $\mu$.

We can define an ordirinary list using |IxFix|,
by taking a fixed point of a |Type -> Type| thing,
i.e. first $\mu$, and then $\lambda$.

\begin{align*}
  \mathsf{List}_1 \coloneqq \mu (r : \mathsf{Type} \to \mathsf{Type}).\; \lambda (A : \mathsf{Type}).\; 1 + A \times r\,A
\end{align*}

\begin{code}
data ListF1 rec a = NilF1 | ConsF1 a (rec a)
type List1 = IxFix ListF1

fromList1 :: [a] -> List1 a
fromList1 []     = IxFix NilF1
fromList1 (x:xs) = IxFix (ConsF1 x (fromList1 xs))
\end{code}

Compare to Agda code:

\begin{code}
-- parameter
data List (A : Set) : Set where
    nil  : List A
    cons : A -> List A -> List A

-- index
data List : Set -> Set where
    nil :  (A : Set) -> List A
    cons : (A : Set) -> A -> List A -> List A
\end{code}

These types are subtly different.
See \url{https://stackoverflow.com/questions/24600256/difference-between-type-parameters-and-indices}.

This gives a hint why |Agda| people define |Vec (A : Set) : Nat -> Set|,
i.e. length as the last parameter: because you have to do that way.
And Haskellers (usually) define as |Vec (n :: Nat) (a :: Type)|,
because then |Vec| can be given |Functor| etc instances.
In other words, machinery in both languages forces an order of
of type arguments.

Finally, we can write parametric version of |List| using
|IxFix| too. We just use a dummy, boring index.

\begin{align*}
  \mathsf{List}_2 \coloneqq
  \lambda (A : \mathsf{Type}).\;
  \mu (r : 1 \to \mathsf{Type}).\;
  \lambda (x : 1).\;
  1 + A \times r\,x
\end{align*}

\begin{code}
data ListF2 a rec (unused :: ()) = NilF2 | ConsF2 a (rec unused)
type List2 a = IxFix (ListF2 a) '()

fromList2 :: [a] -> List2 a
fromList2 []     = IxFix NilF2
fromList2 (x:xs) = IxFix (ConsF2 x (fromList2 xs))
\end{code}

|IxFix| is more general than |Fix|, but if you don't need
an extra power, maybe you shouldn't use it.

Do we need something even more powerful than |IxFix|?
I don't think so. If we need more (dependent) indices, we can pack them all into
a single index by tupling (or $\sum$-mming) them.

\section{Conclusion}

We have seen |IxFix|, fixed point of indexed functor.
I honestly do not think that you should start looking in your code base whether you can use it.
I suspect it is more useful as thinking and experimentation tool.
It is an interesting gadget.


\documentclass[24pt, a4]{article}
% To compile latex inside of vim
% ! clear; pdlatex name_of_file.tex or "%"

% \usepackage[utf8]{inputenc}
\usepackage[parfill]{parskip}
\usepackage{listings}
\usepackage{geometry}

\title{Linked List}
\author{Mustafa Muhammad}
\date{12th November 2021}

\begin{document}

\maketitle

Checkout the other common questions like validating brackets as well ......
\section{Two sum}
Find index of two numbers that add upto the target sum
\begin{lstlisting}
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hash_map = {}
        for i in range(0, len(nums)):
            targ = target - nums[i]
            if targ in hash_map:
                return hash_map[targ], i
            else:
                hash_map[nums[i]] = i

        return -1,-1
\end{lstlisting}

\section{Best Time to Buy and Sell Stock}
Simple 1 pass through an array
Bane of my existance
\begin{lstlisting}
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        profit = 0
        buy = float('inf')
        for i in range(0, len(prices)):
            buy = min(prices[i], buy)
            profit = max(profit, prices[i]-buy)

        return profit
\end{lstlisting}
\section{Contains Duplicate}
\begin{lstlisting}
class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        dup = set()
        for i in range(0, len(nums)):
            if nums[i] in dup:
                return True
            else:
                dup.add(nums[i])
        return False
\end{lstlisting}
\section{Maximum Subarray}
\begin{lstlisting}
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        #Kadane's algorithm repeated work
        maxSum = nums[0]
        currSum = 0
        for i in range(0, len(nums)):
            if currSum<0:
                currSum = 0
            currSum += nums[i]
            maxSum = max(maxSum, currSum)

        return maxSum
\end{lstlisting}
\section{Maximum Product Subarray}
\begin{lstlisting}
class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        #Kadane's algorithm
        res = max(nums)
        curr_max = 1
        curr_min = 1

        for i in range(0, len(nums)):
            #Edge case, if 0 zero it makes eveything after it zero.
            if nums[i] == 0:
                curr_max = 1
                curr_min = 1
                continue

            temp = curr_max
            curr_max = max(nums[i]*curr_max, curr_min*nums[i], nums[i])
            curr_min = min(curr_min*nums[i], temp*nums[i], nums[i])

            res = max(res, curr_max)
        return res
\end{lstlisting}
\section{Product of Array except self}
Input: nums = [1,2,3,4]
Output: [24,12,8,6]

Do it in 0(1) without extra space
\begin{lstlisting}
class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        res = [1] * len(nums)
        prefix = 1
        for i in range(0, len(nums)):
            res[i] = prefix
            prefix *= nums[i]

        postfix = 1
        for j in range(len(nums)-1, -1, -1):
            res[j] *= postfix
            postfix *= nums[j]

        return res
\end{lstlisting}
\section{Find array in rotated sorted array}
\begin{lstlisting}
class Solution:
    def findMin(self, nums: List[int]) -> int:
        # binary search
        left = 0
        right = len(nums)-1

        while left <= right:
            if nums[left] <= nums[right]:
                return nums[left]

            mid = int(left + (right - left)/2)

            next = (mid+1) % len(nums)
            prev = (mid-1+len(nums)) % len(nums)

            if nums[mid] <= nums[prev] and nums[mid] <= nums[next]:
                return nums[mid]

            elif nums[left] <= nums[mid]:
                left = mid + 1

            elif nums[mid] <= nums[right]:
                right = mid -1
        return -1
\end{lstlisting}
\section{Search in a rotated sorted array}
\begin{lstlisting}
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        def find_index(nums):
            left = 0
            right = len(nums)-1
            n = len(nums)

            while left <= right:
                mid = int(left + (right-left)/2)
                next = (mid + 1)%n
                prev = (mid-1+n)%n

                if nums[mid] <= nums[prev] and nums[mid] <= nums[next]:
                    return mid

                if nums[0] <= nums[mid]:
                    left = mid + 1

                if nums[mid] <= nums[-1]:
                    right = mid - 1

            return -1

        def binary_search(nums, target):
            left = 0
            right = len(nums)-1

            while left <= right:
                mid = int(left +(right-left)/2)

                if nums[mid] == target:
                    return mid

                elif nums[mid] < target:
                    left = mid+1

                elif nums[mid] > target:
                    right = mid -1

            return -1

        min_index = find_index(nums)
        left_arr = binary_search(nums[0:min_index], target)
        right_arr = binary_search(nums[min_index:], target)

        if right_arr != -1:
            return right_arr + len(nums[0:min_index])

        return left_arr
\end{lstlisting}
\section{3 Sum}
Find three numbers that add upto 0
\begin{lstlisting}
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        if len(nums) < 3:
            return None

        res = []
        nums = sorted(nums)

        for i in range(0, len(nums)):
            first = nums[i]
            if i > 0 and first == nums[i-1]:
                continue
            left = i+1
            right = len(nums)-1

            while left < right:
                if first + nums[left] + nums[right] < 0:
                    left += 1
                elif first+nums[left]+nums[right] > 0:
                    right -=1

                else:
                    res.append((first, nums[left], nums[right]))
                    left += 1
                    while nums[left] == nums[left-1] and left < right:
                        left += 1
        return res
\end{lstlisting}
\section{Container with most water}
Input: height = [1,8,6,2,5,4,8,3,7]
Output: 49

Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
\begin{lstlisting}
class Solution:
    def maxArea(self, height: List[int]) -> int:
        left = 0
        right = len(height)-1

        max_area = 0

        while left < right:
            curr_height = min(height[left], height[right])
            max_area = max(max_area, (right-left)*curr_height)

            if height[left] < height[right]:
                left += 1
            else:
                right -=1

        return max_area
\end{lstlisting}

\section{Merge Sort}
Divide and conquer algorithm, to break down to a single element and recursively build up while sorting.
\begin{lstlisting}
def sort(arr):
    def merge_sort(arr):
        if len(arr) > 1:
            mid = int(len(arr)/2)

            left_arr = arr[:mid]
            right_arr = arr[mid:]

            merge_sort(left_arr)
            merge_sort(right_arr)

            i, j, k = 0, 0, 0

            while i < len(left_arr) and j < len(right_arr):
                if left_arr[i] < right_arr[j]:
                    arr[k] = left_arr[i]
                    i+=1
                else:
                    arr[k] = right_arr[j]
                    j+=1
                k+=1

            while i < len(left_arr):
                arr[k] = left_arr[i]
                i+=1
                k+=1

            while j < len(right_arr):
                arr[k] = right_arr[j]
                j+=1
                k+=1
    merge_sort(arr)
    return arr
\end{lstlisting}
\section{Quick Sort}
Select a pivot point and arrange values according to the pivot.
\begin{lstlisting}
def sort(arr):
    def quick_sort(arr):
        if len(arr) <= 1:
            return arr

        pivot = arr.pop()

        left, right = [], []

        for item in arr:
            if item < pivot:
                left.append(item)
            else:
                right.append(item)

        return quick_sort(left) + [pivot] + quick_sort(right)
    quick_sort(arr)
    return arr
\end{lstlisting}
\end{document}


\section{Preliminaries}
\label{sec:Prelim}

Our proposal, \dyntset, relies mainly on three structures, a \textit{monoid}, a \textit{set} and a \textit{finger tree}, which are briefly described in the following subsections.

\subsection{Monoid}

A \textit{monoid} is a triple $(S,\star,e)$, where $S$ is a set, $\star$ is a binary operation, called $product$ and $e$ is an element of $S$, called $unit$, satisfying the following properties:

\begin{enumerate}
\item $e \star x = x = x \star e$, for all $x \in S$
\item $x \star (y \star z) = (x \star y) \star z $, for all $x,y,z \in S$.
\end{enumerate}

The type class Haskell implementation of a monoid we have:
%\begin{verbatim}
\begin{lstlisting}[mathescape]
class Monoid  a where
   mempty  :: a
   mappend :: a $\to$ a $\to$ a
\end{lstlisting}
%\end{verbatim}

where the function \code{mempty} represents the element $e$ and the function \code{mappend} represents function $\star$. Detailed information about monoids within the functional programming can be found in \cite{Monoids}, and for the Haskell implementation at \cite{HaskellMonoid}.

\subsection{Set as binary search tree}

A set, as a data structure, is used here for searching purposes, seen as testing membership within a specific set. Also, we look for incorporating elements into a set in order to increase such set for further look ups. This incorporation, comes in two flavours, either as single insertion or as the set-union operation. Finally, the presence of an empty set, a set with no elements at all, is crucial since it is the $unit$ when a set behaves as monoid. Also, an empty set is a starting point when a forest contains no trees.

Internally, a set is implemented as binary search tree, also called BST. A BST is either a \textit{leaf} (also called a \code{tip}) or a vertex consisting of a \textit{value}, a \textit{left} BST and a \textit{right} BST. The height of the tree determines the time taken to perform every operation onto it, therefore the shorter the height the better, and this is done throughout a \textit{balancing scheme}. The study of BSTs is vast and there are several implementation around. In our case, a \textit{size balanced} and a \textit{pairing hashed} are used. A detailed comparison and benchmarking is outside the scope of the present work.

The following is an snippet of \code{Data.Set} \footnote{https://hackage.haskell.org/package/containers-0.5.10.2/docs/Data-Set.html}
%\begin{verbatim}
\begin{lstlisting}
data Set a    = Bin Size a (Set a) (Set a)
              | Tip
\end{lstlisting}
%\end{verbatim}

In Table~\ref{tab:Setfuncs} we show the set-functions we have incorporated in \code{dynTsET} from \code{Data.Set}.
\small
\begin{table}[H]
\begin{center}
\begin{tabular}{||l | l | c||}
 \hline
 Function         & Type                                   & Time complexity            \\
 \hline\hline
 \texttt{empty}   & \texttt{Set a}                         & $O(1)$                     \\
 \hline
 \texttt{insert}  & \texttt{a $\to$ Set a $\to$ Set a}     & $O(\log n)$                \\
 \hline
 \texttt{member}  & \texttt{a $\to$ Set a $\to$ Bool}      & $O(\log n)$                \\
 \hline
 \texttt{union}   & \texttt{Set a $\to$ Set a $\to$ Set a} & $O(m(\log\frac{n}{m} +1))$ \\
 \hline
\end{tabular}
\caption{Leijen's implementation of \code{Data.Set} \cite{HaskellSet}, based on \cite{ParallelSets}}
\label{tab:Setfuncs}
\end{center}
where $n$ and $m$ are the sizes of the largest and smallest sets respectively
\end{table}
\normalsize

Functions \code{empty} and \code{union} are, in fact, the monoidal functions \code{mempty} and \code{mappend} respectively.

\subsection{Euler-tour tree}
\label{sec:ETt}
Dealing with trees of different degree can be complicated. A simple way to handle and represent trees of any degree is by an Euler tour, that is, a sequence as in \cite{Rand-DynGs-Algos} and \cite{WerneckR-PhD}. To represent a tree $t$, we replace every edge $\langle u,v \rangle$ of $t$ by two arcs $(u,v)$ and $(v,u)$, and add a loop $(v,v)$ to represent each vertex $v$. In this context, a tree $t$ can have at least one, and in general, many Euler tours. The size of an Euler tour \textit{et} of $t$ is $et(t) = v + 2e $, where $v$ is the number of vertices of $t$ and $e$ its number of edges. We can represent an Euler tour in Haskell simply as a list of pairs, such in

%\begin{verbatim}
\begin{lstlisting}
data EulerTour a = [(a,a)]
\end{lstlisting}
%\end{verbatim}

By managing the tour with lists, we can perform insertion from the left (head) in $O(1)$ but remaining operations such insertion from the right, access, cutting, appending and inserting might take $O(n)$ per operation.
On the other hand, representing tours through finger trees, performance per operation is improved up to $O(\log n)$ per operation amortised as we explain shortly and in Section~\ref{sec:TechDes}.

Our representation of $k$-trees through Euler-tour will not close up the tour with the first node as this avoids the uniqueness presence for such a node, as shown in Fig.~\ref{fig:Euler-tour}.

\begin{figure}[H]
\begin{center}
\includegraphics[scale=0.35]{./Images/Euler-tour}
\end{center}
\caption{The $k$-tree (left) is represented as a sequence of size $v+2e$ (right). Notice we left out the final node-pair to preserve uniqueness}
\label{fig:Euler-tour}
\end{figure}

\subsection{Finger tree}

We present Hinze and Paterson's version of finger trees \madd{(FTs)} \cite{FTs}. A finger tree is a 2-3-4 tree data structure which is always balanced. The structure is designed to store the elements of a sequence in the terminal nodes or leaves while intermediate nodes are dedicated for monoidal annotations. These annotations help out to achieve a specific task when storing or retrieving values in the leaves or when dealing with the tree itself such concatenation or splitting. One instance is random-access on lists. In order to speed up the time taken by a list for accessing the $n$th element, a finger tree stores the list elements on its leaves and the type \code{Sum Int} as its monoidal annotation. In this way, we can ask for a specific element provided its index in $O(\log n)$ rather than $O(n)$ time. This done through monoidal instances for \code{Sum}. The identity is defined as zero as in
\begin{lstlisting}[mathescape]
instance Num a $\Rightarrow$ Monoid (Sum a) where
        mempty = Sum 0
\end{lstlisting}

and the corresponding binary operation on integers which preserves its identity (arithmetic addition),
\begin{lstlisting}[mathescape]
instance Num a $\Rightarrow$ Semigroup (Sum a) where
        (<>) = coerce ((+) :: a $\to$ a $\to$ a)
\end{lstlisting}

The finger tree data type in Haskell is defined as

\begin{figure}[H]
\begin{lstlisting}
data FingerTree v a = Empty
                    | Single a
                    | Deep v
                           Digit a
                           FingerTree v (Node v a)
                           Digit a
\end{lstlisting}
\caption{Data type of the finger tree by Hinze and Paterson}
\label{fig:FTdatatype}
\end{figure}

\code{Digit} type holds from one up to four elements of type \code{a}. \code{Node} type can hold two or three elements of type \code{a}. The recursive and nested definition of \code{FingerTree} forces the structure to be balanced by its types, instead of enforcing it by code invariants. In our case, the leaves of a finger tree stores pairs of nodes or vertices representing an Euler tour. To implement \textit{updates} and \textit{lookups} efficiently, Hinze and Paterson \cite{FTs} added a monoidal annotation on the intermediate vertices, the \code {v} type.

In Fig.~\ref{fig:FT-Euler-tour} we can see our example of the Euler-tour sequence in Fig.~\ref{fig:Euler-tour} managed by the data constructors described above.

\begin{figure}[H]
\begin{center}
\includegraphics[scale=0.35]{./Images/FT-Euler-tour}
\end{center}
\caption{A finger tree (FT) holding the sequence (Euler-tour) that represents the $k$-tree in Fig.\ref{fig:Euler-tour}}
\label{fig:FT-Euler-tour}
\end{figure}

Since the backbone of our structure \dyntset is actually a Hinze's and Paterson finger tree \cite{FTs}, we show the functions involved in our proposal, those to deal with inserting, cutting, appending and accessing finger trees. There are plenty of additional functions from finger trees we do not cover and that can be reached at \url{http://hackage.haskell.org/package/fingertree-0.1.4.1/docs/Data-FingerTree.html}.

\small
\begin{table}[H]
\begin{center}
\begin{tabular}{||l | l | c||}
 \hline
 Function         & Type                                   &
      \begin{tabular}{c} Time complexity \\
                         (amortised bounds)
      \end{tabular} \\
 \hline\hline
 \texttt{viewl}   &
      \begin{tabular}{l} \texttt{FingerTree v a}   \\
                         \texttt{$\to$ ViewL (FingerTree v a)  }
      \end{tabular}
                  & $O(1)$ \\
 \hline
 \texttt{search}  &
      \begin{tabular}{l} \texttt{(v $\to$ v $\to$ Bool)}   \\
                         \texttt{$\to$ FingerTree v a  }   \\
                         \texttt{$\to$ SearchResult v a  }
      \end{tabular}
          & $O(\log(min(i,n-i)))$  \\
 \hline
 \texttt{$\lhd$} (ins. from left) &
      \begin{tabular}{l} \texttt{a $\to$ FingerTree v a} \\
                         \texttt{$\to$ FingerTree v a}
      \end{tabular}
          & $O(1)$                \\
 \hline
 \texttt{$\rhd$} (ins. from right) &
      \begin{tabular}{l} \texttt{FingerTree v a $\to$ a} \\
                         \texttt{$\to$ FingerTree v a}
      \end{tabular}
          & $O(1)$                \\
 \hline
 \texttt{$\bowtie$} (concatenation) &
      \begin{tabular}{l} \texttt{FingerTree v a} \\
                         \texttt{$\to$ FingerTree v a} \\
                         \texttt{$\to$ FingerTree v a}
      \end{tabular}
          & $O(\log ( min(m,n) ))$         \\
 \hline
\end{tabular}
\caption{Hinze's and Paterson implementation of \code{Data.FingerTree} \cite{FTsURL}, based on \cite{FTs}}
\label{tab:FTfuncs}
\end{center}
\end{table}
\normalsize

where $n$ is the size of the largest sequence, $m$ is the size of the smaller sequence (i.e. when concatenating) and $i$ is the index of the element when searching.

\tcb{SPLIT is not longer used, instead there is SEARCHFT, which aim is the same as SPLIT and hope it will be easier to explain}

\tcb{Is it the ``best" part in the document to bring up an explanations or examples or both for amortisation?}


\chapter{Algorithms for Multi-Dimensional Optimization}
\label{sec:algImp}
\section{Generalized Pattern Search Methods (Analysis)}
Generalized Pattern Search (GPS) algorithms are
derivative free optimization algorithms for the minimization of
problem $\mathbf P_c$ and $\mathbf P_{cg}$, defined in~\eqref{sub:Proc}
and~\eqref{sub:Procg}, respectively.
We will present the GPS algorithms for the case where
the function $f(\cdot)$ cannot be evaluated exactly,
but can be approximated by functions $f^* \colon \Re_+^q \times \Re^n \to \Re$,
where the first argument $\epsilon \in \Re_+^q$ is
the precision parameter of PDE, ODE, and algebraic equation solvers.
Obviously, the explanations are similar for problems where
$f(\cdot)$ can be evaluated exactly, except that the scheme to
control $\epsilon$ is not applicable, and that
the approximate functions $f^*(\epsilon,\cdot)$ are replaced by $f(\cdot)$.\\

Under the assumption that the cost function is continuously
differentiable, all the accumulation points constructed by
the GPS algorithms are stationary.\\

What GPS algorithms have in common is that they define the construction
of a mesh $\mathbb M_k$ in $\Re^n$,
which is then explored according to some rules
that differ among the various members of the family of GPS algorithms.
If no decrease in cost is obtained on mesh points around the current iterate,
then the distance between the mesh points is reduced,
and the process is repeated.\\

We will now explain the framework of GPS algorithms that will be used
to implement different instances of GPS algorithms in GenOpt.
The discussion follows the more detailed description of~\cite{PolakWetter2003:1}.\\
\pagebreak

\subsection{Assumptions}
We will assume that $f(\cdot)$ and its
approximating functions $\{ f^*(\epsilon,\cdot) \}_{\epsilon \in \Re_+^q}$
have the following properties.

\begin{assumption} ~\\
\\[-2.5\baselineskip]
\begin{enumerate}
\item There exists an error bound function $\varphi \colon \Re_+^q
  \to \Re_+$ such that for any bounded set $\mathbf S \subset \mathbf
  X$, there exists an $\epsilon_{\mathbf S} \in \Re_+^q$ and a scalar
  $K_{\mathbf S} \in
  (0, \, \infty)$ such that for all $x \in \mathbf S$ and for all
  $\epsilon \in \Re_+^q$,
with $\epsilon \le \epsilon_{\mathbf S}$,\footnote{For
$\epsilon \in \Re_+^q$, by $\epsilon \le
\epsilon_{\mathbf S}$,
we mean that $0 < \epsilon^i \le \epsilon_{\mathbf S}^i$, for all
$i \in \{ 1, \ldots ,q \}$.}
  \begin{equation}
    | \, f^*(\epsilon,x) - f(x) | \le K_{\mathbf S} \, \varphi(\epsilon).
  \lab{eq:fefPhi}
  \end{equation}
Furthermore,
\begin{equation}
\lim_{\| \epsilon \| \to 0} \varphi(\epsilon) = 0.
\end{equation}
\item  The function $f \colon \Re^n \to \Re$ is once continuously differentiable.
\rbox
\end{enumerate}
\lab{as:FFeps}
\end{assumption}

\begin{remark}~\\
\\[-2.5\baselineskip] {\em
\begin{enumerate}
\item
The functions $\{ f^*(\epsilon,\cdot) \}_{\epsilon \in \Re_+^q}$ may be
discontinuous.
\item
See~\cite{PolakWetter2003:1} for the situation where $f(\cdot)$ is
only locally Lipschitz continuous.
\rbox
\end{enumerate}
}
\end{remark}

%--------------------------------------------
Next, we state an assumption on the level sets of the family of
approximate functions. To do so, we first define the notion of a level
set.

\begin{definition}[Level Set]
Given a function $f \colon \Re^n \to \Re$ and an $\alpha \in
\Re$, such that $\alpha > \inf_{x \in \Re^n} f(x)$, we will say that
the set $\mathbf L_\alpha (f) \subset \Re^n$, defined as
\begin{equation}
  \mathbf L_\alpha(f) \triangleq \{ x \in \Re^n \ | \  f(x) \le \alpha \},
\end{equation}
 is a {\em level set} of $f(\cdot)$, parametrized by $\alpha$.
\rbox
\end{definition}

\begin{assumption}[Compactness of Level Sets]
Let $\{ f^*(\epsilon,\cdot) \}_{\epsilon \in \Re_+^q}$ be as in
Assumption~\ref{as:FFeps} and let $\mathbf X \subset \Re^n$ be the
constraint set. Let $x_0 \in \mathbf X$ be the
initial iterate and $\epsilon_0 \in \Re_+^q$ be the
initial precision setting of the numerical solvers.
Then, we assume that there exists a
compact set $\mathbf C \subset \Re^n$ such that
\begin{equation}
  \mathbf L_{f^*(\epsilon_0,x_0)} (f^*(\epsilon,\cdot)) \cap \mathbf X
  \subset \mathbf C, \qquad \forall \, \epsilon \le \epsilon_0.
\end{equation}
\rbox
\lab{as:LevSetBou}
\end{assumption}

% ===============================================
\subsection{Characterization of GPS Algorithms}
There exist different geometrical explanations for pattern search algorithms, and
a generalization is given in the review~\cite{KoldaLewisTorczon2003:1}.
We will use a simple implementation of the pattern search algorithms
in~\cite{PolakWetter2003:1} where we restrict the search directions to
be the positive and negative coordinate directions.
Thus, the search directions are the columns of the matrix
\begin{equation}
  D \triangleq [-e_1, \, +e_1, \, \ldots \, , -e_n, \, +e_n]
  \in \mathbb Z^{n \times 2n},
\end{equation}
which suffices for box-constrained problems. Furthermore, we
construct the sequence of mesh size parameters that parametrizes
the minimum distance between iterates
such that it satisfies the following assumption.
\begin{subequations}
\begin{assumption}[$k$-th Mesh Size Parameter]
Let $r, s_0, k \in \mathbb N$, with $r > 1$,
and $\{ t_i \}_{i=0}^{k-1} \subset \mathbb N$.
We will assume that the sequence of mesh size parameters satisfies
\begin{equation}
\Delta_k \triangleq \frac {1}{r^{s_k}},
\label{eq:GPSDelDef}
\end{equation}
where for $k > 0$
\begin{equation}
s_k \triangleq s_0 + \sum_{i=0}^{k-1} t_i.
\label{eq:GPSDelDefSk}
\end{equation}
\lab{ass:MeshSizePara}
\rbox
\end{assumption}
\end{subequations}
With this construction, all iterates lie on a rational mesh of the form
\begin{equation}
  \mathbb M_k \triangleq \{ x_0 + \Delta_k \, D \, m \ | \ m \in \mathbb N^{2 n} \}.
\lab{eq:Mesh}
\end{equation}

% -------- Global and Local Search Set ---------
We will now characterize the set-valued maps that determine the mesh
points for the ``global'' and ``local'' searches.  Note that the images
of these maps may depend on the entire history of the computation.

\begin{subequations}
\begin{definition}
Let $\underline{\mathbf X}_k \subset \Re^n$ and
$\underline {\boldsymbol \Delta}_k \subset \mathbb Q_+$
be the sets of all sequences containing $k+1$ elements,
let $\mathbb M_k$ be the current mesh,
and let $\epsilon \in \Re_+^q$ be the solver tolerance.
\begin{enumerate}
\item
We define the {\em global search set map}
to be any set-valued map
\begin{equation}
  \gamma_k \colon \underline{\mathbf X}_k \times \underline
  {\boldsymbol \Delta}_k  \times \Re_+^q \to
  \bigl( 2^{\mathbb M_k} \cap \mathbf X \bigr) \cup \emptyset
\end{equation}
whose image
$\gamma_k(\underline x_k, \underline \Delta_k, \epsilon)$
contains only a finite number of mesh points.
\item
We will call $\mathcal G_k \triangleq
\gamma_k (\underline x_k, \underline \Delta_k, \epsilon)$
the {\em global search set}.
\item
We define the directions for the local search as
\begin{equation}
 D \triangleq  [-e_1, \, +e_1, \, \ldots \, , -e_n, \, +e_n].
\end{equation}
\item
We will call
\begin{equation}
  \mathcal L_k \triangleq \bigl \{ x_k + \Delta_k \, D \, e_i \ | \
  i \in \{ 1, \ldots , \, 2 \, n \} \bigr \}
  \cap \mathbf X
\lab{eq:defLK}
\end{equation}
the {\em local search set}.
\rbox
\end{enumerate}
\lab{def:algFunGamDel}
\end{definition}
\lab{sub:mapfp}
\end{subequations}

\vspace{-\baselineskip}
\begin{remark}~\\
\\[-2.5\baselineskip] {\em
\begin{enumerate}
\item
The map $\gamma_k(\cdot, \cdot, \cdot)$
can be dynamic in the sense that if $\{ x_{k_i} \}_{i=0}^I \triangleq
\gamma_k(\underline x_k, \underline \Delta_k, \epsilon)$,
then the rule for selecting
$x_{k_{\widehat i}}$, $1 \le \widehat i \le I$, can depend on
$\{ x_{k_i} \}_{i=0}^{\widehat i - 1}$ and
$\{ f^*(\epsilon, x_{k_i}) \}_{i=0}^{\widehat i - 1}$.
It is only important that the global search terminates after
a finite number of computations, and that
$\mathcal G_k \subset (2^{\mathbb M_k} \cap \mathbf X) \cup \emptyset$.
\item
As we shall see, the global search affects only the efficiency of the
algorithm but not its convergence properties. Any heuristic procedure
that leads to a finite number of function evaluations can be used
for $\gamma_k(\cdot, \cdot, \cdot)$.
\item
The empty set is included in the range of $\gamma_k(\cdot, \cdot, \cdot)$
to allow omitting the global search.
\end{enumerate}
\rbox
}
\end{remark}

% ===========================================
\subsection{Model Adaptive Precision GPS Algorithm}
We will now present our model GPS algorithm
with adaptive precision cost function evaluations.\\

\noindent
\begin{minipage}[b]{\textwidth}
\begin{algorithm}
[Model GPS Algorithm]
~\\
{\em
\begin{tabular}{ll}
\multicolumn{2}{l}{\hspace{\textwidth}~} \\ \\[-8ex]\\
\hline \\[-2ex]
 \textbf{Data}:
     & Initial iterate $x_0 \in \mathbf X$;\\
     & Mesh size divider $r \in \mathbb N$, with $r > 1$;\\
     & Initial mesh size exponent $s_0 \in \mathbb N$.\\
 \textbf{Maps}:
     & Global search set map
       $\gamma_k \colon \underline{\mathbf X_k}
       \times \underline
       {\boldsymbol \Delta}_k  \times \Re_+^q \to \bigl(
       2^{\mathbb M_k} \cap \mathbf X \bigr) \cup \emptyset$; \\
     & Function $\rho \colon \Re_+ \to \Re_+^q$ (to assign $\epsilon$),
       such that the composition \\
     & $\varphi \circ \rho \colon \Re_+ \to \Re_+$
       is strictly monotone decreasing and satisfies\\
     & $\varphi(\rho(\Delta))/\Delta \to 0$, as $\Delta \to 0$.\\
  \textbf{Step 0}:
     & Initialize $k=0$, $\Delta_0 = 1 / r^{s_0}$, and $\epsilon=\rho(1)$.\\
  \textbf{Step 1}:
     & \underline{Global Search}\\
     & Construct the global search set
       $\mathcal G_k = \gamma_k(\underline x_k, \underline \Delta_k,
        \epsilon)$.\\
     & If $f^*(\epsilon, x') - f^*(\epsilon, x_k) < 0$
       for any $x' \in \mathcal G_k$, go to Step 3;\\
       & else, go to Step 2.\\
  \textbf{Step 2}:
     & \underline{Local Search}\\
     & Evaluate $f^*(\epsilon, \cdot)$ for any $x' \in \mathcal L_k$ until
       some $x' \in \mathcal L_k$\\
     & satisfying
       $f^*(\epsilon, x') - f^*(\epsilon, x_k) < 0$
       is obtained,
       or until all points\\
     & in $\mathcal L_k$ are evaluated.\\
  \textbf{Step 3}:
     & \underline{Parameter Update}\\
     & If there exists an $x' \in \mathcal G_k \cup \mathcal L_k$
       satisfying
       $f^*(\epsilon, x') - f^*(\epsilon, x_k) < 0$,\\
     & set  $x_{k+1} = x'$, $s_{k+1}= s_k$, $\Delta_{k+1} = \Delta_k$,
       and do not change $\epsilon$;\\
     & else, set $x_{k+1} = x_k$, $s_{k+1} = s_k + t_k$, with $t_k \in
       \mathbb N_+$ arbitrary,\\
     & $\Delta_{k+1} = 1/r^{s_{k+1}}$,
       $\epsilon = \rho(\Delta_{k+1} / \Delta_0)$.\\
  \textbf{Step 4}:
     & Replace $k$ by $k + 1$, and go to Step 1.\\
    \hline \\
\end{tabular}
}
~\\ \label{al:GPSImp}
\end{algorithm}
\end{minipage}
% ===========================================
\newpage
\begin{remark}~\newline
\vspace{-1.5\baselineskip}
{ \em
\begin{enumerate}
\item
To ensure that $\epsilon$ does not depend on the scaling of $\Delta_0$,
we normalized the argument of $\rho(\cdot)$.
In particular, we want to decouple $\epsilon$ from
the user's choice of the initial mesh parameter.
\item
In Step 2, once a decrease of the cost function is obtained, one
can proceed to Step 3. However, one is allowed to evaluate $f^*(\epsilon,\cdot)$
at more points in $\mathcal L_k$ in an
attempt to obtain a bigger reduction in cost.  However,
one is allowed to proceed to Step 3 only after
either a cost decrease has been found, or after {\em all} points in
$\mathcal L_k$ are tested.
\item
In Step 3, we are not restricted to accepting the
$x' \in \mathcal G_k \cup \mathcal L_k$ that gives lowest cost value.
But the mesh size parameter $\Delta_k$ is reduced {\em only}
if there exists no $x' \in \mathcal G_k \cup \mathcal L_k$ satisfying
$f^*(\epsilon, x') - f^*(\epsilon, x_k) < 0$.
\item
To simplify the explanations, we do
not increase the mesh size parameter if the cost has been reduced.
However, our global search allows searching on a coarser mesh
$\widehat {\mathbb M} \subset \mathbb M_k$,
and hence, our algorithm can easily be extended to include a rule for increasing
$\Delta_k$ for a finite number of iterations.
\item
Audet and Dennis~\cite{AudetDennis2003} update the mesh size parameter
using the formula $\Delta_{k+1} = \tau^m \, \Delta_k$,
where $\tau \in \mathbb Q$, $\tau > 1$, and $m$ is any
element of $\mathbb Z$. Thus, our update rule for $\Delta_k$ is a special case of
Audet's and Dennis' construction since we set $\tau = 1/r$, with
$r \in \mathbb N_+$, $r \ge 2$ (so that $\tau < 1$) and $m \in
\mathbb N$. We prefer our construction because we do not think it negatively affects
the computing performance, but it leads to simpler convergence proofs.
\rbox
\end{enumerate}
}
\end{remark}

% ===========================================
\subsection{Convergence Results}
We will now present the convergence results for our Model GPS algorithm.
See~\cite{PolakWetter2003:1} for a detailed discussion and convergence proofs.

\subsubsection{Unconstrained Minimization}

We will first present the convergence properties of the Model GPS
Algorithm~\ref{al:GPSImp} on unconstrained minimization problems, i.e., for
$\mathbf X = \Re^n$.\\

First, we will need the notion of a {\em refining subsequence},
which we define as follows:
\begin{definition}[Refining Subsequence]
Consider a sequence $\{x_k\}_{k=0}^\infty$ constructed by Model GPS
Algorithm~\ref{al:GPSImp}.  We will say that the subsequence $\{ x_k \}_{k \in
\mathbf K}$ is the {\em refining subsequence}, if $\Delta_{k+1} <
\Delta_k$ for all $k \in \mathbf K$, and $\Delta_{k+1} = \Delta_k$
for all $k \notin \mathbf K$.
\rbox
\end{definition}

We now state that pattern search algorithms with adaptive precision
function evaluations construct sequences with stationary accumulation points.
\begin{theorem}[Convergence to a Stationary Point]
Suppose that Assumptions~\ref{as:FFeps} and \ref{as:LevSetBou} are
satisfied and that $\mathbf X = \Re^n$.
Let $x^* \in \Re^n$ be an accumulation point of the refining
subsequence $\{ x_k \}_{k \in \mathbf K}$, constructed by Model GPS
Algorithm~\ref{al:GPSImp}. Then,
\begin{equation}
  \nabla f(x^*) = 0.
\lab{eq:GradConv}
\end{equation}
\lab{the:GradConv}
\rbox
\end{theorem}
% ===========================================
\subsubsection{Box-Constrained Minimization}
We now present the convergence results for the box-constrained
problem~\eqref{sub:Proc}.
See~\cite{AudetDennis2003, PolakWetter2003:1, KoldaLewisTorczon2003:1}
for the more general case of linearly-constrained problems and for the convergence
proofs.\\

First, we introduce the notion of a tangent cone and a normal cone,
which are defined as follows:
\begin{definition}[Tangent and Normal Cone] ~\\
\\[-2.5\baselineskip]
\begin{enumerate}
\item
Let $\mathbf X \subset \Re^n$. Then, we define the {\em tangent cone} to
$\mathbf X$ at a point $x^* \in \mathbf X$ by
\begin{subequations}
  \begin{equation}
    \mathbf T_{\mathbf X}(x^*) \triangleq
    \overline{ \{ \mu \, (x - x^*) \ | \  \mu \ge 0,
      \, x \in \mathbf X \}}.
  \end{equation}
\item
Let $\mathbf T_{\mathbf X}(x^*)$ be as above. Then, we define the
{\em normal cone} to $\mathbf X$ at $x^* \in \mathbf X$ by
\begin{equation}
      \mathbf N_{\mathbf X}(x^*) \triangleq \{ v \in \Re^n \ | \
      \forall \, t \in \mathbf T_{\mathbf X}(x^*), \, \langle v, \, t
      \rangle \le 0 \}.
    \end{equation}
\end{subequations}
\rbox
\end{enumerate}
\end{definition}

We now state that the accumulation
points generated by Model GPS Algorithm~\ref{al:GPSImp}
are feasible stationary points of problem~\eqref{sub:Proc}.
\begin{theorem}[Convergence to a Feasible Stationary Point]~\\
\noindent
Suppose Assumptions~\ref{as:FFeps} and \ref{as:LevSetBou} are
satisfied.
Let $x^* \in \mathbf X$ be an accumulation point of a
refining subsequence $\{ x_k \}_{k \in \mathbf K}$ constructed by Model
GPS Algorithm~\ref{al:GPSImp} in solving problem~\eqref{sub:Proc}.
Then,
\begin{subequations}
 \begin{equation}
   \langle \nabla f(x^*), \, t \rangle \ge 0, \qquad \forall \, t \in
   \mathbf T_{\mathbf X}(x^*),
   \lab{eq:feaPoiConv}
 \end{equation}
and
 \begin{equation}
   - \nabla f(x^*) \in \mathbf N_{\mathbf X}(x^*).
 \end{equation}
\end{subequations}
\lab{the:feaPoiConv}
\end{theorem}

% ===========================================
\section{Generalized Pattern Search Methods (Implementations)}
We will now present different implementations of the Generalized
Pattern Search (GPS) algorithms.
They all use the Model GPS Algorithm~\ref{al:GPSImp} to solve
problem $\mathbf P_{c}$ defined in~\eqref{sub:Proc}.
The problem $\mathbf P_{cg}$ defined in~\eqref{sub:Procg} can be solved
by using penalty functions as described in Section~\ref{sec:conDepVarGen}.\\

We will discuss the implementations for the case where
the function $f(\cdot)$ cannot be evaluated exactly,
but will be approximated by functions $f^* \colon \Re_+^q \times \Re^n
\to \Re$, where the first argument $\epsilon \in \Re_+^q$ is
the precision parameter of the
PDE, ODE, and algebraic equation solvers.
This includes the case where $\epsilon$
is not varied during the optimization, in which case
the explanations are identical, except that the scheme to
control $\epsilon$ is not applicable, and that
the approximate functions $f^*(\epsilon,\cdot)$ are replaced by $f(\cdot)$.\\

If the cost function $f(\cdot)$ is approximated by
functions $\{ f^*(\epsilon,\cdot)\}_{\epsilon \in \Re_+^q}$
with adaptive precision $\epsilon$, then
the function $\rho \colon \Re_+ \to \Re_+^q$ (to assign $\epsilon$)
can be implemented by using GenOpt's pre-processing capability
(see Section~\ref{par:posPro}).\\

% ===========================================
\subsection{Coordinate Search Algorithm}
We will now present the implementation of the Coordinate Search
algorithm
with adaptive precision function evaluations
using the Model GPS Algorithm~\ref{al:GPSImp}.
To simplify the implementation, we assign
$f^*(\epsilon,x) = \infty$ for all $x \not \in \mathbf X$ where
$\mathbf X$ is defined in~\eqref{eq:setXPc}.

%-------------------------
\subsubsection{Algorithm Parameters}
\lab{sec:AlgParCooSea}
The search direction matrix is defined as
\begin{equation}
   D \triangleq [+s^1 \, e_1, \, -s^1 \, e_1, \ldots ,
\, +s^n \, e_n, \, -s^n \, e_n]
\label{eq:defDMatGPSCooSea}
\end{equation}
where $s^i \in \Re$, $i \in \{1, \ldots, n \}$, is a scaling for each parameter
(specified by GenOpt's parameter \texttt{Step}).\\

The parameter $r \in \Na$, $r>1$, which is used to compute the mesh size parameter
$\Delta_k$,
is defined by the parameter \texttt{MeshSizeDivider},
the initial value for the mesh size exponent $s_0 \in \Na$
is defined by the parameter \texttt{InitialMeshSizeExponent},
and the mesh size exponent increment $t_k$ is, for the
iterations that do not reduce the cost,
defined by the parameter \texttt{MeshSizeExponentIncrement}.

%-------------------------
\subsubsection{Global Search}
\lab{sec:GloSeaCooSea}

In the Coordinate Search Algorithm, there is no global search.
Thus, $\mathcal G_k = \emptyset$ for all $k \in \Na$.

%-------------------------
\subsubsection{Local Search}
\lab{sec:locSeaCooSea}

The local search set $\mathcal G_k$ is constructed using the
set-valued map $E_k \colon \Re^n \times \mathbb Q_+ \times \Re_+^q \to 2^{\mathbb M_k}$,
which is defined as follows:\\[\baselineskip]
\noindent
\begin{minipage}[b]{\textwidth}
\begin{algorithm}
[Map
$E_k \colon \Re^n \times \mathbb Q_+ \times \Re_+^q \rightarrow 2^{\mathbb M_k}$
for ``Coordinate Search'']
~\\
{\em
\begin{tabular}{ ll }
\multicolumn{2}{l}{\hspace{\textwidth}~} \\ \\[-8ex]\\
\hline \\[-2ex]
\textbf{Parameter}:
    & Search direction matrix $D
      =  [+s^1 \, e_1, \, -s^1 \, e_1, \ldots ,
\, +s^n \, e_n, \, -s^n \, e_n]$.\\
    & Vector $\mu \in \Na^n$.\\
\textbf{Input}:
    & Iteration number $k \in \Na$.\\
    & Base point $x \in \Re^n$.\\
    & Mesh divider $\Delta_k \in \mathbb Q_+$. \\
\textbf{Output}:
    & Set of trial points $\mathcal T$.\\
\textbf{Step 0}:
    & Initialize $\mathcal T = \emptyset$.\\
    & If $k = 0$, initialize , $\mu^i=0$ for all $i \in \{1, \ldots, n\}$.\\
\textbf{Step 1}:
    & For $i = 1, \ldots , n$\\
    & \hspace{1cm} Set $\widetilde x = x + \Delta_k \,
      D \, e_{2 \, i - 1 + \mu^i}$ and
      $\mathcal T \leftarrow \mathcal T \cup \{ \widetilde x \}$.\\
    & \hspace{1cm} If $f^*(\epsilon,\widetilde x) < f^*(\epsilon,x)$\\
    & \hspace{2cm} Set $x = \widetilde x$.\\
    & \hspace{1cm} else \\
    & \hspace{2cm} If $\mu^i = 0$, set $\mu^i = 1$, else set $\mu^i = 0$.\\
    & \hspace{2cm} Set $\widetilde x = x + \Delta_k \,
                        D \, e_{2 \, i -1 + \mu_i}$ and
                   $\mathcal T \leftarrow \mathcal T \cup \{
                   \widetilde x \}$.\\
    & \hspace{2cm} If $f^*(\epsilon,\widetilde x) < f^*(\epsilon,x)$\\
    & \hspace{3cm} Set $x = \widetilde x$.\\
    & \hspace{2cm} else\\
    & \hspace{3cm} If $\mu^i = 0$, set $\mu^i = 1$, else set $\mu^i = 0$.\\
    & \hspace{2cm} end if.\\
    & \hspace{1cm} end if.\\
    & end for.\\
\textbf{Step 2}:
    & Return $\mathcal T$.\\
    \hline \\
\end{tabular}
}
\lab{al:CooSeaLocSea}
\end{algorithm}
\end{minipage}
Thus, $E_k(x, \Delta_k, \epsilon) = \mathcal T$ for all $k \in \Na$.
\begin{remark}
{\em
In Algorithm~\ref{al:CooSeaLocSea},
the vector $\mu \in \Na^n$ contains for
each coordinate direction an integer $0$ or $1$ that indicates
whether a step in the positive or
in the negative coordinate direction yield a decrease in cost in the previous
iteration. This reduces the number of exploration steps.
}
\rbox
\end{remark}

%-------------------------
\subsubsection{Parameter Update}
The point $x'$ in Step 3 of the GPS Model Algorithm~\ref{al:GPSImp}
corresponds to
$x' \triangleq \arg \min_{x \in E_k(x_k, \Delta_k, \epsilon)} f^*(\epsilon,x)$
in the Coordinate Search algorithm.

%-------------------------
\subsubsection{Keywords}
\label{sec:GPSCooSeaKeyWor}
For the GPS implementation of the Coordinate Search Algorithm,
the command file (see page~\pageref{par:comFil}) must only contain continuous parameters.\\

To invoke the algorithm,
the \texttt{Algorithm} section of the GenOpt command file must have the following form:
\begin{lstlisting}
Algorithm{
   Main                      = GPSCoordinateSearch;
   MeshSizeDivider           = Integer; // 1 <  MeshSizeDivider
   InitialMeshSizeExponent   = Integer; // 0 <= InitialMeshSizeExponent
   MeshSizeExponentIncrement = Integer; // 0 <  MeshSizeExponentIncrement
   NumberOfStepReduction     = Integer; // 0 <  NumberOfStepReduction
}
\end{lstlisting}
The entries are defined as follows:
\begin{codedescription}
\item [Main]
The name of the main algorithm.
\item [MeshSizeDivider]
The value for $r \in \Na$, $r>1$, used to compute
$\Delta_k \triangleq  {1} / {r^{s_k}}$ (see equation~\eqref{eq:GPSDelDef}).
A common value is $r = 2$.

\item [InitialMeshSizeExponent]
The value for $s_0 \in \Na$ in~\eqref{eq:GPSDelDefSk}.
A common value is $s_0 = 0$.

\item [MeshSizeExponentIncrement]
The value for $t_i \in \Na$ (for the iterations that do not yield
a decrease in cost) in~\eqref{eq:GPSDelDefSk}.
A common value is $t_i = 1$.

\item [NumberOfStepReduction]
The maximum number of step reductions before the algorithm stops.
Thus, if we use the notation $m \triangleq \text{\texttt{NumberOfStepReduction}}$, then
we have for the last iterations $\Delta_k = {1} / {r^{s_0 + m\, t_k}}$.
A common value is $m = 4$.
\end{codedescription}

% ===========================================
\subsection{Hooke-Jeeves Algorithm}
\lab{sec:GPSHooJeeImp}
We will now present the implementation of the Hooke-Jeeves algorithm~\cite{HookeJee1961}
with adaptive precision function evaluations
using the Model GPS Algorithm~\ref{al:GPSImp}.
The modifications of Smith~\cite{Smith1969},
Bell and Pike~\cite{BellPik1966} and
De Vogelaere~\cite{DeVogelaere1968}
are implemented in this algorithm.\\

To simplify the implementation, we assign
$f^*(\epsilon,x) = \infty$ for all $x \not \in \mathbf X$ where
$\mathbf X$ is defined in~\eqref{eq:setXPc}.

%-------------------------
\subsubsection{Algorithm Parameters}
The algorithm parameters $D$, $r$, $s_0$, and $t_k$ are defined
as in the Coordinate Search algorithm
(see page~\pageref{sec:AlgParCooSea}).

%-------------------------
\subsubsection{Map for Exploratory Moves}
To facilitate the algorithm explanation, we use
the set-valued map
$E_k \colon \Re^n \times \mathbb Q_+ \times \Re_+^q \to 2^{\mathbb M_k}$,
as defined in Algorithm~\ref{al:CooSeaLocSea}.
The map $E_k(\cdot,\cdot,\cdot)$ defines the
``exploratory moves'' in~\cite{HookeJee1961}, and
will be used in Section~\ref{sec:GloSeaSetMapHJ}
to define the global search set map and,
under conditions to be seen in Section~\ref{sec:locSeaDirMapHJ},
the local search direction map as well.\\
%-------------------------
%-------------------------
\subsubsection{Global Search Set Map}
\lab{sec:GloSeaSetMapHJ}

The global search set map
$\gamma_k(\cdot, \cdot, \cdot)$ is defined as follows. Because
$\gamma_0(\cdot, \cdot, \cdot)$ depends on $x_{-1}$, we need to introduce
$x_{-1}$, which we define as $x_{-1} \triangleq x_0$.\\

\noindent
\begin{minipage}{\textwidth}
\begin{algorithm}
[Global Search Set Map $\gamma_k \colon \underline{\mathbf X}_k
\times \underline {\boldsymbol \Delta}_k \times \Re_+^q
\rightarrow 2^{\mathbb M_k} $]
~\\
{\em
\begin{tabular}{ll}
\multicolumn{2}{l}{\hspace{\textwidth}~} \\ \\[-8ex]\\
\hline \\[-2ex]
\textbf{Map}:
    & Map for ``exploratory moves''
    $E_k \colon \Re^n \times \mathbb Q_+ \times \Re_+^q \to 2^{\mathbb M_k}$.\\
\textbf{Input}:
    & Previous and current iterate, $x_{k-1} \in \Re^n$
      and $x_k \in \Re^n$.\\
    & Mesh divider $\Delta_k \in \mathbb Q_+$.\\
    & Solver precision $\epsilon \in \Re_+^q$.\\
\textbf{Output}:
    & Global search set $\mathcal G_k$.\\
\textbf{Step 1}:
    & Set $x = x_k + (x_k - x_{k-1})$.\\
\textbf{Step 2}:
    & Compute $\mathcal G_k = E_k(x, \Delta_k, \epsilon)$.\\
\textbf{Step 3}:
    & If $\bigl(\min_{x \in \mathcal G_k}
         f^*(\epsilon,x)\bigr) > f^*(\epsilon,x_k)$\\
    & \hspace{1cm} Set $\mathcal G_k \leftarrow \mathcal G_k \cup
                       E_k(x_k, \Delta_k, \epsilon)$.\\
    & end if.\\
\textbf{Step 4}:
    & Return $\mathcal G_k$.\\
    \hline \\
\end{tabular}
}
\lab{al:HJGloSeaSetMap}
\end{algorithm}
\end{minipage}
Thus, $\gamma_k(\underline x_k, \underline \Delta_k, \epsilon) = \mathcal G_k$.\\

%-------------------------
\subsubsection{Local Search Direction Map}
\lab{sec:locSeaDirMapHJ}
If the global search, as defined by
Algorithm~\ref{al:HJGloSeaSetMap}, has failed in reducing
$f^*(\epsilon,\cdot)$, then Algorithm~\ref{al:HJGloSeaSetMap} has
constructed a set $\mathcal G_k$ that contains the set
$\{ x_k + \Delta_k \, D \, e_i \ | \ i = 1, \ldots , \, 2 n \}$.
This is because in the evaluation of
$E_k(x_k, \Delta_k, \epsilon)$, defined in Algorithm~\ref{al:CooSeaLocSea}, all
``If $f^*(\epsilon,\widetilde x) < f^*(\epsilon,x)$'' statements yield
{\tt false}, and, hence, one has constructed
$\{ x_k + \Delta_k \, D \, e_i \ | \ i = 1, \ldots , \, 2 n
\} = E_k(x_k, \Delta_k, \epsilon)$.

Because the columns of
$D$ span $\Re^n$ positively, it follows that
the search on the set  $\{ x_k + \Delta_k \, D \, e_i \ | \ i = 1, \ldots , \, 2 n
\}$ is a local search. Hence, the constructed set
\begin{equation}
\mathcal L_k \triangleq \{ x_k + \Delta_k \, D \, e_i \ | \
i = 1, \ldots , \, 2 n \} \subset \mathcal G_k
\lab{eq:LkHJ}
\end{equation}
is a local search set.
Consequently, $f^*(\epsilon,\cdot)$ has already been evaluated
at all points of $\mathcal L_k$ (during the construction of $\mathcal
G_k$) and, hence, one does not need to evaluate $f^*(\epsilon,\cdot)$
again in a local search.

%-------------------------
\subsubsection{Parameter Update}
The point $x'$ in Step 3 of the GPS Model Algorithm~\ref{al:GPSImp}
corresponds to $x' \triangleq \arg \min_{x \in \mathcal G_k}
f^*(\epsilon,x)$ in the Hooke-Jeeves algorithm. (Note that
$\mathcal L_k \subset \mathcal G_k$ if a local search has been done as
explained in the above paragraph.)

%-------------------------
\subsubsection{Keywords}
For the GPS implementation of the Hooke-Jeeves algorithm, the command file (see page~\pageref{par:comFil}) must only contain continuous parameters.\\

To invoke the algorithm,
the \texttt{Algorithm} section of the GenOpt command file must have the following form:
\label{algSec:GPSHookeJeeves}
\begin{lstlisting}
Algorithm{
   Main                      = GPSHookeJeeves;
   MeshSizeDivider           = Integer;   // bigger than 1
   InitialMeshSizeExponent   = Integer;   // bigger than or equal to 0
   MeshSizeExponentIncrement = Integer;   // bigger than 0
   NumberOfStepReduction     = Integer;   // bigger than 0
}
\end{lstlisting}
The entries are the same as for the Coordinate Search algorithm, and explained
on page~\pageref{sec:GPSCooSeaKeyWor}.

% ===========================================
\subsection{Multi-Start GPS Algorithms}
\lab{sec:GPSMulSta}
All GPS algorithms can also be run using multiple initial points.
Using multiple initial points increases the chance of finding
the global minimum if the cost function has several local minima,
and furthermore, it decreases the risk of not finding a minimum if the
cost function is not continuously differentiable, which
is the case if building simulation programs, such as
EnergyPlus or TRNSYS, are used to compute the cost function
(see the discussion in Section~\ref{sec:proAppCosFun}).\\

The values that are specified
by GenOpt's parameter \texttt{Ini} in GenOpt's command file
(see Section~\ref{par:comFil}) are used to initialize
the first initial point.
The other initial points are randomly distributed, with
a uniform distribution,
between the lower
and upper bounds of the feasible domain.
They are, however, set to the mesh $\mathbb M_0$, defined in~\eqref{eq:Mesh},
which reduces the number of cost function evaluations if
the optimization algorithm converges
from different initial points to the same minimizer.\\

In GenOpt's command file, a lower and an upper bound must be specified
for each independent variable
using the keywords \texttt{Min} and \texttt{Max}.\\

To use the \texttt{GPSCoordinateSearch} algorithm with multiple
starting points,
the \texttt{Algorithm} section of the GenOpt command file
must have the following form:
\begin{lstlisting}
Algorithm{
   Main                      = GPSCoordinateSearch;
   MultiStart                = Uniform;
   Seed                      = Integer;
   NumberOfInitialPoint      = Integer; // bigger than or equal to 1
   MeshSizeDivider           = Integer; // 1 <  MeshSizeDivider
   InitialMeshSizeExponent   = Integer; // 0 <= InitialMeshSizeExponent
   MeshSizeExponentIncrement = Integer; // 0 <  MeshSizeExponentIncrement
   NumberOfStepReduction     = Integer; // 0 <  NumberOfStepReduction
}
\end{lstlisting}
The entries are defined as follows:
\begin{codedescription}
\item [Main]
The name of the main algorithm.
\item [MultiStart]
Keyword to invoke the multi-start algorithm.
The only valid value is \texttt{Uniform}.
\item [Seed]
This value is used to initialize the random number generator.
\item [NumberOfInitialPoint]
The number of initial points.
\end{codedescription}
The other entries are the same as for the Coordinate Search algorithm,
and are explained on page~\pageref{sec:GPSCooSeaKeyWor}.\\

To use the \texttt{GPSHookeJeeves} algorithm with multiple
starting points,
the \texttt{Algorithm} section of the GenOpt command file
must have the following form:
\begin{lstlisting}
Algorithm{
   Main                      = GPSHookeJeeves;
   MultiStart                = Uniform;
   Seed                      = Integer;
   NumberOfInitialPoint      = Integer; // 0 <  NumberOfInitialPoint
   MeshSizeDivider           = Integer; // 1 <  MeshSizeDivider
   InitialMeshSizeExponent   = Integer; // 0 <= InitialMeshSizeExponent
   MeshSizeExponentIncrement = Integer; // 0 <  MeshSizeExponentIncrement
   NumberOfStepReduction     = Integer; // 0 <  NumberOfStepReduction
}
\end{lstlisting}
The entries are the same as for the
multi-start Coordinate Search algorithm above.

% ===============================================


%SDOF_eqs
\begin{align}
\Delta_D &= \frac{\sum{M_i \delta_{ls,i}^2}}{\sum{M_i \delta_{ls,i}}}\\
M_{eff} &= \frac{\sum{M_i \delta_{ls,i}}}{\Delta_D}\\
H_{eff} &=  \frac{\sum{M_i \delta_{ls,i} h_i}}{\sum{M_i \delta_{ls,i}}}
\end{align}

%theta_y
\begin{align}
\theta_y &=0.5\frac{f_{ye}}{E_s}\frac{L_b}{D_b}
\end{align}

%Delta_y
\begin{align}
\Delta_y &= \\theta_y*H_{eff}
\end{align}

% Moment equilibrium

\subsection{Calculate element design forces}
The element forces were determined based on the equilibrium method.
The set inflection point on the first storey columns was used to determine the
column base moments ($M_{col}_{0}$) \\ref{eq:Mbase}.
The remaining overturning moment was then taken by the axial component ($T$) of the outer columns \\ref{eq:outerCol}.
The axial load was then distributed into the beams ($V_{beam}$) in proportion to the
storey shear force \ref{eq:Beam shear} however for ease of design and construction
the storeys forces were calcualted in groups of XXXXX

 \\ref{eq:groupbeam} and assuming an inflection point at half
the beam length the beam moments were determined \ref{eq:beam moments}.
\begin{align}
\sum{M_{col}_{0}} &=0.6 V_{base} H_0 \label{eq:Mbase} \\
 M_{overturning} &= \sum{F_i*h_i} \\\ \n T &= \\frac{M_{overturning}-
 \sum{M_{col}_{0}}}{\sum{bay_{lengths}}} \label{eq:outerCol} \\
   V_{beam}_{(i)} &=T \\frac{V_{i}}{\sum{V}} \label{eq:Beam shear} \\
    V_{beam}_{(i \& i+1)} = T \\frac{\\frac{V_{i}+...+V_{i+ XXXX}}{' + str(BO.beam_group_size) + '}}{\sum{V}} \label{eq:groupbeam} \\
     Moment_{beam}_i = 0.5 V_{beam}_i*Length_{span}
     \end{align}


\section{Mutual information}
We now consider the case where we have a set of images. This can be
R,G,B color band images, observations of the same area but
at different times, etc.
We are interested in having an entropy measurement
of such data sets, knowing that the correlation between two images
can be relatively high. A 3-dimensional wavelet transform is not
appropriate because the third dimension is generally completely different
from the two first. The standard case is the data set where we have
2-dimensional spatial information versus a frequency band.

\subsection{Principal component analysis}
Principal Component Analysis (PCA), also often referred as eigenvector,
Hotelling,
or Karhunen-Lo\`eve transform
\cite{ima:karhunen47,ima:loeve48,ima:hotelling33},
allows us to transform  discrete signals into a sequence of uncorrelated
coefficients. Considering a population $D(1..M,1..N)$
of $M$ signals or images of dimension $N$,
the PCA method consists of expressing the dataset $D$ by:
\begin{eqnarray}
D = U \Lambda^{\frac{1}{2}} V^t
\end{eqnarray}
and
\begin{eqnarray}
DD^t & = & U \Lambda U^t \\
D^t D & = & V \Lambda V^t
\end{eqnarray}
where $\Lambda$ is the diagonal matrix of eigenvalues of the covariance
matrix $C = DD^t$, the columns of $U$ are the eigenvectors of $C$, and
the columns of $U$ are the eigenvector of $D^t D$.

For a signal $d(1..N)$ we have,
\begin{eqnarray}
d = \sum_{i=1}^{M} \sqrt{\lambda_i} u_i v_i^t
\end{eqnarray}
where $\lambda_i$ are the eigenvalues of the covariance matrix. The $v_i$
vectors can also be calculated by \cite{ima:bijaoui79}:
\begin{eqnarray}
 V(i,j) = v_i(j) = \frac{1}{\sqrt{\lambda_i}} \sum_k D(i,k) u_i(j)
\end{eqnarray}

In practice, we construct the matrix $A$ whose rows are formed
from the eigenvectors
of $C$ \cite{ima:gonzalez93}, ordered following the
monotonic decreasing order of eigenvalues. A vector $x(1..M)$ can then be
transformed by:
\begin{eqnarray}
y = \Lambda^{-\frac{1}{2}}A(x-m_x)
\end{eqnarray}
where $m_x$ is the mean value of $x$.
Because the rows of $A$ are orthonormal vectors, $A^{-1} = A^t$, and
any vector $x$ can be recovered from its corresponding $y$ by:
\begin{eqnarray}
x = \Lambda^{\frac{1}{2}}A^t y + m_x
\end{eqnarray}

The $\Lambda$ matrix multiplication can be seen as a normalization.
Building $A$ from the correlation matrix instead of the covariance matrix
leads to another kind of normalization,
and the $\Lambda$ matrix can be suppressed
($y = A(x-m_x)$ and $x = A^t y + m_x$). Then the norm of $y$ will be equal to the
norm of $x$.

\subsection{The WT-PCA transform}

We consider now that we have $M$ observations of the same view, but
at different wavelengths (or at different epochs, etc.), and denote
as $D_k$ one
observation, and $W(k, 1..P)$ its wavelet transform, $P$ being the
number of scales (or bands) of the wavelet transform. Then for a given
frequency band $j$, we can compare the information content for all observations.
As a strong correlation may exist between the same frequency band of two
different observations, we can appy a principal component analysis for
the specific scale $j$, and repeat the same information for all $j$. Then,
for each scale $j$, we build a correlation matrix $C_j$ (and also $A_j$),
and the wavelet coefficients are transformed into their principal
components. As the obtained coefficients are obtained by applying
successively a wavelet transform and a principal component analysis,
we will term these two transformations a WT-PCA transform,
and the values obtained will be called WT-PCA coefficients.

The advantages of the WT-PCA transform are:
\begin{itemize}
\item We have separated the information not only spatially as if we had
used only a wavelet transform, but also on the wavelength axis as if
had used directly a PCA on the images.
\item We keep the possibility open to estimate the noise level of the
WT-PCA coefficients in  the same rigorous way as for a simple wavelet
transform.
\item We have an exact reconstruction.
\end{itemize}

\subsection{Entropy from the WT-PCA transform}

The entropy relative to a set of observations $D(1..M)$ can be written by:
\begin{eqnarray}
H(D) = \sum_{j=1}^{l} \sum_{e=1}^{M}  \sum_{k=1}^{N_j} h(c_{j,k,e})
\end{eqnarray}
where $l$ is the number of scales used in the wavelet transform
decomposition, $M$ the number of observations, $k$ a pixel position,
 $c$ a WT-PCA coefficients, and $e$ denotes the eigenvector number.

The last scale of the wavelet transform is not used, as previously, so
this entropy measurement is background independent, which is really
important because the background can vary from one wavelength to another.


\documentclass[10pt]{article}

% Manage page layout
\usepackage[margin=2.5cm, includefoot, footskip=30pt]{geometry}
\pagestyle{plain}
\setlength{\parindent}{0em}
\setlength{\parskip}{1em}
\renewcommand{\baselinestretch}{1}

\usepackage{blkarray}
\usepackage{multirow}
\usepackage{amsmath}
\usepackage{enumerate}

\title{\textbf{Week 4.} Static games with complete information III: Nash equilibria}
\date{}

\begin{document}
\maketitle
\vspace{-1cm}

\subsection*{Exercise 1: Nash equilibrium vs dominance solvability}

\textbf{Prove the following statements:}

\begin{enumerate}[(i)]
    \item If a pure strategy \(s^{(i)}_{j}\) is dominated by a pure strategy \(s^{(i)}_{k}\) and
    \(\sigma = (\sigma^{(1)}, \dots, \sigma^{(n)})\) is a Nash equilibrium, then
    \(\sigma^{(i)}_{j}=0\).
    \item If the game is dominance solvable such that the unique outcome of
    iterated elimination of dominated strategies is some pure strategy
    \(s=(s^{(1)}, \dots, s^{(n)})\), then \(s\) is a Nash equilibrium.
\end{enumerate}

[Suggestion: One could use contradiction to prove the above statements. For example, for (i)
assume that these was a Nash equilibrium with \(\sigma^{(i)}_{j}>0\), and show
that this would yield some contradiction.]

\subsection*{Exercise 2: Best responses}

Consider the stag hunt game:

\begin{equation*}
    \begin{blockarray}{cccc}
       & & \BAmulticolumn{2}{c}{\underline{\text{player 2}}} \\ [1em]
       & & \text{Stag} & \text{Hare} \\
        \begin{block}{cc(cc)}
\underline{\text{player 1}} & \text{Stag} & (10, 10) & (0, 6) \\
                            & \text{Hare} & (6, 0) & (6, 6) \\
        \end{block}
    \end{blockarray}
\end{equation*}

Suppose player 1 uses the mixed strategy \((x, 1- x)\), where \(x\) is player 1's
probability to Stag. Similarly, player 2's strategy is \((y, 1 - y)\).

\begin{enumerate}[(i)]
    \item For given \(x, y\) compute the players' payoffs \(\pi^{(1)}(x, y),
    \pi^{(2)}(x, y)\) (see Remarks 2.6, 2.7).
    \item For a given \(y\) compute player 1's best response (BR(\(y\))). In
    particular, show that there is some \(y^{*}\) such that all \(x \in [0,
    1]\) are a best response.
    \item Draw the two best response correspondences BR(\(x\)), BR(\(y\)) into a
    \(x-y\) plane. How often do they intersect? What does it mean if they
    intersect?
\end{enumerate}

\subsection*{Exercise 3: Cournot Duopoly}

The Cournot duopoly game is defined by:

\begin{itemize}
    \item Players: \(N = \{\text{Firm } 1, \text{Firm } 2\}\)
    \item Actions: Amount of good produced, \(x^{(i)} \in [0, \infty)\) for \(i \in \{1, 2\}\)
    \item Payoffs: \(\pi^{(i)}(x^{(1)}, x^{(2)}) = [a - b (x^{(1)} + x^{(2)})] x^{(i)} - c x^{(i)}\)
\end{itemize}

\textbf{Show that there is a Nash equilibrium in pure strategies. For simplicity
assume \(a=10, b=1, c=1\)}.

[Hint: For each \(x^{(i)}\) computer BR\((x^{(-i)})\). Then solve simultaneously:
\begin{align*}
    x^{(1)}= \text{BR}(x^{(2)}) \\
    x^{(2)}= \text{BR}(x^{(1)})
\end{align*}
]

\subsection*{Exercise 4: Matching Pennies}

\textbf{Compute the Nash equilibria for the following two games, and interpret the result.}

\begin{equation*}
    \begin{blockarray}{ccc}
        & \text{Left} & \text{Right} \\
        \begin{block}{c(cc)}
            \text{Top} &    (0.8, 0.4) & (0.4, 0.8) \\
            \text{Bottom} & (0.4, 0.8) & (0.8, 0.4) \\
        \end{block}
    \end{blockarray}\qquad
    %
    \begin{blockarray}{ccc}
        & \text{Left} & \text{Right} \\
        \begin{block}{c(cc)}
            \text{Top} &    (3.2, 0.4) & (0.4, 0.8) \\
            \text{Bottom} & (0.4, 0.8) & (0.8, 0.4) \\
        \end{block}
    \end{blockarray}
    \end{equation*}

\subsection*{Bonus Exercise 1: Verifying NE in games with finitely many players \& actions}

Show that to verify whether a strategy profile \(\hat{\sigma} =
(\hat{\sigma}^{(1)}, \dots, \hat{\sigma}^{(n)})\) is a Nash equilibrium, it is
sufficient to check all deviations towards pure strategies.

\textbf{Specifically show that \(\hat{\sigma}\) is a Nash equilibrium if and only if for
all players \(i\) the following two conditions hold:}

\begin{enumerate}[(i)]
    \item All actions that player \(i\) uses give the same payoff: if
    \(\sigma^{(i)}_j > 0\) and \(\sigma^{(i)}_k > 0\) then
    \(\pi^{(i)}(s^{(i)}_j, \hat{\sigma}^{(-i)}) = \pi^{(i)}(s^{(i)}_k,
    \hat{\sigma}^{(-i)})\).
    \item Actions that are not played are not profitable: if \(\sigma^{(i)}_j =
    0\) then \(\pi^{(i)}(s^{(i)}_j, \hat{\sigma}^{(-i)}) \leq
    \pi^{(i)}(\hat{\sigma}^{(i)}, \hat{\sigma}^{(-i)})\).
\end{enumerate}

[Hint: One way to prove the above is once again by contradiction.]

\subsection*{Bonus Exercise 2: Finding games with a non-generic number of equilibria}

\textbf{Find an example of a symmetric 2 player game, with 2 actions per player, with:}

\begin{itemize}
    \item Exactly 2 Nash equilibria
    \item infinitely many Nash equilibria
\end{itemize}

[Note: These should include all Nash equilibria. Not just pure Nash equilibria.]

\end{document}


%
% Chapter 4
%
\chapter {Shor's Semiprime Integer Factorization Algorithm}

Shor's algorithm is a polynomial-time quantum algorithm for semiprime integer factorization. In comparison, the time complexity of the most efficient known classical factoring algorithm is superpolynomial.

We chose Shor's algorithm because it is one of the most significant quantum algorithms, and because the number of qubits and the number of quantum operations required are proportional to the input size. The number of operations is particullarly relevant since it makes the errors introduced by the physical gates an important consideration.

\section{Algorithm}

The problem that Shor's algorithm solves is the following: given a semiprime integer \textit{N}, find its two prime factor \textit{p} and \textit{q}.

Shor's algorithm combines both classical and quantum computations, and the procedure to perform it is the following:
\begin{enumerate}
    \item Pick a random integer $1 < a < N$.
    \item Check whether $a$ is a factor by determining whether $a$ and $N$ are comprime. If they are, we can compute the factors. Otherwise continue with the rest of the algorithm.
    \item Use a period-finding quantum subroutine to find the period $r$ of the function $f(x)=a^{x} \ mod \ N$.
    \item If $r$ is odd, then go back to step 1. If $r$ is even, go to the next step.
    \item If $a^{\frac{r}{2}} \equiv -1  \ mod \ N$, then go back to step 1.
    \item Either $a^{\frac{r}{2}} - 1$ or $a^{\frac{r}{2}} + 1$ shares a factor with $N$.
\end{enumerate}

\section{Q\# Implementation}

In order to take advantage of the tools built around Q\#, we use a modified implementation of Shor's algorithm found in Microsoft's quantum samples GitHub repository.

\todo{Add reference to Microsoft's quantum samples repository.}

\todo{Breakdown the implementation into different sections and describe each one (similar to what is done in the "Learn Quantum Computing with Python and Q\#" book).}

The following Q\# code presents a top-level implementation of Shor's algorithm.

\begin{lstlisting}[language=C]
@EntryPoint()
operation FactorSemiprimeInteger(N : Int) : (Int, Int) {

    // Check the most trivial case where N is pair.
    if (N % 2 == 0) {
        return (2, N / 2);
    }

    mutable factors = (1, 1);
    mutable foundFactors = false;
    repeat {

        // Start by guessing a coprime to N.
        let coprimeGuess = DrawRandomInt(1, N - 1);

        // If the guess number is a coprime, use a quantum algorithm for period finding.
        // Otherwise, the GCD between N and the coprime guess number is one of the factors.
        if (IsCoprimeI(N, coprimeGuess)) {
            let period = EstimatePeriod(N, coprimeGuess);
            set (foundFactors, factors) = CalculateFactorsFromPeriod(N, coprimeGuess, period);
        } else {
            let gcd = GreatestCommonDivisorI(N, coprimeGuess);
            set (foundFactors, factors) = (true, (gcd, N / gcd));
        }
    }
    until foundFactors

    return factors;
}
\end{lstlisting}

\section{Quantum Subroutine}

\todo{Show the circuit representation of the quantum subroutine.}

The following Q\# code implements the period finding quantum subroutine:

\begin{lstlisting}[language=C]
    @EntryPoint()
    operation EstimatePeriodInstance(N : Int, a : Int) : (Bool, Int) {

        // Prepare eigenstate register.
        let bitSize = BitSizeI(N);
        use eigenstateRegister = Qubit[bitSize];
        let eigenstateRegisterLE = LittleEndian(eigenstateRegister);
        ApplyXorInPlace(1, eigenstateRegisterLE);

        // Prepare phase register.
        let bitsPrecision =  2 * bitSize + 1;
        use phaseRegister = Qubit[bitsPrecision];
        let phaseRegisterLE = LittleEndian(phaseRegister);

        // Prepare oracle for quantum phase estimation.
        let oracle = DiscreteOracle(ApplyOrderFindingOracle(N, a, _, _));

        // Execute quantum phase estimation.
        QuantumPhaseEstimation(oracle, eigenstateRegisterLE!, LittleEndianAsBigEndian(phaseRegisterLE));

        let phaseEstimate = MeasureInteger(phaseRegisterLE);

        // Reset qubit registers
        ResetAll(eigenstateRegister);

        // Return period calculation based on estimated phase.
        return CalculatePeriodFromPhaseEstimate(N, bitsPrecision, phaseEstimate);
    }
\end{lstlisting}