% Chapter X

\chapter{Decisions} % Chapter title

\label{Decisions} % For referencing the chapter elsewhere, use

Figaro also contains the ability to solve and query structured decision problems. These types of models, also known as influence diagrams, are generalizations of Bayesian networks that contain additional decision and utility variables. Figaro generalizes ordinary decision models by allowing the information on which a decision is based to be an arbitrary data structure. Also, the full power of the programming language is available to build decision models. However, Figaro does require that the possible values of the decision variables themselves be discretely enumerated.

In this section, we first give a very brief introduction into decision models and decision-making. We then provide a small example of decision-making in Figaro. We also delve deeper into the decision- making implementation in Figaro. Finally, we discuss the different ways that decision-making can be performed on single and multiple decision models.

\section{Decision models}

Decision models are generalizations of Bayesian networks that contain two additional variable types. The first is a decision variable, which represents a set of actions that a decision-maker can perform. The parents of a decision variable represent the information available to the decision-maker at the time of the decision. Decision models also contain utility variables, which represent some gain or loss in the model that directly or indirectly depends upon some previous decisions or random variables.

The purpose of a decision model is usually to compute an optimal policy for each decision in the model, where a policy defines what action a decision-maker should take for every possible value of the decision's parent variable(s). An optimal policy is when every action specified by the policy for each value of the parents is optimal with respect to some measure. To measure the optimality of an action, Figaro uses the maximum expected utility of the action. That is, for each value of a decision's parents, Figaro determines the action that will result in the highest expected utility of the model.

\section{Basic example}

Using Figaro's decision-making capabilities is generally quite simple. For example, consider the code for a simple decision model shown below:

\begin{flushleft}
\marginpar{This example can be found in SingleDecision.scala}
\texttt{import com.cra.figaro.language.\_
\newline import com.cra.figaro.algorithm.decision.\_
\newline import com.cra.figaro.library.compound.\_
\newline import com.cra.figaro.library.decision.\_
\newline
\newline val market = Select(0.5 -> 0, 0.3 -> 1, 0.2 -> 2)
\newline val survey = CPD(market,
\newline \tab 0 -> Select(0.6 -> 0, 0.3 -> 1, 0.1 -> 2),
\newline \tab 1 -> Select(0.3 -> 0, 0.4 -> 1, 0.3 -> 2),
\newline \tab 2 -> Select(0.1 -> 0, 0.4 -> 1, 0.5 -> 2))
\newline
\newline val found = Decision(survey, List(true, false))
\newline
\newline def valueFcn(f: Boolean, m: Int): Double = \{
\newline \tab if (f) \{
\newline \tab m match \{
\newline \tab case 0 => -7.0
\newline \tab case 1 => 5.0
\newline \tab case 2 => 20.0
\newline \}
\newline \} else \{
\newline\tab  0.0
\newline \}
\newline \}
\newline
\newline val value = Apply(found, market, valueFcn)
\newline
\newline val alg = DecisionVariableElimination(List(value), found)
\newline alg.start()
\newline alg.setPolicy(found)
}
\end{flushleft}

The first four lines import the packages needed for decision models. The elements \texttt{market} and \texttt{survey} are random variables in a normal Figaro model. We create a decision variable called \texttt{found} that uses the element \texttt{survey} as a parent, with the possible actions of the decision as \texttt{true} or \texttt{false}. The element named \texttt{value} is a utility variable that computes a \texttt{Double} conditioned upon the action of the decision (\texttt{found}) and the current value of the \texttt{market} element. It uses the function \texttt{valueFcn} to compute current utility. Finally, we use Figaro's decision variable elimination to compute an optimal policy for the \texttt{found} decision, and set the policy in the \texttt{found} element when the algorithm completes so that it can be used for querying.

\section{Decisions in Figaro}

As can be seen in the previous section, decision-making can be implemented in Figaro with little effort. Decisions are created using the \texttt{Decision[T,U]} element. The \texttt{Decision[T,U]} element actually inherits from \texttt{Chain}; that is, a decision is simply an element that uses an \texttt{Element[T]} as a parent, and generates an \texttt{Element[U]} as the action. A new decision is instantiated simply as:

\begin{flushleft}
\texttt{Decision(Flip(0.7), List(0, 1, 2))}
\end{flushleft}

where the first argument is the parent of the decision, and the second argument is a list of the possible actions of the decision. The possible actions must always be finite and discrete. However, the parent of a decision may be an element over any Scala type. So, we could imagine making a decision based on a social network or a DNA sequence. One thing to note is that decision elements only support single parent decisions. However, multiple parent decisions can be easily created by grouping several parent elements into an element tuple. There are various other ways to instantiate a decision that can be found in the code for the \texttt{Decision} class.

Also, the no-forgetting assumption in decision models is not explicitly enforced in Figaro, hence Limited Memory Influence Diagrams (LIMIDs) can be represented in Figaro, though there is not an explicit LIMID reasoning algorithm implemented.

In decision models, there are also variables that represent the utility of the model. In Figaro, there is no need to explicitly create a utility element; this can be easily done using the \texttt{Apply} element, as shown in the example above. Utility elements must be of type \texttt{Element[Double]}.

A decision is similar to a chain, but unlike the chain, a decision element can change its functionality after an optimal policy has been computed for the decision. Most of the time, setting the policy of a decision can be done simply through the algorithm that computes the optimal policy. However, a user may manually set the policy of a decision element by calling the \texttt{setPolicy} function of the decision, defined as:

\begin{flushleft}
\texttt{def setPolicy(new\_fcn: (T => Element[U])): Unit}
\end{flushleft}

That is, setting the policy of a decision is just providing a new function from the value of a parent to an \texttt{Element[U]}. Users can also get the policy for a specific value of the parent by calling \texttt{getPolicy(p: T): Element[U]}. Various other ways to set the policy can also be found in the Decision code.

\section{Single decision models and policy generation}

Single decision models can be created in Figaro by simply inserting a \texttt{Decision} element into the model. Once the model has been created, the goal is usually to compute the optimal policy for the decision that maximizes the expected utility of the model. This is done as two explicit steps in Figaro;computing the expected utility of each parent and decision pair, then determining the decision that has the maximum expected utility for each parent value. The policy is then set as a function that returns the maximum expected utility decision as a \texttt{Constant}  for any parent value. This policy computation is performed using one of Figaro's built-in inference algorithms. Two alternative methods are provided. One is generally used when the support of the parent is finite, the other when it is infinite. However, there are some cases where the support is finite but very large and the infinite support method is preferable. Alternatively, for some distributions with infinite support, like Poisson or Geometric, only a small number of values are likely, and the finite support method can be used.

\subsection{Finite parent support}

In this case, computing the optimal policy can be performed using the variable elimination, importance sampling, or Metropolis-Hastings algorithms. In addition to the normal parameters that each algorithm takes (as explained in previous sections), the decision version of these algorithms also takes a \texttt{List[Element[Double]]} that indicates the utility nodes in the model. The target of the algorithm is always the decision you wish to compute an optimal policy for. To find the optimal policy for discrete decisions, you simply instantiate one of the algorithms, for example:

\begin{flushleft}
\texttt{val alg = DecisionVariableElimination(List(value), found)
\newline val alg = DecisionImportanceSampling(10000,	List(value), found)
\newline val alg = DecisionMetropolisHastings(10000, ProposalScheme.default,
1000, List(value), found)
}
\end{flushleft}

Where \texttt{List(value)} is the list of utilities in the model, and \texttt{found} is the decision. To compute the optimal policy, you simple start the algorithm, i.e., \texttt{alg.start()}. One the algorithm has completed running, you can call \texttt{alg.setPolicy(found)}, which will set the optimal policy in the \texttt{Decision} element that was computed from the algorithm.

\subsection{Infinite parent support}

When the parent(s) of a decision have infinite support, it is more difficult to compute an exact optimal policy. This is because it is not possible to compute the maximum expected utility action for each value of the parent since the range of the parent is infinite. In such a case, we use Figaro's sampling algorithms to compute an \emph{approximate} optimal policy that attempts to provide a maximal expected utility decision for any possible value of the parent. Since we use sampling algorithms to compute the approximation, only importance sampling and Metropolis-Hastings can be used with continuous decisions.

Instantiating a decision with infinite parent support is similar to finite parent support, except that one must explicitly instantiate a \texttt{NonCachingDecision}, which is based on \texttt{NonCachingChain}:

\begin{flushleft}
\texttt{NonCachingDecision(Normal(0.0, 1.0), List(0, 1, 2))}
\end{flushleft}

The creation of the algorithm and setting of the policy is the same as discrete decisions. Internally in Figaro, however, there are major differences between the implementation of policies for discrete and continuous decisions.

When a sampling algorithm is run on a continuous decision, the algorithm records the utility of the model for each parent and action value that is randomly sampled. When \texttt{setPolicy} is called on the algorithm, all of the generated samples are stored in the decision element. That is, no optimal policy is generated when \texttt{setPolicy} is called; the optimal action to take for a parent value is only computed when the model is queried for a decision with a particular parent value.

When the decision is queried, i.e., \texttt{getPolicy(p: T)} or \texttt{generate()} is invoked on the decision element, the optimal action for parent value p is computed using a nearest-neighbor method. The N closest samples to the parent value are retrieved from the stored samples, the expected utility is computed for each possible action, and the maximum is chosen as the optimal action for this parent value.

Since nearest-neighbor is used to find nearby parent values, a distance metric must also be defined for the parent type \texttt{T}. To use an \texttt{Element[T]} as the parent to a decision, the type \texttt{T} must implement the \texttt{Distance[T]} trait, defined as:

\begin{flushleft}
\texttt{trait Distance[T] \{
\newline \tab def distance(that : T) : Double
\newline \} }
\end{flushleft}

This trait just defines a function that computes a Double distance between two values of the type. For built-in types (Double, Int and Boolean), we use Scala's implicit conversion mechanism to automatically handle conversion to a class that implements the \texttt{Distance[T]} interface so that no changes are needed by the user. For examples, the Double implementation is:

\begin{flushleft}
\texttt{case class DoubleDistance(value : Double) extends Distance[Double] \{
\newline \tab def distance(that : Double) = math.abs(value-that)
\newline \}
\newline implicit def double2Dist(x : Double) = DoubleDistance(x)
}
\end{flushleft}

See the \texttt{Distance} class for more details on default conversions of basic types and parents that are element tuples. For user defined classes, all the user needs to do is implement a distance function in the \texttt{Distance} trait, and the type can be used as a parent to a decision element. For instance, we can use an element over the range of graphs as a parent to a decision by declaring the \texttt{dGraph} class as such:

\begin{flushleft}
\texttt{class dGraph() extends Distance[dGraph] \{
\newline \tab ...
\newline \tab def distance(that: dGraph): Double = \{
\newline \tab \tab ...
\newline \}
\newline \} }
\end{flushleft}

Since the number of samples generated from the algorithm may be large, and the optimal policy method retrieves the nearest neighbors for \emph{every} parent value that is queried from the decision, computing the optimal action can be quite slow. To ameliorate this slowdown, Figaro stores the samples in an index. The default implementation is a VP-index, used for metric distances. Different indices can be created an integrated as well. See the \texttt{Index} and \texttt{DecisionPolicy} classes for more information.

\section{Multiple decision models and policy generation}

Figaro also supports for multiple decision models using a backward induction algorithm.
In this algorithm, the optimal policies are computed in reverse order on a set of partially ordered decision variables. To create policies for multiple decision models, a user uses the multi-decision versions of the algorithms:

\begin{flushleft}
\marginpar{A multiple decision example can be found in MultiDecision.scala}
\texttt{val alg = MultiDecisionVariableElimination(List(utility1, utility2), decision1, decision2)
\newline val alg = MultiDecisionImportanceSampling(10000,	List(utility1, utility2), decision1, decision2)
\newline val alg = MultiDecisionMetropolisHastings(10000, maker: ProposalMakerType, 1000, List(utility1, utility2), decision1, decision2)
}
\end{flushleft}

Note that the interface for the \texttt{MultiDecisionMetropolisHastings} is different than the \texttt{DecisionMetropolisHastings} algorithm. \texttt{MultiDec\-isionMetropolisHastings} needs a \texttt{ProposalMakerType}, since inside the algorithm, \texttt{Decision\-MetropolisHastings} is run for each decision. The \texttt{ProposalMakerType} is defined as:

\begin{flushleft}
\texttt{type ProposalMakerType = (Universe, Element[\_]) => ProposalScheme}
\end{flushleft}

Only the one-time versions of the decision algorithms can be used for multi-decision models. To compute the optimal policy for every decision in the model, the user simply does, for example,:

\begin{flushleft}
\texttt{val propmaker = (mv: Universe, e: Element[\_]) => ProposalScheme.default(mv)
\newline val alg = MultiDecisionMetropolisHastings(200000, propmaker, 20000, List(value, cost), test, found)
\newline alg.start()}
\end{flushleft}

The ProposalMaker for this small example just uses the default proposal for each instantiation of \texttt{DecisionMetropolisHastings} for a decision. However, we could also change the proposal scheme for each decision. There is also no need to call \texttt{alg.setPolicy}, since the multi-decision algorithm will set the optimal policy for each decision as it is needed for backward induction. Figaro will automatically compute the partial order of the decisions that are in the parameter list.


\chapter{Conclusion and Future Work}
\label{ch:Conclusion-and-Future-Work}
In this study, we have shown that the application of a clustering step that utilizes dimensionality reduction techniques such as \gls{t-sne} and hierarchical, density-based clustering in the form of \gls{hdbscan} leads to significant improvements in forecasting accuracy when taking individual households into consideration. While this technique is certainly more complex, in particular with regards to the number of steps and moving parts associated with the entire pipeline, we maintain that the benefits in terms of improved forecasting accuracy outweigh the overall increase with regards to the time and effort it would take to train and set up such a model. The practicality of the model lies in the availability of the data that it requires to function -- primarily with respect to historical energy consumption data for the individual households in question (which is becoming easier and easier to obtain thanks to the prevalence of smart meters) and meteorological data that can easily be obtained from numerous sources. Furthermore, it is highly likely that, given enough historical data, the need to further train the model(s) after the initial setup is rather low further compounding the efficacy of our method.

\noindent \newline Furthermore, one of the benefits of our method that we previously discussed is that no prior knowledge of the number of clusters is required. As there is no guarantee that any 2 individual households contain a similar number of \textit{repeating} patterns we avoid running into the problem of overly generalizing a single working solution that may or may not work given said change in energy consumption patterns and instead present a solution that could potentially extend to a much larger scale. A potential issue with this implementation however, is that an individual household \textit{may} contain a large number of repeating consumption patterns which could possibly lead to an overall decline in what can already be considered sub-par performance from our classifier. That said, there is definitely room for improvement that could accommodate these potential risks, specifically with regards to the feature engineering step -- for example, improvements in classifier accuracy could be seen through the utilization of a more efficient classifier. Alternatively, the current lack of contextual information that serves to explain the emergence of the clusters as part of the clustering step could likely be the reason for obtaining sub-par accuracy scores as, in its current iteration, the premise of our clustering step was to group together days that exhibited the highest similarity purely in terms of their energy consumption patterns and, given that this information is not readily available to us when considering a new day, we are left reaching for straws when attempting to explain when any individual household is likely to observe energy consumption patterns that fall within any of the obtained clusters. Evidently, temporal and meteorological information is not enough to explain the emergence of said clusters and other information (perhaps patterns in terms of cluster labels leading up to the new sample) could serve to improve classifier accuracy. This is definitely an area of this study that could be looked into as part of future research. Additionally, regardless of the fact that the performance of our forecasting model is the highlight of this paper, it is interesting to note that a byproduct of our method is the potential to extract insights into variables that have an effect on the daily energy consumption patterns of unique households. A cursory glance at applying our method to a portion of the data at hand, as an example of the insights that we can obtain, shows us that some households have frequently occurring patterns that tend to deviate among the different days of the week while other households have an even bigger separation across months of the year or even among meteorological factors such as the temperature or chance of rain.

\noindent \newline To conclude, we note that, as a result of pre-clustering our data, and then training separate models on a per-cluster basis we achieved an improvement in overall forecasting accuracy with superior \gls{mape} scores in contrast to the current state-of-the-art (\gls{lstm} networks, clustering based on K-means, etc.).


\subsection{Continuous utility functions}

With non-discrete choice a consumer chooses how much of product \(x\) to consume.

The utility function is of the form:

\(U_i(x_1,...,x_m;d)\)

And the consumer chooses how much of \(x_i\) to consume to maximise this, subject to the budget constraint.

We include features relating to the individual, \(d\).

\subsection{Discrete choice}

The utility customer \(i\) gets from product \(j\) is:

\(U_{ij}=f_i(p,d)+\epsilon_{ij}\)

The customer chooses the product with the highest utility.

\subsection{The outside option}

We need to know the market share of the outside option. Do this theoretically. Eg number of customers in area, and 1 per day.


\chapter{Introduction}\label{chap:introduction}

A neural network, also known as an Artificial Neural Network (ANN), is an algorithm that mimics the way a human brain operates. It took millions of years of evolution for the human brain to achieve the level of intelligence we observe today. This intelligence helps us quickly interpret and evaluate what we see in our surroundings. For example, consider the following image of hand-written digits from the MNIST dataset \cite{mnist}:

\begin{figure}[h]
	\centering
	\includegraphics[width=0.5\linewidth]{images/introduction/digits.png}
	\caption[Hand-written digits]%
	{\textbf{Hand-written digits}: Each hand-written digit is a $28\times28$ pixel grayscale image. The entire MNIST dataset contains a total of $70000$ such images that split into a training set of $60000$ images and a test set of $10000$ images.}
	\label{fig:digits}
\end{figure}

One can quickly recognize these digits as $04192$, thanks to the network of billions of neurons available in our brain that makes it easy to identify visual patterns. Past experiences and memories stored in our brain make this process so simple that it happens subconsciously most of the time. This simple process becomes much more difficult when we try to write computer programs to identify similar patterns due to the lack of precise rules and hundreds of exceptions and varieties of a single pattern.

Neural networks tackle this problem by inferring rules from a large set of related training data. For example, to train a neural network to efficiently recognize hand-written digits shown in figure \ref{fig:digits}, a dataset large enough to include different styles of hand-written digits is needed.

Neural networks and their variations such as Convolutional Neural Networks (CNNs), Recurrent Neural Networks (RNNs) are proven to be useful in many different application areas such as image recognition \cite{image_recon}, machine translation \cite{russian}, recommender systems \cite{recommender}. Despite this state-of-the-art performance, neural networks are computationally complex and memory-intensive due to their deep structures.

Sparse Neural Networks are a viable option to make neural networks less complex and make them memory efficient. Such sparsity in neural networks can be induced by pruning weights, utilizing skip connections, or generating random architectures based on graphs. Sparsity in a neural network can reduce that network's size by many times with little to no drop in performance \cite{sparse_nn, dey, liu}. Therefore, in this thesis, we implement two different ways to achieve sparsity in Recurrent Neural Networks and analyze its performance impact.

% -----------------------------------------------------------------------------------------------------------
% ------------------------------------------------ MOTIVATION -----------------------------------------------
% -----------------------------------------------------------------------------------------------------------

\section{Motivation}\label{section:motivation}

As stated before, deep neural networks are likely to have an increased performance but at the cost of higher complexity and increased fast memory requirements. One way to mitigate this issue while maintaining the performance is to introduce sparsity into a network's connections \cite{deep_res}. For example, Mao et al. in \cite{mao} report a higher-compression ratio with coarse-grained pruning without loss of accuracy while saving about twice the memory references. Similarly, Sun et al. in \cite{sparse_face} reported that the sparse ConvNet model, which only has 12\% of the original parameters, still performs similarly to the baseline model.

These are just a few examples where Sparse Neural Networks have proven advantageous in time, energy, and memory savings. Sparsity in traditional neural networks and CNNs is studied widely by many researchers but is not explored much in Recurrent Neural Networks that are difficult to train due to their nonlinear iterative nature. Sparse structures in traditional neural networks have shown a promise of training potential \cite{sparse_nn} which, if applied to Recurrent Neural Networks, can also make training RNNs less difficult by reducing their network size while retaining their performance.

% -----------------------------------------------------------------------------------------------------------
% -------------------------------------------- RESEARCH QUESTIONS -------------------------------------------
% -----------------------------------------------------------------------------------------------------------

\newpage
\section{Research questions}\label{section:research_questions}

The primary research goal of this master thesis is to investigate the effects of sparse structure on the performance of the Recurrent Neural Networks and its variants, namely Long Short-Term Memory and Gated Recurrent Unit. To do so, we have defined the following set of correlated research questions:

\begin{enumerate}
	\item\label{rq:q1} What is the effect of weights pruning on a recurrent network's accuracy?

	\item\label{rq:q2} What percentage of weights pruning is permissible without triggering a significant reduction in the performance?

	\item\label{rq:q3} After pruning a certain percent of weights, if we see a significant reduction in the accuracy,  how many re-training epochs can regain accuracy?

	\item\label{rq:q4} How does a randomly structured recurrent network's performance correlate with the graph properties of its internal structure?

	\item\label{rq:q5} Is it possible to predict a randomly structured recurrent network's performance using the graph properties of its base random graph?
\end{enumerate}

We will answer all these questions for four different recurrent networks, namely RNN with Tanh nonlinearity (RNN-Tanh), RNN with ReLU nonlinearity (RNN-ReLU), Long Short-Term Memory (LSTM), and Gated Recurrent Unit (GRU), by following the approach explained in section \ref{section:proposed_approach}.

% -----------------------------------------------------------------------------------------------------------
% -------------------------------------------- PROPOSED APPROACH --------------------------------------------
% -----------------------------------------------------------------------------------------------------------

\newpage
\section{Proposed approach}\label{section:proposed_approach}

To investigate the effects of sparse structures in recurrent networks, we propose the following three experiments:
\begin{enumerate}
	\item \textbf{Investigating the effects of weights pruning on recurrent networks}: \\
	    In this experiment, we prune input-to-hidden and hidden-to-hidden weights, both simultaneously and individually.

	    We start by training a recurrent network on a dataset for a certain number of epochs. Once this training is complete, we follow the process shown in the following flowchart:

	    \begin{figure}[h]
            \centering
            \includegraphics[width=0.5\linewidth]{images/introduction/flow_1.png}
            \caption[Flowchart for the pruning experiment]{The basic flowchart depicting the process of pruning and re-training a trained recurrent network.}
            \label{fig:flowchart_pruning}
        \end{figure}

    	 To outline this flowchart, once the initial training is complete, retrieve the learned weights of the trained model, prune the lower $p\%$ of weights (where $p \in \mathbb{Z}:p \in [1, 100]$), and re-train this pruned model to check for the number of epochs required to regain accuracy.

    	 This experiment will help answer research questions \ref{rq:q1}, \ref{rq:q2}, and \ref{rq:q3}.

	\item \textbf{Analyzing the performance of recurrent networks with randomly structured recurrent networks}: \\
	    We start by generating randomly structured neural networks by following the technique described by Stier et al. in \cite{julian} that generate Sparse Neural Networks.

        After generating Sparse Neural Networks, we introduce recurrent connections to generate Sparse RNNs. These recurrent connections are necessary to make each subsequent run dependent on the previous run.

        Once we have Sparse RNNs, we train them on a dataset and compute the correlation between its accuracy and its internal structure's graph properties.

        This experiment will help answer the \ref{rq:q4}th research question.

    \item \textbf{Performance prediction of a randomly structured neural network:}: \\
        Once we have trained Sparse RNNs, we train three different regressor algorithms with graph properties as features and corresponding accuracy as the target. Since this is a regression problem, we finally report an R-squared value for each RNN variant and each regressor algorithm.

        This experiment will help answer the \ref{rq:q5}th research question.
\end{enumerate}

All these three approaches are described in detail in the later chapters.

% -----------------------------------------------------------------------------------------------------------
% ------------------------------------------------ STRUCTURE ------------------------------------------------
% -----------------------------------------------------------------------------------------------------------


\chapter{Hartree-Fock}

\begin{Exercise}
    Answer each of the following in one sentence, using words only.
    \Question{Define canonical Hartree-Fock orbitals.}\label{canon_hf}
    \Question{Explain why the choice of Hartree-Fock orbitals is not unique.}\label{unique_hf}
\end{Exercise}

\begin{Answer}
    \ref{canon_hf}. Hartree-Fock orbitals are ``canonical'' when the Lagrange multiplier matrix is diagonal.
    \ref{unique_hf}. The Hartree-Fock energy and the orbital overlaps are invariant to a unitary transformation, so any unitary variation of the canonical orbitals satisfies the Hartree-Fock optimization conditions.
\end{Answer}

\begin{Exercise}
    Briefly explain how the Lagrangian approach to constrained optimization works. Draw pictures where necessary.
\end{Exercise}

\begin{Exercise}
  Determine the functional derivatives of the Hartree-Fock Lagrangian,
  $\dfr{\d\mc{L}}{\d\y_k^*}$
  and
  $\dfr{\d\mc{L}}{\d\y_k}$.
\end{Exercise}

\begin{Exercise}
    Derive the following expression for the energy expectation value of a Slater determinant, known as the \textit{first Slater rule}.
    \begin{align*}
      \ip{\F|\op{H}_e|\F}
    =
    \sum_{i}^n
      \ip{\y_i|\op{h}|\y_i}
    +\fr{1}{2}\sum_{ij}^n
      \ip{\y_i\y_j||\y_i\y_j}
    \end{align*}
\end{Exercise}


\documentclass[a4paper, fleqn, 10pt]{report}
\usepackage[utf8]{inputenc}
\usepackage{t1enc}
\usepackage[table, usenames,dvipsnames,svgnames]{xcolor}
\usepackage[pdftex]{graphicx}
\usepackage{booktabs}
\usepackage{setspace}
\onehalfspacing
\usepackage{fullpage}
\usepackage{enumerate}
\usepackage{multicol}
\usepackage{tikz}
\usepackage{amsmath, amsthm, amssymb}
\usepackage{caption}
\usepackage{subcaption}
\usepackage{multirow}

\usepackage{newtxtext}
\usepackage[libertine]{newtxmath}
%\usepackage{fourier}

\theoremstyle{definition}
\newtheorem{prb}{Problem}[chapter]
\newenvironment{prb*}[1]
  {\renewcommand\theprb{\thechapter.\arabic{prb}\rlap{$^{#1}$}}\prb}
  {\endprb}

\newcommand{\R}{\mathbf{R}}
\newcommand{\N}{\mathbf{N}}
\newcommand{\Z}{\mathbf{Z}}
\newcommand{\Q}{\mathbf{Q}}
\newcommand{\C}{\mathbf{C}}
\renewcommand{\P}{\mathbf{P}}

\renewcommand{\labelitemi}{$\blacktriangleright$}
\renewcommand{\tan}{\mathrm{tg}}

\newcommand{\mc}[1]{{\color{Blue}\tt #1}}
\newcommand{\mck}[1]{{\tt#1}}

\DeclareMathOperator{\ch}{cosh}

\frenchspacing

\title{Introduction to Matlab Programming}
\author{Problems \\[2em] Budapest University of Technology and Economics}
\date{2014}

\begin{document}
\maketitle
\chapter{Arrays and Graphics}
\section{Exercises}
\begin{prb*}{1}
Use the documentation to look up the functions: \mc{atan} and \mc{atan2}.
Illustrate the similarity and difference between them.
\end{prb*}

\begin{prb*}{1}
What are the results of the following expressions and why:
\[\frac{1}{0},\: \frac{0}{0},\: \frac{0}{\infty},\: \frac{\infty}{0},\: \frac{\infty}{\infty},\: \infty + \infty,\: \infty - \infty,\: 0\cdot\infty, \: 1^\infty, 0^0,\: 0^\infty,\: \infty^0,\: \infty^\infty.\]
\end{prb*}

\begin{prb*}{1}
Let $x:=3$ and $y:=7,$ using variables $x$ and $y$ find the value of the following expressions:
\begin{multicols}{3}
\begin{enumerate}[a)]
 \item $\dfrac{x^2-y^2}{x^3y}$
 \item $x^y-y^x$
 \item $\sin(\pi(x+y)) - \sqrt{y-x}$
 \item $\log_x(y)$
 \item $e^x + e^{-x} - 2\ch(x)$
 \item $\sqrt[x]{y}$
\end{enumerate}
\end{multicols}
\end{prb*}

\begin{prb*}{1}
Write a program, that converts from kilometers to miles by reading an input (number) from the user.
\end{prb*}

\begin{prb*}{1}
Explain the results of the following expressions:
\[\mc{uint8}(5-17), \quad [\text{'M'},\: 65,\: 84,\: 76,\: 65,\: 66], \quad \mc{int8}(1-2^{10}), \quad 1+0.1\times\mc{eps}\: \text{ opposed to }\: 1+100\times\mc{eps}.\]
\end{prb*}

\begin{prb*}{2}
Make the following lists using only the colon operator (\mc{:}), \mc{linspace} and arithmetics:
\begin{multicols}{2}
\begin{enumerate}[a)]
 \item $[0, 2, 4, 6, \dots, 20]$
 \item $[11, 9, \dots, -9, -11]$
 \item $[0.001, 0.01, \dots, 1000, 10000]$
 \item $[1, 2, 4, 8, \dots, 1024]$
 \item $[\underbrace{1,-1,1,-1,\dots, 1,-1}_{20}]$
 \item the list obtained by dividing the unit interval $[0, 1]$ to 5 equal parts (boundary points included)
 \item the list obtained by dividing the interval $[0, 2\pi)$ to 7 equal parts ($0$ included, $2\pi$ excluded)
\end{enumerate}
\end{multicols}
\end{prb*}

\begin{prb*}{1}
Run the following command and explain the result:
\[\mathrm{\mc{char}}(\mathrm{\mc{cumsum}}([117,\:-2,\:-14,\:13,\:-50,\:45,\:-12,\:8,\:3,\:-62,\:53,\:12,\:-2])).\]
Can you do your own version?
\end{prb*}

\begin{prb*}{2}
Make a list $X$ of 20 random integers: $-10\le X_k\le 30$ with uniform distribution.
Now, select the following entries of this list:
\begin{multicols}{2}
\begin{enumerate}[a)]
 \item negative entries
 \item entries greater than or equal to $7$
 \item entries greater than $-5$ and less than or equal to $12$
 \item odd entries
 \item entries divisible by 3 or 7
 \item entries dividing 360
\end{enumerate}
\end{multicols}
\end{prb*}

\begin{prb*}{2}
Define the following functions using anonymus functions:
\begin{multicols}{2}
\begin{enumerate}[a)]
 \item $\mathrm{sum\_n}(n) := 1 + 2 + \dots + n$
 \item $\mathrm{sum\_square}(n):= 1^2 + 2^2 + \dots + n^2$
 \item $\mathrm{fact}(n) := n!$
 \item $\mathrm{binom}(n,k) := \binom{n}{k}$
 \item $\mathrm{ln2}(n) := 1 - \frac{1}{2} + \frac{1}{3} - \frac{1}{4} + \dots + \frac{(-1)^{n+1}}{n}$
 \item $\mathrm{sol\_quad}(a, b) := [\frac{-a-\sqrt{a^2-4b}}{2}, \frac{-a+\sqrt{a^2-4b}}{2}]$
 \item $\mathrm{cum\_avr}([x_1, x_2, \dots, x_n]) := [x_1, \frac{x_1 + x_2}{2}, \dots, \frac{x_1 + x_2 + \dots + x_n}{n}]$
 \item $\mathrm{first}([x_1, x_2, \dots, x_n]) := x_1$
 \item $\mathrm{rest}([x_1, x_2, \dots, x_n]) := [x_2, x_3, \dots, x_n]$
 \item $\mathrm{take}([x_1, x_2, \dots, x_n], m) := [x_1, x_2, \dots, x_m]$
 \item $\mathrm{drop}([x_1, x_2, \dots, x_n], m) := [x_{m+1}, x_{m+2}, \dots, x_n]$
\end{enumerate}
\end{multicols}
\end{prb*}

\begin{prb*}{2}
Make the following matrices using only the colon operator (\mc{:}), \mc{diag}, \mc{zeros},
\mc{ones}, \mc{eye}, \mc{repmat}, \mc{reshape}, \mc{cat}, \mc{flipdim}, \mc{padarray} and arithmetics:
\begin{multicols}{3}
\begin{enumerate}[a)]
\item $\displaystyle
\begin{bmatrix}
0 & 1 & 0 & 1 & 0 & 1\\
1 & 0 & 1 & 0 & 1 & 0\\
0 & 1 & 0 & 1 & 0 & 1\\
1 & 0 & 1 & 0 & 1 & 0
\end{bmatrix}
$
\item $\displaystyle
\begin{bmatrix}
2 & 5 & 0 & 0 & 0 & 0\\
7 & 2 & 5 & 0 & 0 & 0\\
0 & 7 & 2 & 5 & 0 & 0\\
0 & 0 & 7 & 2 & 5 & 0\\
0 & 0 & 0 & 7 & 2 & 5\\
0 & 0 & 0 & 0 & 7 & 2
\end{bmatrix}
$

\item $\displaystyle
\begin{bmatrix}
1 & 1 & 1 & 1\\
2 & 2 & 2 & 2\\
3 & 3 & 3 & 3\\
4 & 4 & 4 & 4
\end{bmatrix}
$

\item $\displaystyle
\begin{bmatrix}
1 & 4 & 7 & 10\\
0 & 0 & 0 & 0\\
2 & 5 & 8 & 11\\
0 & 0 & 0 & 0\\
3 & 6 & 9 & 12\\
0 & 0 & 0 & 0
\end{bmatrix}
$

\item $\displaystyle
\begin{bmatrix}
0 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0\\
0 & 0 & 1 & 1 & 1 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0
\end{bmatrix}
$

\item $\displaystyle
\begin{bmatrix}
0 & 0 & 0 & 3 & 3 & 1 & 1\\
0 & 0 & 0 & 3 & 3 & 1 & 1\\
2 & 2 & 2 & 3 & 3 & 1 & 1\\
2 & 2 & 2 & 3 & 3 & 5 & 5\\
0 & 0 & 0 & 3 & 3 & 5 & 5\\
0 & 0 & 0 & 3 & 3 & 5 & 5
\end{bmatrix}
$
\end{enumerate}
\end{multicols}
\end{prb*}

\begin{prb*}{1}
Make a $10\times10$ multiplication table. Could you do it in modulo $11$ residue class?
\end{prb*}

\begin{prb*}{2}
Make a $5\times6$ matrix $X$ of random integers $0\le X_{ij}\le 50,$
then determine the
\begin{multicols}{3}
\begin{enumerate}[a)]
 \item maximum of each column,
 \item minimum of each row,
 \item sum of the rows,
 \item sum of the even columns,
 \item sum of the first and last columns,
 \item even entries,
 \item number of zeros,
 \item largest entry,
 \item three smallest entries.
\end{enumerate}
\end{multicols}
\end{prb*}

\begin{prb*}{3}
Consider Table \ref{tab:experiment} containing experiment data on 30 subjects.
Make a random test table, and determine the:
\begin{multicols}{2}
\begin{enumerate}[a)]
 \item IDs of all female,
 \item ID of the youngest male,
 \item IDs of those scored $\ge0.5,$
 \item mean and standard deviation of the scores
 \item mean age of those scored $\le 0.2,$
 \item gender ratio,
 \item IDs of females past 35,
 \item mean scores of males younger than 37,
 \item gender ratio of those scored $\ge 0.7,$
 \item IDs of females scored $\le 0.3$ or younger than $40.$
\end{enumerate}
\end{multicols}
\begin{table}[ht!]
\centering
\begin{tabular}{cccc}
\toprule
 ID & Gender (1--M, 2--F) & Age (20--50) & Score (0--1)\\
 \midrule
 1  & 2 & 32 & 0.68\\
 2  & 2 & 28 & 0.78\\
 3  & 1 & 47 & 0.98\\
 4  & 2 & 45 & 0.43\\
 \vdots & \vdots & \vdots & \vdots\\[0.5em]
 30  & 1 & 22 & 0.73\\
 \bottomrule
\end{tabular}
\caption{Example of the experiment data}\label{tab:experiment}
\end{table}
\end{prb*}

\begin{prb*}{3}
Given a round table with 10 seats.
Let $0$ and $1$ denote the empty and occupied seats, respectively.
The seats are randomly taken, that is we have a list of random 0's and 1's.
Count the number of (non-empty) neighbours within distance of 2 for all seats.
How about if the table wasn't round?
\end{prb*}

\begin{prb*}{3}
Plot the following functions in one figure, but in three -- vertically arranged -- seperate axes:
 \[ \frac{\sin(x)}{x},\: -10\le x\le 10, \qquad \sin\left(\frac{1}{x}\right),\: -10\le x\le 10, \qquad x^2e^{-x}\cos(5x),\: 0\le x\le 10.\]
\end{prb*}

\begin{prb*}{1}
Simulate a hundred rolls with two dice, and plot the histogram of the result.
\end{prb*}

\begin{prb*}{1}
 Plot the pie chart of the age data in Table \ref{tab:experiment} for the age groups: 20--30--40--50,
 highlight the most numerous group.
\end{prb*}

\begin{prb*}{1}
 Make 5 figures arranged in an X pattern.
 Make sure that your solution works with any screen resolution.
\end{prb*}

\begin{prb*}{2}
 Draw the following pictures using graphics primitives.
 \begin{figure}[ht!]
\centering
\includegraphics[height=4cm]{stop}\hspace{4cm}
\includegraphics[height=4cm]{owl}
\end{figure}
\end{prb*}

\begin{prb*}{2}
Design your own clock showing the time given by a triplet \mck{[h, m, s]}.
\end{prb*}

\newpage
\section{Projects}
\subsection*{Random Walk in 2D$^{10}$}
Consider a particle sitting at the origin.
Every step the particle makes one of the moves: left, right, up or down
randomly with equal probability.
Plot the particle's trajectory for a few hundred steps as shown in Figure \ref{fig:rw}.

\begin{figure}[ht!]
\centering
\includegraphics[width=0.5\linewidth]{rwFig}
\caption{Trajectory of a random walk.}\label{fig:rw}
\end{figure}

\subsection*{Monte Carlo Simulation$^{20}$}
Consider the square having vertices $A(1,-1),\: B(1,1),\: C(-1,1),\: D(-1,-1)$ and -- inside this square -- the unit disk.
Choose $n$ random points $P(x,y)$ inside the square, i.e. $-1\le x,y \le 1.$
Let $N$ denote the number of points inside the disk, that is $x^2+y^2\le 1.$
Now, if $n$ is large enough, then
\[\frac{N}{n} \approx \frac{A_{\text{disk}}}{A_{\text{square}}} = \frac{\pi}{4}.\]
Write a program that simulates the above process.
Display the unit disk and the points, also plot the relative frequency: $\frac{N}{n}$ for
all $n=1,2,\dots$ as shown in Figure \ref{fig:mc}.

\begin{figure}[ht!]
\centering
\includegraphics[width=0.48\linewidth]{mcFig1}
\includegraphics[width=0.48\linewidth]{mcFig2}
\caption{Results of the simulation.}\label{fig:mc}
\end{figure}

\subsection*{Convay's Game of Life$^{30}$}
This game is played on an $n\times n$ grid of 1's and 0's,
where 1 and 0 represent living and dead cells, respectively.
It is clear that every cell has exactly 8 neighbours,
except along the border.
However, we can view these border cells, as if they had 8 neighbours,
considering the cells outside the border dead.
The population of cells advances to a new generation by
applying the following rules for every cell (from Wikipedia):
\begin{itemize}
 \item Any live cell with fewer than two live neighbours dies, as if caused by under-population.
 \item Any live cell with two or three live neighbours lives on to the next generation.
 \item Any live cell with more than three live neighbours dies, as if by overcrowding.
 \item Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
\end{itemize}

Write a program that for a given table, computes the next generation.
For example:
\[
\begin{bmatrix}
 0 & 1 & 1 & 0\\
 1 & 1 & 0 & 1\\
 0 & 1 & 1 & 1\\
 1 & 0 & 1 & 1
\end{bmatrix}
\quad \longrightarrow
\quad
\begin{bmatrix}
 1 & 1 & 1 & 0\\
 1 & 0 & 0 & 1\\
 0 & 0 & 0 & 0\\
 0 & 0 & 0 & 1
\end{bmatrix}
\]
Look up the \mc{image} object in the documentation, and
use it to display the original and new generation in separate figures.

\subsection*{PageRank$^{30}$}
This algorithm was first used by Google to order search results.
According to Google:
\begin{quote}
PageRank works by counting the number and quality of links to a page to determine a rough estimate of how important the website is.
The underlying assumption is that more important websites are likely to receive more links from other websites.
\end{quote}
From this perspective the internet consists of webpages and links between them (see Figure \ref{fig:graph}).
\begin{figure}[ht!]
 \centering
 \includegraphics[width=0.5\textwidth]{graph}
 \caption{An example graph with $n=4$ edges.}\label{fig:graph}
\end{figure}
The graph in Figure~\ref{fig:graph} is represented as two arrays: vertecies ($V$) and edges ($E$)
in the following way:
\[V=
\begin{bmatrix}
1 & 2 & 3 & 4
\end{bmatrix},
\quad
E=\begin{bmatrix}
1 & 1 & 3 & 3 & 4\\
2 & 3 & 1 & 2 & 2
\end{bmatrix}.
\]
Denote the number of vertices by $n,$ which is $n=4$ in our example.
Now we construct the adjacency matrix $A$ of the graph, that is we have $A_{ij}=1$
if and only if the graph has the edge $i\to j,$ otherwise $A_{ij}=0.$
It could be that, some of the rows have only zero entries, which are quite problematic, therefore
we need to substitute every such row with a row full of ones to get a new matrix $B.$
This means, that if we have webpages that don't link to anywere, than we assume
instead they link to everywhere.
For the example graph, they look like this:
\[
A =
\begin{bmatrix}
0 & 1 & 1 & 0\\
0 & 0 & 0 & 0\\
1 & 1 & 0 & 0\\
0 & 1 & 0 & 0
\end{bmatrix}
\qquad\longrightarrow
\qquad
B =
\begin{bmatrix}
0 & 1 & 1 & 0\\
1 & 1 & 1 & 1\\
1 & 1 & 0 & 0\\
0 & 1 & 0 & 0
\end{bmatrix}.
\]
The next step is to make sure that every row sums up to one, thus we need to normalize the rows of $B$
by which we obtain the matrix $M$ with entries
\[M_{ij} := \frac{B_{ij}}{\sum_{k=1}^n B_{ik}} = \frac{B_{ij}}{B_{i1} + B_{i2} + \dots + B_{in}}.\]
Continuing the example, we have:
\[
M =
\begin{bmatrix}
0 & \frac{1}{2} & \frac{1}{2} & 0\\
\frac{1}{4} & \frac{1}{4} & \frac{1}{4} & \frac{1}{4}\\
\frac{1}{2} & \frac{1}{2} & 0 & 0\\
0 & 1 & 0 & 0
\end{bmatrix}.
\]
In order to regularize the problem, we need to perturb the matrix $M$ with the matrix $S,$
that is \[P:=\alpha M + (1-\alpha)S,\]
where  $S_{ij} := 1/n.$
Following Google's recommendation we set $\alpha := 0.8.$ The example becomes:
\[P = \frac{4}{5}\begin{bmatrix}
0 & \frac{1}{2} & \frac{1}{2} & 0\\
\frac{1}{4} & \frac{1}{4} & \frac{1}{4} & \frac{1}{4}\\
\frac{1}{2} & \frac{1}{2} & 0 & 0\\
0 & 1 & 0 & 0
\end{bmatrix} + \frac{1}{5}
\begin{bmatrix}
\frac{1}{4} & \frac{1}{4} & \frac{1}{4} & \frac{1}{4}\\
\frac{1}{4} & \frac{1}{4} & \frac{1}{4} & \frac{1}{4}\\
\frac{1}{4} & \frac{1}{4} & \frac{1}{4} & \frac{1}{4}\\
\frac{1}{4} & \frac{1}{4} & \frac{1}{4} & \frac{1}{4}
\end{bmatrix}=
\frac{1}{20}
\begin{bmatrix}
1 & 9 & 9 & 1\\
5 & 5 & 5 & 5\\
9 & 9 & 1 & 1\\
1 & 17 & 1 & 1
\end{bmatrix}
\]
Now, in the last step we need to solve the linear equation $P^\top x=x$ for the unkown vector $x.$
This $x$ vector will contain the ranking scores for each webpage.
The equation $P^\top x=x$ is equivalent to the homogeneous equation $(P^\top-I)x=0,$
where $I$ is the $n\times n$ identity matrix.
Due to the earlier regularization, we can be sure there is only one
$x$ vector satisfying this equation\footnote{It is clear that both $x$ and let's say $1.34\cdot x$
imply the same ranking.
So actually, there are infinitely many solutions for $P^\top x = x,$
but they only differ in a scalar factor, thus implying the same ranking.}.
Finally, normalize the result, so that the ranking scores sum up to 1:
\[r := \frac{x}{\sum_{i=1}^n x_i}.\]
The ranking scores for the example: $r = [0.223,\: 0.426,\: 0.223,\: 0.128],$
so the ranking is $R = [2,\: 3,\: 1,\: 4].$

Write a program that for a given $V$ and $E$ computes the ranking.
Use randomly generated test graphs to test your program.
Make sure that the test graph is a simple (directed) graph, i.e. it does not contain
loops or multiple edges.

\chapter{Data Types, Functions and Flow Control}
\section{Exercises}
\begin{prb*}{3}
Create a structure array named {\tt subject} with the following fields: {\tt .name}, {\tt.age}, {\tt.weight}, {\tt.height}
using data from Table~\ref{tab:sub}, and determine the
\begin{multicols}{2}
 \begin{enumerate}[a)]
  \item average age
  \item mean and standard deviation of the weights
  \item names of the 3 oldest subjects
  \item names of those who are younger than $25$
  \item average age of those who are taller than 160\,cm, and not heavier than 60\,kg
  \item names of those who have height above average
 \end{enumerate}
\end{multicols}
\begin{table}[ht!]
 \centering
 \begin{tabular}{lccc}
  \toprule
  \multicolumn{4}{c}{Subject}\\
  \midrule
  Name & Age & Weight & Height\\
  \midrule
  Judy Garcia  	  & 23 & 59 & 167\\
  Robert Baker 	  & 22 & 66 & 180\\
  Laura Ross 	  & 28 & 70 & 171\\
  Kimberly Price  & 21 & 45 & 162\\
  Nancy Thompson  & 27 & 90 & 165\\
  Tina Clark 	  & 28 & 77 & 191\\
  \bottomrule
 \end{tabular}
 \caption{Data for creating the structure {\tt subject}.}\label{tab:sub}
\end{table}
\end{prb*}

\begin{prb*}{5}
 Write a script that you can use to manage the structure {\tt subject}.
 At the start it should be checked (\mc{exist}) whether there is a variable in the Work Space called {\tt subject}
 or not, in the latter case it should be checked if there is a file {\tt subject.m}, and then loaded (\mc{load}) into the Work Space.
 If neither the variable nor the file exist; an empty structure should be initialized.
 Create a menu for your program with the following items:
 \begin{description}
  \item[New] Create new entry in {\tt subject}. The program should ask for the subject's name, age, weight and height.
  \item[View] Print out the name of every subject.
  \item[Exit] Before quitting, the program should ask whether to save the changes or not, and act accordingly (\mc{save}).
 \end{description}
\end{prb*}

\begin{prb*}{5}
Write a function that, for a given subject,
calculates the body mass index.
Specifically, write a function named \mc{get\_bmi} with one input and three (optional) outputs:
\begin{description}
 \item[\mc{get\_bmi}\mck{(s)}] prints out the name and textual classification of the subject {\tt s},
 \item[\mck{bmi = }\mc{get\_bmi}\mck{(s)}] gives the body mass index of subject {\tt s},
 \item[\mck{[bmi, bmi\_class] = }\mc{get\_bmi}\mck{(s)}] gives the body mass index and numeric classification.
\end{description}

\begin{table}[ht!]
 \centering
 \begin{tabular}{clc}
  \toprule
  & \multicolumn{2}{c}{Classification}\\
  \cmidrule(r){2-3}
  BMI [$\mathrm{kg}/\mathrm{m}^2$] & Text & Number \\
  \midrule
  --15 	 & very severely underweight 	& $-3$\\
  15--16 & severely underweight 	& $-2$\\
  16--18.5 & underweight 		& $-1$\\
  \midrule
  18.5--25 & normal 			& $0$\\
  \midrule
  25--30   & overweight			& $1$\\
  30--35   & moderately obese 		& $2$\\
  35--   & severely obese 		& $3$\\
  \bottomrule
 \end{tabular}\label{tab:BMI}
 \caption{BMI classification}
\end{table}
\end{prb*}

\begin{prb*}{2}
Using the following cells
\begin{center}
\mck{ranks =  \{2,3,4,5,6,7,8,10,J,Q,K,A\}},\quad \mck{suits =  \{Clubs,Diamonds,Hearts,Spades\}}
\end{center}
create the standard 52-card deck as a cell containing all pairs: \mck{\{\{'2','Clubs'\}, \{'3','Clubs'\},\dots\}}.
\end{prb*}

\begin{prb*}{2}
Determine how many different ways the number $1729$ can be decomposed to a sum of two cubes of positive integers, i.e. integers $a,b>0$ satisfying $a^3 + b^3 = 1729.$
Use trial and error for all integers $1\le a\le b\le 12.$
\end{prb*}

\begin{prb*}{2}
Using trial and error, determine the Pythagorean triples: $a^2 + b^2 = c^2$ for all $1\le a\le b\le c\le 100$.
\end{prb*}

\begin{prb*}{5}
Let $M$ a natural number, and consider the (finite) sequence $u(M)=\begin{bmatrix}u_0 & u_1 & \dots & u_n\end{bmatrix}^\top$
generated by a given function $f\colon \N\to \N$ in the following way:
\[u(M) = \begin{bmatrix}
          M& f(M)&\ f(f(M)) & f^3(M) & \dots & f^n(M)
         \end{bmatrix}\quad \text{or equivalently} \quad u_0:=M,\ u_{k+1} = f(u_k),\]
where
\[f(n) = \begin{cases}
            n/2, & \text{if }n \text{ is even,}\\
            3n+1 & \text{if }n \text{ is odd,}
           \end{cases}
\]
The famous Collatz conjecture states that starting from any natural number $M$ the sequence $u(M)$ will eventually
reach $1.$
Assuming the conjecture is true, let $n$ the smallest number such that $f^n(M) = 1,$
so that the last element in the list $u(M)$ is $u_n=1.$
The number of steps taken to reach 1 is called stopping time $T(M)$.
For example:
\[u(17)=[17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1], \quad T(17) = 12.\]
Write a function named \mck{u = }\mc{collatz}\mck{(M)}.
Plot $(M,\max u(M)).$ Plot the histogram of the stopping time $T(M)$ for $2\le M \le 500.$
\end{prb*}

\begin{prb*}{4}
Implement the quicksort algorithm as a function \mck{v = }\mc{quicksort}\mck{(u)}, where
$u,\,v$ are lists, and $v$ is the sorted version of $u.$
\begin{quote}
The quicksort algorithm (from Wikipedia):
\begin{enumerate}
 \item Pick an element, called a pivot, from the array.
 \item Reorder the array so that all elements with values less than the pivot come before the pivot, while all elements with values greater than the pivot come after it (equal values can go either way). After this partitioning, the pivot is in its final position. This is called the partition operation.
 \item Recursively apply the above steps to the sub-array of elements with smaller values and separately to the sub-array of elements with greater values.
\end{enumerate}

\end{quote}

\end{prb*}

\section{Projects}
\subsection*{Simple Game$^{30}$}
In this game the computer thinks of a number $ 1\le n\le 100$, then you have to guess that number.
Each time you guess, the computer tells you whether your guess is too small or too large.
As soon as you guess the correct number the game is over.
Every time the game is played the time (score) that was needed to find the number should be recorded.

To store information about the players and their scores use the structure \mck{game} with fields:
\begin{description}
 \item[\mck{.player}] A structure array with fields:
  \begin{description}
  \item[\mck{.name}] A string, the name of the player.
  \item[\mck{.time}] A vector containing the player's scores. Should be an empty vector, if no game has been played yet.
 \end{description}
 \item[\mck{.cp}] An integer representing the current player, such that \mck{game.player(game.cp)} refers to the
		  structure corresponding to the current player.
\end{description}
Make sure, that the variable \mck{game} exists in the Work Space by
loading a previously saved one, or -- if the file does not exist then -- initializing one (with at least one player).

Create a menu for the game with the following items:
\begin{description}
\item[Start]
    Starts the game by calling the function \mc{start\_game}.
    Write a function named \mck{game\_new =}\mc{ start\_game}\mck{(game)}, so that -- after finishing the game --
    it appends the time (needed to succed) to the current player's time vector; and returns with the updated structure \mck{game\_new}.
\item[Change Player]
    Change the current player by calling the function \mc{change\_player}.
    Write a function named \mck{game\_new = }\mc{change\_player}\mck{(game)} that
    lists all players, from which the user can choose one; and returns with the structure \mck{game\_new}
    where the current player (\mck{game.cp}) has been updated -- in accordance with the user's choice.
\item[New Player]
    Add a new player by calling the function \mc{new\_player}. Write a function named \mck{game\_new = }\mc{new\_player}\mck{(game)} that adds a new entry to the structure array \mck{game.player} by asking the player's name,
    and returning with the updated structure \mck{game\_new}.
    The new player's  time vector should be empty. When a new player is added, make sure that the the current player is set to the new player.
\item[View Ranking]
    List the top 5 players and their scores by calling the function \mc{view\_ranking}.
\item[Quit]
    Quit the program. Save the variable \mck{game} using \mc{save}.
\end{description}
Make sure that besides the menu the current player's name is also displayed.

\subsection*{Euler Solver$^{30}$}
Differential equations play a central role in modeling dynamical systems, such as the weather,
the chemical processes in a cell or the motion of a commet.
Henceforth, we only consider deterministic continuous models that can be described by
an explicit, first order ordinary differential equation in the form:
\begin{equation}
\dot x(t) = f(t,x(t)),\quad x(t_0) = x_0,\label{eq:ode}
\end{equation}
for some interval $t\in [t_0, t_N],$
where $x\colon \R\to\R^n$ the state variable, and $f\colon\R\times\R^n\to\R^n$ is the model.
In general, we can only calculate the approximate solution of \eqref{eq:ode} in discrete points $t_1,t_2,\dots,t_N.$
The solution at these points are approximated $x(t_n)\approx x_n$ by using the forward Euler method:
\[t_{n+1} = t_n + h, \quad x_{n+1} = x_n + h f(t_n, x_n), \qquad n=0,1,\dots,N-1\]
where $h$ is the step size, a fixed small positive number.

Write a function named \mck{sol = }\mc{euler\_solve}\mck{(ivp)}
where the input \mck{ivp} is a structure defining the initial value problem \eqref{eq:ode},
having the following fields:
\begin{description}
 \item[\mck{.model}] is a function handle for the function $f\colon \R\times\R^n\to\R^n,$
 \item[\mck{.initial\_value}] is the initial vector $x_0\in\R^n,$
 \item[\mck{.interval}] is an array \mck{[t0, tN]}, where $t_0$ and $t_N$ are the initial and final time, respectively.
 \item[\mck{.step\_size}] is the step size $h,$ if it's empty use $h:=|t_N-t_0|\cdot 10^{-3}.$
\end{description}
The output \mck{sol} is a structure with fields \mck{.t} which contains the time vector $[t_0,t_0+h,\dots,t_0+Nh],$
and \mck{.x} which contains the approximation of the solutions $x_1(t),\,x_2(t),\dots,x_n(t)$ in its rows.

Test your solver by writing scripts for the following problems:
\begin{enumerate}[a)]
\item Solve the logistic equation: $\dot x = x(1-x)$ for the initial values $x(0):=x_0\in\{0,0.25,0.5,\dots,2\},$
      and plot the solutions (see Figure \ref{fig:logistic}).
\item Solve the equation $\ddot u + 2\xi\dot u + u = 0$ of a damped oscillator -- with the initial value
$u(0) := 1,\: \dot u(0) := 0$ -- for the damping parameters $\xi =0.2,0.3,\dots,1.4,$
      and plot the solutions (see Figure \ref{fig:damped}).\\
      {\it \small Hint: to write the oscillator in the form of \eqref{eq:ode} set $x=(x_1\ \ x_2)^\top:=(u\ \ \dot u)^\top.$}
      \begin{figure}[ht!]
	\centering
	\begin{subfigure}[b]{0.48\textwidth}
	  \includegraphics[width=\textwidth]{logistic}
	  \caption{Logistic equation for different initial values.}
	  \label{fig:logistic}
	\end{subfigure}
	\begin{subfigure}[b]{0.48\textwidth}
	 \includegraphics[width=\textwidth]{damped}
	 \caption{Damped oscillator for different dampings.}
	  \label{fig:damped}
	\end{subfigure}
	\caption{Solutions of the logistic equation and the damped oscillator.}
      \end{figure}

\item Solve the Lorenz system:
	\begin{equation}
	    \dot u = 10(v-u),\qquad
	    \dot v = u(28-w)-v,\qquad
	    \dot w = uv - \frac{8}{3}z,\label{eq:lorenz}
	\end{equation}
	\begin{figure}[ht!]
	\centering
	 \includegraphics[width=0.8\textwidth]{lorenz}
	 \caption{A trajectory and its projections of the Lorenz System.}\label{fig:lorenz}
	\end{figure}

      for the initial value $x(0) = (u(0)\ v(0)\ w(0))^\top := (1\ 1\ 1)^\top,$
      and plot the  trajectory $t\mapsto (u(t), v(t), w(t))$ in three dimensions using \mc{plot3} (see Figure~\ref{fig:lorenz}).
      Show the following projections of the trajectory as well: $t\mapsto (30, v(t), w(t)),\: t\mapsto (u(t), 30, w(t)),\: t\mapsto (u(t), v(t), 0).$
\end{enumerate}

\subsection*{Cellular Automaton$^{30}$}
Let $x_1=[x_{1,1},x_{1,2},\dots,x_{1,m}]$ a list of zeros and ones representing the state of the automaton.
At each step the state of automaton evolves by a set of rules.
For a given rule $r$ the state is updated by
\[x_{i+1,k} = f_r(x_{i,k-1}, x_{i,k}, x_{i,k+1}),\quad k=1,2,\dots,m\]
with the assumption $x_{i,0} = x_{i,m+1} = 0$ for all $i=1,2,\dots,n.$
\begin{table}[ht!]\centering
 \begin{tabular}{ccccccccccccc}
 \toprule
      &     &     &  &\multicolumn{8}{c}{rules} \\
      \cmidrule{5-13}
  $a$ & $b$ & $c$ &  & 0 & 1 & 2 & 3 & 4 &\dots & 30 &\dots  & 255 \\
  \midrule
%  & & & & \multicolumn{5}{c}{$f_r(u_{k-1},u_k,u_{k+1})$} \\
  0 & 0 & 0 & $d_0(r)$ & 0 & 1 & 0 & 1 & 0 & \dots & 0 &\dots & 1\\
  0 & 0 & 1 & $d_1(r)$ & 0 & 0 & 1 & 1 & 0 & \dots & 1 &\dots & 1\\
  0 & 1 & 0 & $d_2(r)$ & 0 & 0 & 0 & 0 & 1 & \dots & 1 &\dots & 1\\
  0 & 1 & 1 & $d_3(r)$ & 0 & 0 & 0 & 0 & 0 & \dots & 1 &\dots & 1\\
  1 & 0 & 0 & $d_4(r)$ & 0 & 0 & 0 & 0 & 0 & \dots & 1 &\dots & 1\\
  1 & 0 & 1 & $d_5(r)$ & 0 & 0 & 0 & 0 & 0 & \dots & 0 &\dots & 1\\
  1 & 1 & 0 & $d_6(r)$ & 0 & 0 & 0 & 0 & 0 & \dots & 0 &\dots & 1\\
  1 & 1 & 1 & $d_7(r)$ & 0 & 0 & 0 & 0 & 0 & \dots & 0 &\dots & 1\\
  \bottomrule
 \end{tabular}
\caption{All possible rules. Columns $0,1,2,\dots$ contain the digits of the corresponding rule in base 2.}\label{tab:rules}
\end{table}
Any rule $r=0,1,2,\dots,255$ in base 2 has at most 8 digits, and can be written as
\[r = d_0(r) + 2 d_1(r) + 2^2d_2(r) + \dots + 2^7d_7(r), \qquad d_i(r)\in\{0,1\},\quad i=0,2,\dots,7.\]
The map $f_r$ is defined as $f_r(a,b,c) = d_i(r),$ where $i=2^2a + 2b + c.$
For instance, consider $r = 30 = 2^1 + 2^2 + 2^3 + 2^4,$ so $d_0(30) = 0,\: d_1(30) = 1,\: d_2(30) = 1,$ etc.
Therefore $f_{30}(0,0,0)=d_0(30) = 0,\: f_{30}(0,0,1)=d_1(30) = 1,\: f_{30}(0,1,0)=d_2(30) = 1,$ etc., for summary see Table~\ref{tab:rules}.
\begin{figure}[ht!]
\centering
  \includegraphics[width=0.7\textwidth]{rule30}
  \caption{Rule 30, generated using \mc{cellular\_automaton}\mck{(30,\,[50,\,100],\,50)}.}\label{fig:automaton}
\end{figure}

The evolution of an initial state $x_1=[x_{1,1},x_{1,2},\dots,x_{1,m}]$ for $n$ steps is collected in the matrix
\[X = \begin{bmatrix}
       x_1\\
       x_2\\
       \vdots\\
       x_n
      \end{bmatrix} =
     \begin{bmatrix}
       x_{1,1} & x_{1,2} & \dots & x_{1,m}\\
       x_{2,1} & x_{2,2} & \dots & x_{2,m}\\
       \vdots & \vdots & \ddots & \vdots\\
       x_{n,1} & x_{n,2} & \dots & x_{n,m}
      \end{bmatrix}.
      \]
Write a function named \mc{cellular\_automaton} considering the following specification:
\begin{description}
  \item[\mc{cellular\_automaton}\mck{(r, [n,\,m])}] shows the evolution of the initial state $x_1$  as an image by the rule $r$ for $n$ steps, where the initial state is $x_{1,1}=1,$ $x_{1,i}=0$ for all $i=2,\dots,m.$
  \item[\mc{cellular\_automaton}\mck{(r, n)}] is the same as before except $m=n.$
  \item[\mc{cellular\_automaton}\mck{(r, [n,\, m], [i1,\,i2\,\dots,\,ik])}] is the same as before except the initial state is defined by $x_{1,i}=1$ for all $i\in\{i_1,i_2,\dots,i_k\}$ and $x_{1,i}=0$ otherwise. See an example in Figure \ref{fig:automaton}.
  \item[\mck{X = }\mc{cellular\_automaton}\mck{(r, \dots)}] instead of plotting, it returns with a matrix $X$ containing the states of the automaton as its rows.
\end{description}

\subsection*{Iterated Function System$^{30}$}
Given a polygon $S$ in the plane represented by its $m$ vertices $u_{i}=(x_i\ y_i)^\top,$ and a set of of affine contraction maps:
\[S =  \begin{bmatrix}
	    u_{1}\\
	    u_{2}\\
	    \vdots\\
	    u_{m}
        \end{bmatrix},\qquad F_i(u):=A_i u + b_i, \quad A_i\in\R^{2\times 2},\,b_i\in\R^2, \quad i=1,2,\dots,n.\]
One can apply $F_i$ to the polygon $S$ and get an other polygon $F_i(S)$ by applying $F_i$
to every vertices of the polygon in the following way:
\[F_i(S) =
	    \begin{bmatrix}
	      F_i(u_{1})\\
	      F_i(u_{2})\\
	      \vdots\\
	      F_i(u_{m})\\
	    \end{bmatrix}=
	    \begin{bmatrix}
	      A_iu_{1}+b_i\\
	      A_iu_{2}+b_i\\
	      \vdots\\
	      A_iu_{m}+b_i\\
	    \end{bmatrix}.
\]
Generate new polygons recursively by
\[X_{k+1} = \begin{bmatrix}
             F_1(X_k) & F_2(X_k) & \dots\ & F_n(X_k)
            \end{bmatrix}
, \qquad X_0 = S,\]
where $X_k$ is a matrix containing polygons as its columns, and $F_i(X_k)$ means that $F_i$
applied column-wise, that is applied to every polygon contained in $X_k.$

For example, when the polygons are triangles $m=3$, and we have two transformations $F_1,\,F_2$ so that $n=2.$
\[
X_0 =\begin{bmatrix}
      u_{1}\\
      u_{2}\\
      u_{3}
     \end{bmatrix},\quad
X_1 =\begin{bmatrix}
      F_1(X_0) & F_2(X_0)
     \end{bmatrix},\quad
\]
\[
X_2 =\begin{bmatrix}
      F_1(X_1) & F_2(X_1))
     \end{bmatrix}=
     \begin{bmatrix}
      F_1(F_1(X_0)) & F_1(F_2(X_0)) & F_2(F_1(X_0)) & F_2(F_2(X_0))
     \end{bmatrix}.
\]

Write a function named \mc{ifs} considering the following specification:
\begin{description}
 \item[\mc{ifs}\mck{(ifs\_data)}] shows the polygons determined by the input (see below the input specification).
 \item[\mck{X = }\mc{ifs}\mck{(ifs\_data)}] instead of plotting it gives the matrix $X_k.$
 \item[\mc{ifs}\mck{(ifs\_data, 'Color', [1,0,0], \dots)}] excepts extra arguments as an option for \mc{patch} object.
\end{description}

The input structure \mck{ifs\_data} has the following fields:
\begin{description}
 \item[\mck{.initial\_shape}] a vector representing the initial polygon $S.$
 \item[\mck{.transformation}] a cell containing the matrices $A_i,\ i=1,2\dots,n$
 \item[\mck{.dilation}] a cell containing the dilations $b_i,\ i=1,2\dots,n$
 \item[\mck{.step}] is an integer $N,$ then the iteration goes $N$ steps, thus calculating $X_N.$
		    Note that the size of $X_N$ is $2m\times n^N.$
\end{description}

Test your function by writing a script for the following problems:
\begin{enumerate}[a)]
 \item Show the 6th approximation of the Sierpinski triangle:
 \[A_1 = A_2 = A_3 = \begin{bmatrix}
          1/2 & 0\\
          0   & 1/2
         \end{bmatrix},\quad
         b_1 = \begin{bmatrix}
          0 \\
          0
         \end{bmatrix},\quad
         b_2 = \begin{bmatrix}
          1/2 \\
          0
         \end{bmatrix},\quad
         b_3 = \begin{bmatrix}
          1/4 \\
          \sqrt{3}/4
         \end{bmatrix},
\]
starting from the equilateral triangle: $S=\begin{bmatrix}0 & 0 & 1 & 0 & 1/2 & \sqrt{3}/2\end{bmatrix}^\top.$
The Figure \ref{fig:ifs}. shows the first three approximation of the Sierpinski triangle.
Try out what happens when you start from the square: $S=\begin{bmatrix}0 & 0 & 1 & 0 & 1 & 1 & 0 & 1\end{bmatrix}^\top.$
\begin{figure}[ht!]
\centering
  \includegraphics[width=0.3\textwidth]{ifs1}
  \includegraphics[width=0.3\textwidth]{ifs2}
  \includegraphics[width=0.3\textwidth]{ifs3}
  \caption{Approximations of the the Sierpinski triangle: $X_0,\,X_1,\,X_2$.}\label{fig:ifs}
\end{figure}
\item Show the 4th approximation of the Sierpinski carpet:
 \[A_1 =  \dots = A_8 = \begin{bmatrix}
          1/3 & 0\\
          0   & 1/3
         \end{bmatrix}\]
\[       b_1 = \begin{bmatrix}
          0 \\
          0
         \end{bmatrix},\
         b_2 = \begin{bmatrix}
          1 \\
          0
         \end{bmatrix},\
         b_3 = \begin{bmatrix}
          2 \\
          0
         \end{bmatrix},\
         b_4 = \begin{bmatrix}
          0 \\
          1
         \end{bmatrix},\
         b_5 = \begin{bmatrix}
          2 \\
          1
         \end{bmatrix},\
         b_6 = \begin{bmatrix}
          0 \\
          2
         \end{bmatrix},\
         b_7 = \begin{bmatrix}
          1 \\
          2
         \end{bmatrix},\
         b_8 = \begin{bmatrix}
          2 \\
          2
         \end{bmatrix},
\]
starting from the square: $S=\begin{bmatrix}0 & 0 & 3 & 0 & 3 & 3 & 0 & 3\end{bmatrix}^\top.$
\begin{figure}[ht!]
\centering
  \includegraphics[width=0.3\textwidth]{carpet1}
  \includegraphics[width=0.3\textwidth]{carpet2}
  \includegraphics[width=0.3\textwidth]{carpet3}
  \caption{Approximations of the Sierpinski triangle: $X_0,\,X_1,\,X_2$.}\label{fig:ifs}
\end{figure}
\item Show the 9th approximation of the Dragon curve:
\[
A_1 = \frac{1}{\sqrt{2}}\begin{bmatrix}
          \cos(\pi/4) & \sin(\pi/4)\\
          -\sin(\pi/4) & \cos(\pi/4)
         \end{bmatrix},\quad
A_2 = \frac{1}{\sqrt{2}}\begin{bmatrix}
          \cos(5\pi/4) & -\sin(5\pi/4)\\
          \sin(5\pi/4) & \cos(5\pi/4)
         \end{bmatrix}
\]
\[       b_1 = \begin{bmatrix}
          0 \\
          0
         \end{bmatrix},\
         b_2 = \begin{bmatrix}
          1 \\
          0
         \end{bmatrix}
\]
in blue (see Figure \ref{fig:dragon}.), starting from the initial polygon $S= \begin{bmatrix}0 & -0.05 & 1 & -0.05 & 1 & 0.05 & 0 & 0.05\end{bmatrix}^\top.$
\begin{figure}[ht!]
\centering
  \includegraphics[width=0.3\textwidth]{dragon1}
  \includegraphics[width=0.3\textwidth]{dragon2}
  \includegraphics[width=0.3\textwidth]{dragon3}
  \caption{Approximations of the dragon curve: $X_0,\ X_1,\ X_2$.}\label{fig:dragon}
\end{figure}
\end{enumerate}

\end{document}

\[S_1 = \begin{bmatrix}
	    F_1(u_{1,1}) & F_2(u_1) & \dots & F_n(u_1)\\
	    F_1(u_{2,1}) & F_2(u_2) & \dots & F_n(u_2)\\
	    \vdots\\
	    F_1(u_{m,1}) & F_2(u_m) & \dots & F_n(u_m)\\
        \end{bmatrix}
\]


% Format: LaTeX
\documentstyle{report}

\setlength{\parskip}{\baselineskip}
\setlength{\parindent}{0pt}

\begin{document}

\chapter{Unsolved Problems}

\section{Odd Perfect Numbers}

A number is said to be {\em perfect\/} if it
is the sum of its divisors.  For example, $6$ is
perfect because \(1+2+3 = 6\), and $1$, $2$, and $3$
are the only numbers that divide evenly into $6$
(apart from 6 itself).

It has been shown that all even perfect numbers
have the form \[2^{p-1}(2^{p}-1)\] where $p$
and \(2^{p}-1\) are both prime.

The existence of {\em odd\/} perfect numbers is
an open question.
\end{document}


\section{Update PAULI-ISO-QMDD after Clifford unitary}

Roughly: two parts. 1: Update rule for general matrices and general (Pauli group) isomorphism QMDD. 2: Update rule for Clifford gates on Pauli isomorphism QMDDs representing stabilizer states.

\subsection{General update rule}

(We assume that the data structures for vectors and matrices have been described in earlier sections.)

1. Produce $\ket{\psi}:=A\ket{\phi}$, namely  $A\ket{phi_0}$ en $A\ket{phi_1}$. Here $A$

2. Check whether the node $\ket{\psi}$ is already in the database.

3. Otherwise, check whether $\ket{\psi}$ is $\mathcal{G}$-isomorphic to a node already in the database. If so, reroute the edges of $\ket{\psi}$ to that node, and delete all newly orphaned nodes.

(Bonus algorithm: Compute expectation values: $\bra{\psi} H \ket{\psi}$. Find a place to put this.)

TODO: Sketch of algorithm on A4.

\subsection{Special update rule}

\subsubsection{Applying a CNOT gate}

1. Update rule for CNOT

2. Try to prune the isomorphism into a single global phase

\subsubsection{Applying a Single-qubit Clifford gate}

1. Expression for Hadamard gate, Phase gate

2. Finding a new isomorphism (work in progress)

(The remainder of this text is old)

Here, we explain briefly why updating Pauli-ISO-QMDDs after a Clifford is nontrivial in the general case.
Below, an algorithm that performs the task is presented

\subsection{Why the Clifford update is nontrivial}

Stabilizer states in Pauli-iso-qmdd has multiple flavours:

\begin{itemize}
\item Z-flavour: read the QMDD as 'in the computational basis'
\item Graph-State-flavour: use Z-flavour but only use Pauli strings containing I and Z (at this point, this flavour precisely contains all graph states), while keeping a list of single-qubit Cliffords that will be applied to the graph state.
\item Pauli-flavour: for each qubit, keep a flag that indicates whether it is stored in the X,Y or Z-basis
\end{itemize}

Performing a single-qubit Clifford in Z-flavour requires an algorithm to update a subpart of the tree with $(\unit + \beta P) / \sqrt{2}$ where $P$ is a Pauli string and $\beta \in \{\pm 1, \pm i\}$.
This follows from a local basis transform, which for example for Z to X-basis follows from the identity
\[
    \ket{0} \otimes \ket{\phi} + \ket{1} \otimes P\ket{\phi}
    =
    \ket{+} \otimes \frac{\unit + P}{\sqrt{2}} \ket{\phi} + \ket{-} \otimes \frac{\unit - P}{\sqrt{2}}\ket{\phi}
.
\]
CNOTs, on the other hard, are straightforward in Z-flavour.

For Pauli-flavour, the story is reversed: for the same reason, CNOTs are hard but single-qubit Cliffords are trivial.

[For more explanation, see the presentation \url{miscellaneous/2020_05_19_treeform_clifford_update_difficulty.pdf}]

\subsection{An algorithm for the Clifford update}

Here, we sketch how to update a stabilizer state in treeform after application of a single-qubit Clifford or a CNOT.
We use the Z-flavour of treeform, i.e. a stabilizer state on $n$ qubit is recursively defined as $\ket{\phi} = \ket{a} \otimes \ket{\psi}$ or $\ket{\phi} = (\ket{0} \otimes \ket{\psi} + \alpha \ket{1}\otimes \otimes P \ket{\psi}) / \sqrt{2}$, where $a \in \{0, 1, \pm 1, \pm i\}$ and $\alpha \in \{\pm 1, \pm i\}$ and $\ket{\psi}$ is an $n-1$ qubit stabilizer state (or equals $1$ in case $n=1$).

First note that if the most significant qubit is not involved in the application of a Clifford $C$, then in both the knife- and fork cases, it can easily be seen that the Clifford 'propogates' down the tree with little overhead until it meets the first qubit it acts upon:

knife: $C\ket{a} \otimes \ket{\psi} = \ket{a} \otimes \left( C\ket{\psi}\right)$

fork:
$
C \left( \ket{0} \otimes \ket{\psi} + \alpha \ket{1} \otimes Q\ket{\psi}\right)
=
\ket{0} \otimes C\ket{\psi} + \alpha \ket{1} \otimes \left(CQC^{\dagger}\right) \left(C\ket{\psi}\right)
$

\subsubsection{Updating stabilizer state in Treeform after a CNOT}

Denote the stabilizer state by $\ket{\phi}$

\textbf{Claim: updating after a CNOT can be done in time $\mathcal{O}(n^2)$, where $n$ is the number of qubits of $\ket{\phi}$.}

We distinguish two cases.

If $\ket{\phi}$ is a `knife', i.e. $\ket{\phi} = \ket{a} \otimes \ket{\psi}$ for some $a \in \{0, 1, \pm 1, \pm i\}$ and $\ket{\psi}$ is an $(n-1)$-qubit stabilizer state, then the update is straightforward: if $a\in \{0, 1\}$, then the post-CNOT state is a knife and becomes a fork otherwise.
For example, if $\ket{\phi} = \ket{+}\otimes\ket{\psi}$, then $CNOT\ket{\phi} = \ket{0} \ket{\psi} + \ket{1} \otimes X \ket{\psi}$.
(Note we could still ``reduce'' the tree [in the sense of reducing a decision diagram], which we treat below]

If $\ket{\phi}$ is a `fork', i.e. $\ket{\phi} = \ket{0} \otimes \ket{\psi} + \alpha \ket{1}\otimes \otimes P \ket{\psi}$ (omitting normalization), then $CNOT\ket{\phi} = \ket{0} \otimes \ket{\psi} + \alpha \ket{1} \otimes XP \ket{\psi}$.

The only remaining question is: can we reduce this tree?
That is, are the post-CNOT states which are a fork, really a fork or can they also be written as knife?

We claim that this can be done in time $\mathcal{O}(n^2)$ by distinguishing the modulus of the expectation value of the fork-operator (i.e. the Pauli-string $Q$ in $\ket{0} \otimes \ket{\psi} + \alpha \ket{1} \otimes Q\ket{\psi}$) with $\ket{\phi}$ to equal 1, or to be less.
To be precise: if $|\bra{\phi} Q \ket{\phi}| = 1$, then $Q\ket{\phi} = \bra{\phi} Q\ket{\phi} \ket{\phi}$ and thus the fork can be reduced to $\left(\ket{0} + \alpha \bra{\phi} Q\ket{\phi} \ket{1} \right) \otimes \ket{\psi}$, and otherwise it remains as it is.

We now claim that $\bra{\phi} Q \ket{\phi}$ can be determined in time $\mathcal{O}(n^2)$ by recursing over the $n$ qubits, and each step takes at most time $\mathcal{O}(n)$.
The knife case is straightforward: $\bra{\phi} A \ket{\phi} = \bra{\phi} A_0 \ket{\phi} \cdot \bra{\phi} A_r \ket{\phi}$, and the lefmost expectation value is computed in constant time.

[TODO: IDEA: below, we assume that $A$ is a general string. Can we exploit the fact that we know its structure (i..e $X \cdot P$ where $P$ is a known string)?]

The fork case is a bit more involved (omitting adjoint signs since Pauli strings are self-adjoint):
\begin{eqnarray}
\bra{\phi} A \ket{\phi}
    &=&
\bra{0} A_0 \ket{0} \otimes \bra{\psi} A_r \ket{\psi}
+
\\
    &&
\bra{1} A_0 Q_0 \ket{0} \otimes \bra{\psi} A_r Q_r \ket{\psi}
+
\\
    &&
\bra{1} Q_0 A_0 \ket{0} \otimes \bra{\psi} Q_r A_r \ket{\psi}
+
\\
    &&
\bra{1} Q_0 A_0 Q_0 \ket{1} \otimes \bra{\psi} Q_r A_r Q_r \ket{\psi}
\end{eqnarray}

Note by the fact that $Q$ and $A$ are Pauli strings, either the first and last terms or the second and third terms are zero (because Pauli strings either commute or anticommute).
The remaining terms only differ by a $\pm 1$ factor.
Which is the case, can be determined by computing whether the string commute or anticommute, which can be done in time $\mathcal{O}(n)$ since the strings are of length $n$.
What remains is to compute $\bra{\psi} Q_r A_r \ket{\psi}$ or $\bra{\psi} A_r \ket{\psi}$ (depending on which terms survive), which is done in the recursive step.

\subsubsection{Updating Treeform after a single-qubit Clifford}

Updating a stabilizer state in treeform $\ket{\phi}$ after a single-qubit Clifford for a knife-case is straightforward and uses the fact that the set $\{\ket{0}, \ket{1}, \ket{\pm}, \ket{\pm i}$ is closed under single-qubit Cliffords.

For a fork, the algorithm requires slightly different operations for each Clifford, but for each, the underlying principle is the same and is again based on the fact that they map the set of single-qubit stabilizer states to itself.

As an example, we treat the application of $H$ to the first qubit of the state $\ket{0} \otimes \ket{\psi} + \alpha \ket{1} \otimes P \ket{\psi}$, which equals
\[
\ket{+} \otimes \ket{\psi} + \alpha \ket{-} \otimes P \ket{\psi}
\]
and can be rewritten as
\[
    \ket{0} \otimes (\unit + \alpha P) \ket{\psi} + \ket{1} \otimes (\unit - \alpha P) \ket{\psi}
    .
\]

Now we need two things:

- a pauli string $A$ that maps $\unit + \alpha P$ to $\unit - \alpha P$. Any string that anitcommutes with $P$ will do [TODO NEEDS CHECKING!] and can be found in time $\mathcal{O}(n)$.

- rewriting $(\unit + \alpha P) \ket{\psi}$ in treeform. This is more involved and can be done recursively on the size of $\ket{\psi}$. At each level, it is required to check whether $P$ and the fork-operator of that level commute or anticommute (in a similar fashion to the `reduction of the tree' in the CNOT-application explained above) and thus requires a total runtime of $\mathcal{O}(n^2)$.