\section{Implementation and Numerical Results}
\label{sec:64results}

\minitoc[-3mm]{73mm}{5}

\noindent
In this final section of the chapter,
we study optimal results of the test scenarios and
analyze interpolation errors and optimization results
for topology optimization with B-spline surrogates on sparse grids.

\subsection{Implementation}
\label{sec:641implementation}

In the following, for simplicity,
we combine the two functions to be interpolated,
i.e., the Cholesky factor
$\cholfactor\colon \clint{\*0, \*1} \to \real^{6 \times 6}$ and
the micro-cell density $\denscell\colon \clint{\*0, \*1} \to \real$,
to one single objective function
$\*\objfun\colon \clint{\*0, \*1} \to \real^{m+1}$,
from which both functions can be recovered.

\paragraph{Overview of offline and online phase}

Our method is divided into an offline phase and an online phase,
both of which are sketched in \cref{fig:topoOptPhases}.
The offline phase consists of
generating the spatially adaptive sparse grid
$\sgset = \{\gp{\*l_k,\*i_k} \mid k = 1, \dotsc, \ngp\}$,
solving the corresponding micro-problems,
computing the Cholesky factors, and
hierarchizing the Cholesky factor entries and micro-cell densities
to obtain the sparse grid interpolant $\vsgintp$.
Each optimization iteration of the online phase consists of
evaluating the interpolant $\vsgintp$
for each micro-cell parameter $\mcp{j}$ ($j = 1, \dotsc, M$),
reconstructing the elasticity tensor $\etensorcholintp$ from
the Cholesky factors $\cholfactorintp$,%
\footnote{%
  In addition, the partial derivatives
  $\partialdiff{} \etensorcholintp/\partialdiff{} x_t$
  ($t = 1, \dotsc, d$)
  are evaluated using \cref{eq:choleskyFactorDerivative}.
  This is necessary to employ gradient-based optimization.%
}
and solving the macro-problem to retrieve the approximated compliance value
$\complianceintp(\mcp{1}, \dotsc, \mcp{M})$.
The superscript in $\complianceintp$ indicates that
we do not use the exact elasticity tensors $\etensor$
to compute the compliance value,
but rather the reconstructed and interpolated tensors
$\etensorcholintp$.

\begin{figure}
  \tikzset{
    myCircle/.style={
      circle,
      fill=mittelblau!30,
      draw=mittelblau,
      inner sep=0.5mm,
    }
  }%
  \subcaptionbox{%
    Offline phase (without the actual grid generation).%
  }[149mm]{%
    \begin{tikzpicture}
      \node[myCircle] (points) at (0mm,0mm) {%
        $
          \begin{matrix}
            \gp{\*l_1,\*i_1},\\
            \dots,\\
            \gp{\*l_{\ngp},\*i_{\ngp}}
          \end{matrix}
        $%
      };
      \node[myCircle] (elasticityTensors) at (43mm,0mm) {%
        $
          \begin{matrix}
            \etensor(\gp{\*l_1,\*i_1}),\\
            \dots,\\
            \etensor(\gp{\*l_{\ngp},\*i_{\ngp}})
          \end{matrix}
        $%
      };
      \node[myCircle] (choleskyFactors) at (80mm,0mm) {%
        $
          \begin{matrix}
            \cholfactor(\gp{\*l_1,\*i_1}),\\
            \dots,\\
            \cholfactor(\gp{\*l_{\ngp},\*i_{\ngp}})
          \end{matrix}
        $%
      };
      \node[myCircle] (choleskyInterpolant) at (118mm,0mm) {%
        $
          \begin{matrix}
            \cholfactorintp\colon \clint{\*0, \*1}\\
            {} \to \real^{6 \times 6}
          \end{matrix}
        $%
      };
      \draw[->,draw=C0] (points) -- node[above] {%
        \footnotesize{}micro-problem%
      } (elasticityTensors);
      \draw[->,draw=C0] (elasticityTensors) -- node[above] {%
        \footnotesize{}%
        $
          \tr{\cholfactor} \cholfactor = \etensor
        $\vphantom{p}%
      } (choleskyFactors);
      \draw[->,draw=C0] (choleskyFactors) -- node[above] {%
        \footnotesize{}interpolate%
      } (choleskyInterpolant);
    \end{tikzpicture}%
  }%
  \\[2mm]%
  \subcaptionbox{%
    Online phase (one iteration of the optimizer).%
  }[149mm]{%
    \begin{tikzpicture}
      \node[myCircle] (points) at (0mm,0mm) {%
        $
          \begin{matrix}
            \mcp{1},\\
            \dots,\\
            \mcp{M}
          \end{matrix}
        $%
      };
      \node[myCircle] (choleskyFactors) at (34mm,0mm) {%
        $
          \begin{matrix}
            \cholfactorintp(\mcp{1}),\\
            \dots,\\
            \cholfactorintp(\mcp{M})
          \end{matrix}
        $%
      };
      \node[myCircle] (elasticityTensors) at (83mm,0mm) {%
        $
          \begin{matrix}
            \etensorcholintp(\mcp{1}),\\
            \dots,\\
            \etensorcholintp(\mcp{M})
          \end{matrix}
        $%
      };
      \node[myCircle] (complianceValue) at (129.5mm,0mm) {%
        $
          \begin{matrix}
            \complianceintp(\mcp{1},\\
            \dotsc,\\
            \mcp{M})
          \end{matrix}
        $%
      };
      \draw[->,draw=C0] (points) -- node[above] {%
        \footnotesize{}evaluate\vphantom{p}%
      } (choleskyFactors);
      \draw[->,draw=C0] (choleskyFactors) -- node[above] {%
        \footnotesize{}%
        $
          \etensorcholintp
          = \tr{(\cholfactorintp)} \cholfactorintp
        $\vphantom{p}%
      } (elasticityTensors);
      \draw[->,draw=C0] (elasticityTensors) -- node[above] {%
        \footnotesize{}macro-problem%
      } (complianceValue);
    \end{tikzpicture}%
  }%
  \caption[Offline and online phase for topology optimization]{%
    Offline and online phase for topology optimization.
    The interpolation of the
    micro-cell density $\denscell$ with $\denscellintp$
    (see \cref{sec:622BSplines}) has been omitted for brevity.%
  }%
  \label{fig:topoOptPhases}%
\end{figure}

\paragraph{Generation of spatially adaptive sparse grids}

We use the classical surplus-based refinement criterion
(see, e.g., \cite{Pflueger10Spatially})
as shown in \cref{alg:topoOptGridGeneration}
to generate the spatially adaptive sparse grids.
The difference to common surrogate settings is that the objective function
$\*f\colon \clint{\*0, \*1} \to \real^{m+1}$ is vector-valued.
As the entries of $\cholfactor$ cannot be evaluated individually,
the adaptivity criterion has to consider all entries at once
to avoid performing unnecessary evaluations.
We use the surpluses in the piecewise linear hierarchical basis,
as their absolute values correlate with the second mixed derivative
of the objective function due to \cref{eq:surplusIntegral}.
The surpluses are combined using the formula
$\beta_k \ceq \tr{\*c} \vabs{\vsurplus_{\*l_k,\*i_k}}$
(with entry-wise absolute value) and the
points with largest $\beta_k$ are refined.

\begin{algorithm}
  \begin{algorithmic}[1]
    \Function{$\sgset = \texttt{offlinePhase}$}{%
      $\*\objfun$, $n$, $b$, $\*c$, $l_{\max}$, $\refinetol$,
      $\ngp_{\mathrm{refine}}$%
    }
      \State{$\sgset \gets \coarseregsgset{n}{d}{b}$}
      \Comment{initial regular sparse grid}%
      \While{\True}
        \State{$\ngp \gets \setsize{\sgset}$}
        \Comment{number of grid points}%
        \State{%
          Let $(\vsurplus_{\*l_{k'},\*i_{k'}})_{k' = 1, \dotsc, \ngp}$
          satisfy $
            \fa{k = 1, \dotsc, \ngp}{
              \sum_{k'=1}^{\ngp} \vsurplus_{\*l_{k'},\*i_{k'}}
              \bspl{\*l_{k'},\*i_{k'}}{1}(\gp{\*l_k,\*i_k})
              = \*\objfun(\gp{\*l_k,\*i_k})
            }
          $%
        }
        \ForOneLine{$k = 1, \dotsc, \ngp$}{%
          $\beta_k \gets \tr{\*c} \vabs{\vsurplus_{\*l_k,\*i_k}}$%
        }
        \Comment{combine surpluses to a scalar value}%
        \State{%
          $
            \liset^\ast \gets \{
              k = 1, \dotsc, \ngp \mid
              \ex{\gp{\*l,\*i} \notin \sgset}{
                \gp{\*l_k,\*i_k} \to \gp{\*l,\*i}
              },\,
              \norm[\infty]{\*l_k} < l_{\max},\,
              \abs{\beta_k} > \refinetol
            \}
          $%
        }
        \IfOneLine{$\liset^\ast = \emptyset$}{\Break{}}
        \Comment{stop when there are no refinable grid points left}%
        \State{%
          Refine $\le \ngp_{\mathrm{refine}}$ of the points
          $\{\gp{\*l_k,\*i_k} \in \sgset \mid k \in \liset^\ast\}$
          with largest $\beta_k$%
        }
      \EndWhile{}
    \EndFunction{}
  \end{algorithmic}
  \caption[%
    Generation of spatially adaptive sparse grids for topology optimization%
  ]{%
    Generation of spatially adaptive sparse grids for topology optimization.
    Inputs are
    the objective function $\*f\colon \clint{\*0, \*1} \to \real^{m+1}$
    (combination of the Cholesky factor of the elasticity tensor and
    the micro-cell density),
    the level $n \ge d$ and boundary parameter $b \in \nat$ of the
    initial regular sparse grid,
    the vector $\*c \in \real^{m+1}$ of coefficients with which the
    absolute values of the entries of the surpluses are combined,
    the maximal level $l_{\max} \in \nat$,
    the refinement threshold $\refinetol \in \posreal$, and
    the number $\ngp_{\mathrm{refine}} \in \nat$ of points to refine
    in each iteration.
    Output is the spatially adaptive sparse grid $\sgset$.%
  }%
  \label{alg:topoOptGridGeneration}%
\end{algorithm}

\paragraph{Parameter bounds}

In the micro-cell models presented in \cref{sec:631models},
extreme micro-cell parameters near zero or one may cause problems
with the resulting elasticity tensors.
For instance, many elasticity tensor entries corresponding to
the 2D cross model are discontinuous near the lines $x_1 = 1$ or $x_2 = 1$
\multicite{Huebner14Mehrdimensionale,Valentin14Hierarchische}.
This is due to the fact that the micro-cell is completely filled with material
on these lines,
independent of the other micro-cell parameter.
Similar issues occur for the other models and the shearing angles.
Hence, we have to restrict the range of the feasible micro-cell parameters,
i.e., the sparse grid points
$\*x = \gp{\*l_k,\*i_k}$ are still defined on the unit hyper-cube
$\clint{\*0, \*1}$,
but the actual micro-cell parameters $\xscaled$ are retrieved by an
affine transformation $\xscaled \ceq \*a + (\*b - \*a) \*x$.
For the models in \cref{sec:631models},
we restrict the bar widths to $\clint{0.01, 0.99}$ and
the shearing angles to $\clint{-0.35\pi, 0.35\pi}$.

\paragraph{Software, algorithms, and domain discretization}

The micro-problems and macro-problems were solved with the
\fem software package CFS++ \cite{Kaltenbacher10Advanced}.%
\footnote{%
  \url{http://www.lse.uni-erlangen.de/cfs/}%
}
The micro-prob\-lems were discretized by dividing the micro-cells into
$128 \times 128 = \num{16384}$ elements (models in two dimensions) or
$16 \times 16 \times 16 = \num{4096}$ elements (models in three dimensions).
The macro-domains $\objdomain$ were discretized using
32 macro-cells per meter in the 2D cantilever scenario
(i.e., $64 \times 32 = \num{2048}$ cells),
20 macro-cells per meter in the 3D cantilever scenario
(i.e., $20 \times 20 \times 20 = \num{8000}$ cells), and
10 macro-cells per meter in the other scenarios
(i.e.,
%$50 \times 20 + 20 \times 30 = \num{1600}$
\num{1600} cells for the 2D L-shape and
%$20 \times 20 \times 10 = \num{4000}$
\num{4000} cells for the 3D center-load).
The generation of the sparse grids (offline phase) was done via a MATLAB code,
while the evaluation of the interpolants (online phase) was performed
by the sparse grid toolbox \sgpp \cite{Pflueger10Spatially}.%
\footnote{%
  \url{http://sgpp.sparsegrids.org/}%
}
For the solution of the emerging optimization problems,
a sequential quadratic programming method was employed
(see \cref{sec:513gradientBasedConstrained}).

\subsection{Error Sources}
\label{sec:642errorSources}

There are multiple sources that contribute to the numerical error
of our method:

\begin{enumerate}[label=E\arabic*.,ref=E\arabic*,leftmargin=2.7em]
  \item
  \label{item:topoOptErrorMicro}
  Discretization of the micro-problem
  (i.e., the elasticity tensors $\etensor$ are inaccurate)

  \item
  \label{item:topoOptErrorInterpolation}
  Sparse grid interpolation
  (i.e., $\etensorintp \not= \etensor$)

  \item
  \label{item:topoOptErrorCholesky}
  Reconstruction of elasticity tensors with Cholesky factors
  (i.e., $\etensorcholintp \not= \etensorintp$)

  \item
  \label{item:topoOptErrorMacro}
  Discretization of the macro-problem
  (i.e., the compliance $\compliance$ is inaccurate)

  \item
  \label{item:topoOptErrorOptimization}
  Optimization
  (i.e., the minimum found by the optimizer is inaccurate or not global)

  \item
  \label{item:topoOptErrorRounding}
  Floating-point rounding errors
  (i.e., arithmetical operations are inaccurate)
\end{enumerate}

\noindent
\ref{item:topoOptErrorRounding}-type errors are always present and
will not be analyzed in this chapter.
Errors of type \ref{item:topoOptErrorMicro} and \ref{item:topoOptErrorMacro}
are intrinsic to the homogenization approach
and will not be discussed here either.
The optimization error \ref{item:topoOptErrorOptimization}
has already been discussed in \cref{sec:542optimization}
for explicit test functions.
Therefore, in the remainder of this chapter,
we will focus on the analysis of the errors of types
\ref{item:topoOptErrorInterpolation} and \ref{item:topoOptErrorCholesky},
since the interpolation of Cholesky factors is the
major new contribution to this application.

\subsection{Interpolation Error}
\label{sec:643interpolation}

\paragraph{Spectral interpolation error measure}

For the interpolation error \ref{item:topoOptErrorInterpolation} and
the Cholesky factorization error \ref{item:topoOptErrorCholesky},
we cannot simply take the absolute value of the difference
of the objective function $\*\objfun\colon \clint{\*0, \*1} \to \real^{m+1}$
and its surrogate $\vsgintp$, since both are vector-valued.
As the micro-cell density $\denscell$
is not affected by the Cholesky factorization,
we consider only the elasticity tensor
$\etensor\colon \clint{\*0, \*1} \to \real^{6 \times 6}$ and
its surrogate
$\etensorcholintp\colon \clint{\*0, \*1} \to \real^{6 \times 6}$
obtained by Cholesky factorization.
To retrieve a scalar error measure,
we use the spectral norm
\begin{equation}
  \norm[2]{\etensor(\*x) - \etensorcholintp(\*x)},\quad
  \*x \in \clint{\*0, \*1},
\end{equation}
i.e., the largest absolute eigenvalue of
$\etensor(\*x) - \etensorcholintp(\*x)$.
However, the choice of the norm is arbitrary,
as all matrix norms on $\real^{6 \times 6}$ are equivalent to each other.

\paragraph{Pointwise spectral interpolation error}

\Cref{fig:topoOptInterpolationErrorPointwise}
shows the pointwise spectral interpolation error for the 2D cross model
and the corresponding spatially adaptive sparse grid
generated with the refinement algorithm as explained in
\cref{sec:641implementation}.
The above-mentioned discontinuity of elasticity tensor entries
near $x_1 = 1$ or $x_2 = 1$
is most severe near the corners $\*x \in \{(0, 1), (1, 0)\}$
(cf.\ \cref{fig:cholesky}),
as some entries vanish if one of the micro-cell bars has zero width.
Hence, most points are placed near these singularity corners.

\begin{figure}
  \subcaptionbox{%
    $\norm[2]{\etensor(\*x) - \etensorintp(\*x)}$%
    \label{fig:topoOptInterpolationErrorPointwise_1}%
  }[63mm]{%
    \includegraphics{topoOptInterpolationPointwise_1}%
  }%
  \hspace{3mm}%
  \subcaptionbox{%
    $\norm[2]{\etensor(\*x) - \etensorcholintp(\*x)}$%
    \label{fig:topoOptInterpolationErrorPointwise_2}%
  }[63mm]{%
    \includegraphics{topoOptInterpolationPointwise_2}%
  }%
  \hfill%
  \includegraphics{topoOptInterpolationPointwise_3}%
  \caption[Pointwise spectral interpolation error for the 2D cross model]{%
    Pointwise spectral interpolation error for the 2D cross model and
    cubic B-splines on
    $\ngp = 1320$ spatially adaptive sparse grid points \emph{(dots)} for
    the direct elasticity tensor interpolation \emph{(left)} and
    the Cholesky factor interpolation \emph{(right).}%
  }%
  \label{fig:topoOptInterpolationErrorPointwise}%
\end{figure}

The left plot (\cref{fig:topoOptInterpolationErrorPointwise_1})
shows the spectral interpolation error
$\norm[2]{\etensor(\*x) - \etensorintp(\*x)}$
of the direct elasticity tensor interpolant without Cholesky factorization
(i.e., error \ref{item:topoOptErrorInterpolation}).
The maximum error is \num{1.2e-3},
which is attained near the critical lines $x_1 = 1$ or $x_2 = 1$.
Note that the mean error over the whole domain $\clint{\*0, \*1}$
is only \num{4.5e-5}.
In the right plot (\cref{fig:topoOptInterpolationErrorPointwise_2}),
the picture changes slightly when looking at the spectral interpolation error
$\norm[2]{\etensor(\*x) - \etensorcholintp(\*x)}$
of the elasticity tensor resulting from Cholesky factorization
(i.e., errors \ref{item:topoOptErrorInterpolation} and
\ref{item:topoOptErrorCholesky} combined).
The maximum error becomes \num{3.4e-3},
while the mean error increases to \num{1.1e-4}.
We conclude that the Cholesky factorization leads to an increase
of interpolation errors by only less than half an order of magnitude.

\paragraph{Convergence of spectral interpolation error}

\Cref{fig:topoOptInterpolationErrorBasisFunctions_1} shows
the convergence of the relative $\Ltwo$ spectral interpolation errors
\begin{equation}
  \error^{\sparse} \ceq
  \frac{
    \normLtwoscaled{
      \vphantom{\big(}
      \norm[2]{\etensor({\cdot}) - \etensorintp({\cdot})}
    }
  }{
    \normLtwoscaled{
      \vphantom{\big(}
      \norm[2]{\etensor({\cdot})}
    }
  }, \qquad
  \error^{\chol,\sparse} \ceq
  \frac{
    \normLtwoscaled{
      \vphantom{\big(}
      \norm[2]{\etensor({\cdot}) - \etensorcholintp({\cdot})}
    }
  }{
    \normLtwoscaled{
      \vphantom{\big(}
      \norm[2]{\etensor({\cdot})}
    }
  }
\end{equation}
for the 2D cross model, i.e.,
the relative $\Ltwo$ error of the functions depicted in
\cref{fig:topoOptInterpolationErrorPointwise}.
Relative errors of \SI{1}{\permille} are already obtained
for $\ngp = 200$ grid points.
Unfortunately, even for higher B-spline degrees $p > 1$,
the order of convergence is only quadratic
due to the singularities of the elasticity tensor.
This slow convergence does not improve for the other
micro-cell models as shown in
\Cref{fig:topoOptInterpolationErrorBasisFunctions_2}.
In fact, the convergence decelerates even more
as the number of micro-cell parameters increases.
For the 2D sheared cross and 3D cross models with three parameters,
the spatially adaptive sparse grid with $\ngp \approx \num{10000}$ grid points
is able to achieve a relative error of around \SI{3}{\permille}.
However, for the 2D sheared framed cross and 3D sheared cross models
with five parameters, only errors of about \SI{5}{\percent} are reached
for the same grid size.

\begin{figure}
  \hspace*{5mm}%
  \includegraphics{topoOptInterpolation_3}%
  \hfill%
  \raisebox{0.5mm}{\includegraphics{topoOptInterpolation_4}}%
  \\[2mm]%
  \subcaptionbox{%
    $\error^{\sparse}$ \emph{\textcolor{C0}{(blue)}} and
    $\error^{\chol,\sparse}$ \emph{\textcolor{C1}{(red)}}
    for the 2D cross model and different degrees.%
    \label{fig:topoOptInterpolationErrorBasisFunctions_1}%
  }[72mm]{%
    \includegraphics{topoOptInterpolation_1}%
  }%
  \hfill%
  \subcaptionbox{%
    $\error^{\chol,\sparse}$
    for the other models and $p = 3$.%
    \label{fig:topoOptInterpolationErrorBasisFunctions_2}%
  }[72mm]{%
    \includegraphics{topoOptInterpolation_2}%
  }%
  \caption[Convergence of relative $L^2$ spectral interpolation errors]{%
    Convergence of relative $\Ltwo$ spectral interpolation errors
    over the increasing number $\ngp$ of spatially adaptive grid points
    (i.e., decreasing threshold $\refinetol$)
    for the 2D cross model without or with Cholesky factor interpolation
    and different degrees $p$ \emph{(left)} and
    for the other models and cubic degree \emph{(right)}.%
  }%
  \label{fig:topoOptInterpolationErrorBasisFunctions}%
\end{figure}

\subsection{Optimal Compliance Values and Structures}
\label{sec:644optimization}

\paragraph{Optimal compliance values for different micro-cell models}

In the following, we use for each micro-cell model
a specific spatially adaptive sparse grid with around \num{10000} points.
The exact grid sizes and other details about the employed sparse grids
can be found in \cref{tbl:topoOptModels}
(located in \cref{chap:a30topoOptDetails}).
For hierarchical cubic B-splines ($p = 3$),
\cref{tbl:topoOptResultsModels} lists the
compliance values $\compliance(\mcpoptappr{1}, \dotsc, \mcpoptappr{M})$
for each of the four scenarios
and the corresponding possible micro-cell models,
where $(\mcpoptappr{1}, \dotsc, \mcpoptappr{M}) \in (\real^d)^M$
is the micro-cell parameter combination that is returned by the optimizer.%
\footnote{%
  Note that this true compliance value differs from the
  approximated value
  $\complianceintp(\mcpoptappr{1}, \dotsc, \mcpoptappr{M})$,
  which the optimizer reports as the optimal objective function value.%
}
It is obvious that more complicated micro-cell models
lead to lower (better) compliance values,
as they are a generalization of the simple models.
For instance, the 2D cross is a special case of
the 2D framed cross, the 2D sheared cross, and the 2D sheared framed cross.
By choosing the respectively best model for each scenario,
we are able to decrease the compliance value
(and, hence, increase the stability of the resulting structure)
by \SI{9.6}{\percent} in the 2D cantilever scenario,
by \SI{7.7}{\percent} in the 2D L-shape scenario,
by \SI{34}{\percent} in the 3D cantilever scenario, and
by \SI{73}{\percent} in the 3D center-load scenario.
In general, this motivates the usage of more complicated micro-cell models,
which cannot be computationally handled with
conventional full grid interpolation methods.
Consequently, sparse grids or similar methods have to be used.

\begin{table}
  \setnumberoftableheaderrows{1}%
  \begin{tabular}{%
    >{\kern\tabcolsep}=l<{\kern5mm}*{6}{+c}<{\kern\tabcolsep}%
  }
    \toprulec
    \headerrow
    Scenario&       2D-C&   2D-FC&  2D-SC&           2D-SFC& 3D-C&   3D-SC\\
    \midrulec
    % id = 650,652,654,656
    2D cantilever&  74.974& 70.816& \textbf{67.809}& 68.602& ---&    ---\\
    % id = 651,653,655,657
    2D L-shape&     183.68& 177.51& \textbf{169.60}& 174.55& ---&    ---\\
    \midrulec
    % id = 658,660
    3D cantilever&  ---&    ---&    ---&             ---&    247.60& \textbf{162.59}\\
    % id = 659,661
    3D center-load& ---&    ---&    ---&             ---&    169.27& \textbf{46.171}\\
    \bottomrulec
  \end{tabular}
  \caption[Optimal compliance values for different micro-cell models]{%
    Optimal compliance values for the different scenarios
    and micro-cell models using cubic B-splines
    (spatially adaptive grids with around \num{10000} points).
    %The columns correspond to the micro-cell models
    %as presented in \cref{fig:microCell}:
    %2D cross,
    %2D framed cross,
    %2D shared cross,
    %2D shared framed cross,
    %3D cross, and
    %3D sheared cross.
    The entries highlighted in \textbf{bold face} indicate the best choice
    of micro-cell models for a given scenario.
    %The optimization run of the entry marked as \emph{italic}
    %terminated prior to success due to numerical difficulties.
    More details can be found in \cref{tbl:topoOptResultsDetailed}.%
  }%
  \label{tbl:topoOptResultsModels}%
\end{table}

\paragraph{Corresponding optimal structures}

The corresponding optimal structures are shown in
\cref{fig:topoOptStructure2DCantilever} for the 2D cantilever scenario
and, for reasons of space, in \cref{chap:a30topoOptDetails} in
\cref{fig:topoOptStructure2DLShape,fig:topoOptStructure3D}
for the other three scenarios.
Of course, the periodic micro-cell structures cannot be plotted directly,
as the micro-cells are infinitesimally small.
Therefore, the figures show for each macro-cell only
one single large micro-cell.

\begin{figure}
  \subcaptionbox{%
    2D cross%
  }[72mm]{%
    % id = 650
    \includegraphics{topoOptStructure2D_1}%
  }%
  \hfill%
  \subcaptionbox{%
    2D framed cross%
  }[72mm]{%
    % id = 652
    \includegraphics{topoOptStructure2D_3}%
  }%
  \\[2mm]%
  \subcaptionbox{%
    2D sheared cross%
  }[72mm]{%
    % id = 654
    \includegraphics{topoOptStructure2D_5}%
  }%
  \hfill%
  \subcaptionbox{%
    2D sheared framed cross%
  }[72mm]{%
    % id = 656
    \includegraphics{topoOptStructure2D_7}%
  }%
  \caption[Optimal structures in the 2D cantilever scenario]{%
    Topologically optimal structures in the 2D cantilever scenario
    for different micro-cell models using cubic B-splines
    (spatially adaptive grids with around \num{10000} points).
    The colors indicate the length of the displacement,
    where dark regions correspond to weak displacements and
    bright regions to strong displacements.
    The color map is the same as in
    \cref{fig:topoOptStructure2DLShape}.
    Only bars with widths $\ge 0.1$ are shown.
    More details can be found in \cref{tbl:topoOptResultsDetailed}.%
  }%
  \label{fig:topoOptStructure2DCantilever}%
\end{figure}

Two effects can be seen in the plots of the optimal structures:
First, the simpler models are not able to direct the emerging forces at
arbitrary angles.
For example, the 2D framed cross model strongly prefers
angles of \ang{45}, which results in structures that are not as stable
as they could be.
The 2D sheared cross and 2D sheared framed cross models
are considerably more flexible, allowing
internal forces to act at almost arbitrary angles.
Second, the sheared micro-cell models use the available
material volume more efficiently than the cross model.
This is most striking in the 3D case (see \cref{fig:topoOptStructure3D}),
where it seems that the sheared cross structures
use more volume than the simple cross structures,
although the structures spend exactly the same amount of material volume.
The reason is that for the cross model, both bars
have to be used in order to connect the macro-cell to its neighbors.
For the sheared cross model, a shearing of the vertical bar suffices,
and we save volume by not using the horizontal bar.
Both of these effects explain the significantly lower compliance
values for the sheared micro-cell models.

\paragraph{Comparison to the direct solution}

B-splines on sparse grids lead to a drastic reduction in computation time.
Solving the 2D cantilever scenario with the best-placed sheared cross model
would take 453 days with
exact elasticity tensor evaluations (i.e., without surrogates),
assuming the same number of iterations as for the surrogate tensor case
and sequential computation of the elasticity tensors.
This estimate does not account for approximating the missing derivatives
of the elasticity tensor.
If we incorporate this and use 100 parallel processes,
we still need weeks for the solution.
In contrast, the computation time using our sparse grid surrogates
is a matter of minutes or hours at most,
resulting in speedups of around 200.
This is excluding the time for the offline phase,
which is in the range of hours, but which has to be spent only once,
as the resulting grid can be reused for different scenarios.

\vspace{2em}

\paragraph{Optimality-interpolation gaps}

\begin{figure}
  \includegraphics{topoOptOptimalityGap_3}%
  \\[2mm]%
  \includegraphics{topoOptOptimalityGap_1}%
  \hfill%
  \includegraphics{topoOptOptimalityGap_2}%
  \caption[Convergence of the optimality-interpolation gap]{%
    Convergence of the optimality-interpolation gap
    $\abs{\compliance[\opt,\ast] - \complianceintp[\opt,\ast]}$
    for the 2D/3D cantilever scenario
    and different micro-cell models using cubic B-splines ($p = 3$).
    The left plot additionally shows
    $\compliance[\opt,\ast]
    \ceq \compliance(\mcpoptappr{1}, \dotsc, \mcpoptappr{M})$ and
    $\complianceintp[\opt,\ast]
    \ceq \complianceintp(\mcpoptappr{1}, \dotsc, \mcpoptappr{M})$
    for the 2D cross model.%
  }%
  \label{fig:topoOptOptimalityGap}%
\end{figure}

%For a given computed optimal solution
%$(\mcpoptappr{1}, \dotsc, \mcpoptappr{M}) \in (\real^d)^M$,
Ideally, we would measure the true optimality gap
\begin{equation}
  \label{eq:topoOptOptimalityGapTrue}
  \compliance(\mcpoptappr{1}, \dotsc, \mcpoptappr{M}) -
  \compliance(\mcpopt{1}, \dotsc, \mcpopt{M}),
\end{equation}
cf.\ error \ref{item:topoOptErrorOptimization}.
Unfortunately, the true optimum
$(\mcpopt{1}, \dotsc, \mcpopt{M})$ could not be computed:
Apart from the time issue mentioned above,
oscillations in the elasticity tensor evaluation and
errors stemming from types
\ref{item:topoOptErrorMicro} and \ref{item:topoOptErrorRounding}
reliably led to optimizer crashes as it ran into discontinuities,
which are smoothed out when using B-spline surrogates.
However, as in \cref{fig:topoOptOptimalityGap},
we can at least calculate the \term{optimality-interpolation gap}
\begin{equation}
  \label{eq:topoOptOptimalityGapPseudo}
  \abs{
    \compliance(\mcpoptappr{1}, \dotsc, \mcpoptappr{M}) -
    \complianceintp(\mcpoptappr{1}, \dotsc, \mcpoptappr{M})
  }
\end{equation}
between the actual compliance value
%(i.e., using exact elasticity tensors $\etensor(\mcpoptappr{q})$,
%$q = 1, \dotsc, M$, for the final solution)
and the approximated, reported compliance value.
%(i.e., using the surrogate tensors $\etensorcholintp(\mcpoptappr{q})$).
This gap does not constitute any kind of bound on the true optimality gap;
however, the idea is that
as the interpolation error converges to zero,
the optimality-interpolation gap should converge to zero, too.

\pagebreak

\Cref{fig:topoOptOptimalityGap} (left) shows that for the 2D cross model,
the optimizer reports compliance values that are smaller than in reality
($\complianceintp[\opt,\ast]$ vs. $\compliance[\opt,\ast]$).
However, the difference steadily converges to zero.
This is similar for the other micro-cell model as shown in the
right part of \cref{fig:topoOptOptimalityGap},
although the convergence is much slower due to the
higher number $d$ of micro-cell parameters.

\paragraph{Optimal compliance values for different B-spline degrees}

Finally, to study the effect of the B-spline degree on the
optimization performance,
\cref{tbl:topoOptResultsDegrees} lists the compliance values
for the degrees $p = 1, 3, 5$ and the 2D/3D cross and sheared cross
micro-cell models.
In the two-dimensional scenarios,
higher-order B-splines decrease the compliance value
by up to \SI{9}{\percent}.
In the three-dimensional scenarios,
higher-order B-splines may perform worse than the piecewise linear
functions ($p = 1$).
(However, as indicated in \cref{tbl:topoOptResultsDegrees},
all optimization runs with piecewise linear functions
terminated prematurely due to numerical difficulties with the
discontinuous derivatives.)
It may be suspected that if we used micro-cell models with
less prominent discontinuities (i.e., ``smoother'' elasticity tensors),
the advantage of higher-order B-splines would be more visible.
All in all, the application of topology optimization underlines
that good interpolation (and thus a good quality of the surrogate)
is key to good optimization results.

\begin{table}
  \setnumberoftableheaderrows{2}%
  \begin{tabular}{%
      >{\kern\tabcolsep}=l<{\kern5mm}*{3}{+c}%
      <{\kern5mm}*{3}{+c}<{\kern\tabcolsep}%
    }
    \toprulec
    \headerrow
    &
    \multicolumn{3}{c}{\hspace*{-12pt}2D/3D cross}&
    \multicolumn{3}{c}{\hspace*{-6pt}2D/3D sheared cross}\\
    \headerrow
    Scenario&       $p = 1$&         $p = 3$&         $p = 5$&          $p = 1$&                $p = 3$&         $p = 5$\\
    \midrulec
    % id = 690,650,670,694,654,674
    2D cantilever&  \emph{82.365}&   \textbf{74.974}& 76.070&           \emph{68.889}&          \textbf{67.809}& 68.018\\
    % id = 691,651,671,695,655,675
    2D L-shape&     \emph{193.83}&   \textbf{183.68}& 183.70&           \emph{169.85}&          169.60&          \textbf{169.60}\\
    \midrulec
    % id = 698,658,678,700,660,680
    3D cantilever&  \emph{249.75}&   247.60&          \textbf{247.33}&  \emph{\textbf{148.72}}& 162.59&          152.34\\
    % id = 699,659,679,701,661,681
    3D center-load& \textbf{162.68}& 169.27&          163.94&           \emph{\textbf{45.713}}& 46.171&          47.074\\
    \bottomrulec
  \end{tabular}
  \caption[Optimal compliance values for different B-spline degrees]{%
    Optimal compliance values for the different scenarios
    and B-spline degrees using the 2D/3D cross micro-cell model \emph{(left)}
    and the 2D/3D sheared cross micro-cell model \emph{(right).}
    The spatially adaptive sparse grids are the same as in
    \cref{tbl:topoOptResultsModels}.
    The entries highlighted in \textbf{bold face} indicate the best choice
    of B-spline degree for a given scenario and micro-cell model.
    Optimization runs of entries marked as \emph{italic}
    terminated prior to success due to numerical difficulties.%
  }%
  \label{tbl:topoOptResultsDegrees}%
\end{table}

%10197   cross-sisc-conv-tol2.15443e-05-lb0.01-ub0.99-cholesky-hier-bspl3
%10502   framed-cross-sga16-conv-tol0.794328-lb0.01-ub0.99-cholesky-hier-bspl3
%10723   sheared-cross-sisc-conv-tol0.00464159-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3
%10694   sheared-framed-cross-sga16-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3
%9207    cross-3d-sga16-conv-tol0.0794328-lb0.01-ub0.99-cholesky-hier-bspl3
%15389   sheared-cross-3d-sga16-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3
%
%
%
%python3 generate.py --checkpoint-hack=sgpp --default-id=626 stats=cross-sisc-conv-tol2.15443e-05-lb0.01-ub0.99-cholesky-hier-bspl3 optLB=0.01,0.01 optUB=0.99,0.99 optIC=0.2,0.2 problem=thesis-2d-cantilever id=650
%python3 generate.py --checkpoint-hack=sgpp --default-id=620 stats=cross-sisc-conv-tol2.15443e-05-lb0.01-ub0.99-cholesky-hier-bspl3 optLB=0.01,0.01 optUB=0.99,0.99 optIC=0.2,0.2 problem=thesis-2d-L id=651
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=framed-cross-sga16-conv-tol0.794328-lb0.01-ub0.99-cholesky-hier-bspl3 optLB=0.01,0.01,0.01,0.01 optUB=0.99,0.99,0.99,0.99 optIC=0.2,0.2,0.2,0.2 id=652
%python3 generate.py --checkpoint-hack=sgpp --default-id=651 stats=framed-cross-sga16-conv-tol0.794328-lb0.01-ub0.99-cholesky-hier-bspl3 optLB=0.01,0.01,0.01,0.01 optUB=0.99,0.99,0.99,0.99 optIC=0.2,0.2,0.2,0.2 id=653
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=sheared-cross-sisc-conv-tol0.00464159-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 optLB=0.01,0.01,0.15 optUB=0.99,0.99,0.85 optIC=0.2,0.2,0.5 id=654
%python3 generate.py --checkpoint-hack=sgpp --default-id=651 stats=sheared-cross-sisc-conv-tol0.00464159-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 optLB=0.01,0.01,0.15 optUB=0.99,0.99,0.85 optIC=0.2,0.2,0.5 id=655
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=sheared-framed-cross-sga16-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 optLB=0.01,0.01,0.01,0.01,0.15 optUB=0.99,0.99,0.99,0.99,0.85 optIC=0.2,0.2,0.2,0.2,0.5 id=656
%python3 generate.py --checkpoint-hack=sgpp --default-id=651 stats=sheared-framed-cross-sga16-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 optLB=0.01,0.01,0.01,0.01,0.15 optUB=0.99,0.99,0.99,0.99,0.85 optIC=0.2,0.2,0.2,0.2,0.5 id=657
%python3 generate.py --checkpoint-hack=sgpp --default-id=634 stats=cross-3d-sga16-conv-tol0.0794328-lb0.01-ub0.99-cholesky-hier-bspl3 optLB=0.01,0.01,0.01 optUB=0.99,0.99,0.99 optIC=0.2,0.2,0.2 problem=thesis-3d-cantilever id=658
%python3 generate.py --checkpoint-hack=sgpp --default-id=635 stats=cross-3d-sga16-conv-tol0.0794328-lb0.01-ub0.99-cholesky-hier-bspl3 optLB=0.01,0.01,0.01 optUB=0.99,0.99,0.99 optIC=0.2,0.2,0.2 problem=thesis-3d-centerload id=659
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=sheared-cross-3d-sga16-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 optLB=0.01,0.01,0.01,0.15,0.15 optUB=0.99,0.99,0.99,0.85,0.85 optIC=0.2,0.2,0.2,0.5,0.5 id=660
%python3 generate.py --checkpoint-hack=sgpp --default-id=659 stats=sheared-cross-3d-sga16-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 optLB=0.01,0.01,0.01,0.15,0.15 optUB=0.99,0.99,0.99,0.85,0.85 optIC=0.2,0.2,0.2,0.5,0.5 id=661
%
%
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-thesis-conv-tol2.15443e-05-lb0.01-ub0.99-cholesky-hier-bspl5 bsplineDegree=5 id=670
%python3 generate.py --checkpoint-hack=sgpp --default-id=651 stats=cross-thesis-conv-tol2.15443e-05-lb0.01-ub0.99-cholesky-hier-bspl5 bsplineDegree=5 id=671
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-thesis-conv-tol0.794328-lb0.01-ub0.99-cholesky-hier-bspl5 bsplineDegree=5 id=672
%python3 generate.py --checkpoint-hack=sgpp --default-id=653 stats=framed-cross-thesis-conv-tol0.794328-lb0.01-ub0.99-cholesky-hier-bspl5 bsplineDegree=5 id=673
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-thesis-conv-tol0.00464159-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl5 bsplineDegree=5 id=674
%python3 generate.py --checkpoint-hack=sgpp --default-id=655 stats=sheared-cross-thesis-conv-tol0.00464159-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl5 bsplineDegree=5 id=675
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-thesis-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl5 bsplineDegree=5 id=676
%python3 generate.py --checkpoint-hack=sgpp --default-id=657 stats=sheared-framed-cross-thesis-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl5 bsplineDegree=5 id=677
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-thesis-conv-tol0.0794328-lb0.01-ub0.99-cholesky-hier-bspl5 bsplineDegree=5 id=678
%python3 generate.py --checkpoint-hack=sgpp --default-id=659 stats=cross-3d-thesis-conv-tol0.0794328-lb0.01-ub0.99-cholesky-hier-bspl5 bsplineDegree=5 id=679
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-thesis-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl5 bsplineDegree=5 id=680
%python3 generate.py --checkpoint-hack=sgpp --default-id=661 stats=sheared-cross-3d-thesis-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl5 bsplineDegree=5 id=681
%
%
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-thesis-conv-tol2.15443e-05-lb0.01-ub0.99-cholesky-hier-bspl1 bsplineDegree=1 id=690
%python3 generate.py --checkpoint-hack=sgpp --default-id=651 stats=cross-thesis-conv-tol2.15443e-05-lb0.01-ub0.99-cholesky-hier-bspl1 bsplineDegree=1 id=691
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-thesis-conv-tol0.794328-lb0.01-ub0.99-cholesky-hier-bspl1 bsplineDegree=1 id=692
%python3 generate.py --checkpoint-hack=sgpp --default-id=653 stats=framed-cross-thesis-conv-tol0.794328-lb0.01-ub0.99-cholesky-hier-bspl1 bsplineDegree=1 id=693
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-thesis-conv-tol0.00464159-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl1 bsplineDegree=1 id=694
%python3 generate.py --checkpoint-hack=sgpp --default-id=655 stats=sheared-cross-thesis-conv-tol0.00464159-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl1 bsplineDegree=1 id=695
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-thesis-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl1 bsplineDegree=1 id=696
%python3 generate.py --checkpoint-hack=sgpp --default-id=657 stats=sheared-framed-cross-thesis-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl1 bsplineDegree=1 id=697
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-thesis-conv-tol0.0794328-lb0.01-ub0.99-cholesky-hier-bspl1 bsplineDegree=1 id=698
%python3 generate.py --checkpoint-hack=sgpp --default-id=659 stats=cross-3d-thesis-conv-tol0.0794328-lb0.01-ub0.99-cholesky-hier-bspl1 bsplineDegree=1 id=699
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-thesis-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl1 bsplineDegree=1 id=700
%python3 generate.py --checkpoint-hack=sgpp --default-id=661 stats=sheared-cross-3d-thesis-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl1 bsplineDegree=1 id=701
%
%
%
%
%
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.215443-lb0.01-ub0.99-cholesky-hier-bspl3 id=720
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.1-lb0.01-ub0.99-cholesky-hier-bspl3 id=721
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.0464159-lb0.01-ub0.99-cholesky-hier-bspl3 id=722
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.0215443-lb0.01-ub0.99-cholesky-hier-bspl3 id=723
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.01-lb0.01-ub0.99-cholesky-hier-bspl3 id=724
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.00464159-lb0.01-ub0.99-cholesky-hier-bspl3 id=725
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.00215443-lb0.01-ub0.99-cholesky-hier-bspl3 id=726
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.001-lb0.01-ub0.99-cholesky-hier-bspl3 id=727
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.000464159-lb0.01-ub0.99-cholesky-hier-bspl3 id=728
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.000215443-lb0.01-ub0.99-cholesky-hier-bspl3 id=729
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol0.0001-lb0.01-ub0.99-cholesky-hier-bspl3 id=730
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol4.64159e-05-lb0.01-ub0.99-cholesky-hier-bspl3 id=731
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol2.15443e-05-lb0.01-ub0.99-cholesky-hier-bspl3 id=732
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol1e-05-lb0.01-ub0.99-cholesky-hier-bspl3 id=733
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol4.64159e-06-lb0.01-ub0.99-cholesky-hier-bspl3 id=734
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol2.15443e-06-lb0.01-ub0.99-cholesky-hier-bspl3 id=735
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol1e-06-lb0.01-ub0.99-cholesky-hier-bspl3 id=736
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol4.64159e-07-lb0.01-ub0.99-cholesky-hier-bspl3 id=737
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol2.15443e-07-lb0.01-ub0.99-cholesky-hier-bspl3 id=738
%python3 generate.py --checkpoint-hack=sgpp --default-id=650 stats=cross-sisc-conv-tol1e-07-lb0.01-ub0.99-cholesky-hier-bspl3 id=739
%
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol5.01187-lb0.01-ub0.99-cholesky-hier-bspl3 id=750
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol3.98107-lb0.01-ub0.99-cholesky-hier-bspl3 id=751
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol3.16228-lb0.01-ub0.99-cholesky-hier-bspl3 id=752
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol2.51189-lb0.01-ub0.99-cholesky-hier-bspl3 id=753
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol1.99526-lb0.01-ub0.99-cholesky-hier-bspl3 id=754
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol1.58489-lb0.01-ub0.99-cholesky-hier-bspl3 id=755
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol1.25893-lb0.01-ub0.99-cholesky-hier-bspl3 id=756
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol1-lb0.01-ub0.99-cholesky-hier-bspl3 id=757
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol0.794328-lb0.01-ub0.99-cholesky-hier-bspl3 id=758
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol0.630957-lb0.01-ub0.99-cholesky-hier-bspl3 id=759
%python3 generate.py --checkpoint-hack=sgpp --default-id=652 stats=framed-cross-sga16-conv-tol0.501187-lb0.01-ub0.99-cholesky-hier-bspl3 id=760
%
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.316228-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=770
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.215443-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=771
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.14678-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=772
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.1-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=773
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.0681292-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=774
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.0464159-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=775
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.0316228-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=776
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.0215443-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=777
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.014678-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=778
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.01-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=779
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.00681292-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=780
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.00464159-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=781
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.00316228-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=782
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.00215443-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=783
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.0014678-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=784
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.001-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=785
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.000681292-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=786
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.000464159-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=787
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.000316228-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=788
%python3 generate.py --checkpoint-hack=sgpp --default-id=654 stats=sheared-cross-sisc-conv-tol0.000215443-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=789
%
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol31.6228-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=800
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol25.1189-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=801
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol19.9526-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=802
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol15.8489-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=803
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol12.5893-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=804
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol10-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=805
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol7.94328-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=806
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol6.30957-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=807
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=808
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol3.98107-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=809
%python3 generate.py --checkpoint-hack=sgpp --default-id=656 stats=sheared-framed-cross-sga16-conv-tol3.16228-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=810
%
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol1.25893-lb0.01-ub0.99-cholesky-hier-bspl3 id=820
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.794328-lb0.01-ub0.99-cholesky-hier-bspl3 id=821
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.630957-lb0.01-ub0.99-cholesky-hier-bspl3 id=822
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.501187-lb0.01-ub0.99-cholesky-hier-bspl3 id=823
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.398107-lb0.01-ub0.99-cholesky-hier-bspl3 id=824
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.316228-lb0.01-ub0.99-cholesky-hier-bspl3 id=825
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.251189-lb0.01-ub0.99-cholesky-hier-bspl3 id=826
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.199526-lb0.01-ub0.99-cholesky-hier-bspl3 id=827
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.158489-lb0.01-ub0.99-cholesky-hier-bspl3 id=828
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.125893-lb0.01-ub0.99-cholesky-hier-bspl3 id=829
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.1-lb0.01-ub0.99-cholesky-hier-bspl3 id=830
%python3 generate.py --checkpoint-hack=sgpp --default-id=658 stats=cross-3d-sga16-conv-tol0.0794328-lb0.01-ub0.99-cholesky-hier-bspl3 id=831
%
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-sga16-conv-tol31.6228-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=840
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-sga16-conv-tol25.1189-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=841
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-sga16-conv-tol19.9526-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=842
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-sga16-conv-tol15.8489-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=843
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-sga16-conv-tol12.5893-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=844
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-sga16-conv-tol10-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=845
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-sga16-conv-tol7.94328-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=846
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-sga16-conv-tol6.30957-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=847
%python3 generate.py --checkpoint-hack=sgpp --default-id=660 stats=sheared-cross-3d-sga16-conv-tol5.01187-lb0.01,0.15-ub0.99,0.85-cholesky-hier-bspl3 id=848


Using the \code{lm} software is largely a matter of familiarity
with the model design language described in Chapter \ref{chap:language}.
Computing the fitted model values and the residuals is
done with the \code{fitted} and \code{resid}.  These operators take
a model as an input.  To illustrate:
\index{P}{lm@\texttt{lm}}
\index{P}{fitted@\texttt{fitted}}
\index{P}{resid@\texttt{resid}}
\index{P}{Modeling!lm@\texttt{lm}}
\index{P}{Modeling!fitted@\texttt{fitted}}
\index{P}{Modeling!resid@\texttt{resid}}

\index{C}{residual!computing}
\index{C}{fitted model values!computing}
\index{C}{fitting!software}
\index{C}{regression report!computing}

\begin{Schunk}
\begin{Sinput}
> swim = fetchData("swim100m.csv")
> mod1 = lm(time ~ year + sex, data=swim)
> coef(mod1)
\end{Sinput}
\begin{Soutput}
(Intercept)        year        sexM
    555.717      -0.251      -9.798
\end{Soutput}
\end{Schunk}

\datasetSwimming

Once you have constucted the model, you can use \code{fitted} and
\code{resid}:
\begin{Schunk}
\begin{Sinput}
> fitted(mod1)
\end{Sinput}
\end{Schunk}
\begin{Schunk}
\begin{Soutput}
   1    2    3    4    5    6    7    8    9   10   11   12
66.9 66.1 65.6 65.1 63.6 63.1 62.6 62.1 59.6 59.3 59.1 57.1
... for 62 cases altogether ...
\end{Soutput}
\end{Schunk}

\subsection{Sums of Squares}

\index{C}{sum of squares!computing}

Computations can be performed on the fitted model values and the
residuals, just like any other quantity:
\begin{Schunk}
\begin{Sinput}
> mean(fitted(mod1))
\end{Sinput}
\begin{Soutput}
mean
59.9
\end{Soutput}
\begin{Sinput}
> var(resid(mod1))
\end{Sinput}
\begin{Soutput}
 var
15.3
\end{Soutput}
\begin{Sinput}
> sd(resid(mod1))
\end{Sinput}
\begin{Soutput}
  sd
3.92
\end{Soutput}
\begin{Sinput}
> summary(resid(mod1))
\end{Sinput}
\begin{Soutput}
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  -4.70   -2.70   -0.60    0.00    1.28   19.10
\end{Soutput}
\end{Schunk}

Sums of squares are very important in statistics.  Here's how to
calculate them for the response values, the fitted model values, and
the residuals:
\begin{Schunk}
\begin{Sinput}
> sum(swim$time^2)
\end{Sinput}
\begin{Soutput}
[1] 228635
\end{Soutput}
\begin{Sinput}
> sum(fitted(mod1)^2)
\end{Sinput}
\begin{Soutput}
[1] 227699
\end{Soutput}
\begin{Sinput}
> sum(resid(mod1)^2)
\end{Sinput}
\begin{Soutput}
[1] 936
\end{Soutput}
\end{Schunk}
The partitioning of variation by models is seen by the way
\index{C}{partitioning!sums of squares}
\index{C}{sum of squares!partitioning}
the sum of squares of the fitted and the residuals add up to the sum of squares of the response:
\begin{Schunk}
\begin{Sinput}
> 227699 + 935.8
\end{Sinput}
\begin{Soutput}
[1] 228635
\end{Soutput}
\end{Schunk}

Don't forget the squaring stage of the operation!  The sum of the
residuals (without squaring)
is very different from the sum of squares of the residuals:
\begin{Schunk}
\begin{Sinput}
> sum(resid(mod1))
\end{Sinput}
\begin{Soutput}
[1] 1.85e-14
\end{Soutput}
\begin{Sinput}
> sum(resid(mod1)^2)
\end{Sinput}
\begin{Soutput}
[1] 936
\end{Soutput}
\end{Schunk}
Take care in reading numbers formatted like
\code{1.849e-14}.   The notation stands for $1.849 \times 10^{-14}$.
That number, $0.00000000000001849$, is effectively zero compared to the
residuals themselves!
\index{C}{scientific notation}
\index{C}{zero}

\subsection{Redundancy}

\index{C}{redundancy!and NA}
\index{C}{coefficients!NA (redundancy)}
The \code{lm} operator will automatically detect redundancy and deal
with it by leaving the redundant terms out of the model.

To see how redundancy is handled, here is an example with a
constructed redundant variable in the swimming dataset.
The following statement adds a new variable to the
dataframe counting how many years after the end of World War II each
record was established:
\begin{Schunk}
\begin{Sinput}
> swim$afterwar = swim$year - 1945
\end{Sinput}
\end{Schunk}

Here is a model that doesn't involve redundancy
\begin{Schunk}
\begin{Sinput}
> mod1 = lm( time ~ year + sex, data=swim)
> coef(mod1)
\end{Sinput}
\begin{Soutput}
(Intercept)        year        sexM
    555.717      -0.251      -9.798
\end{Soutput}
\end{Schunk}

When the redundant variable is added in, \code{lm} successfully
detects the redundancy and handles it.  This is indicated by a
coefficient of NA on the redundant variable.
\begin{Schunk}
\begin{Sinput}
> mod2 = lm( time ~ year + sex + afterwar, data=swim)
> coef(mod2)
\end{Sinput}
\begin{Soutput}
(Intercept)        year        sexM    afterwar
    555.717      -0.251      -9.798          NA
\end{Soutput}
\end{Schunk}

In the absence of redundancy, the model coefficients don't depend on
the order in which the model terms are specified.  But this is not the
case when there is redundancy, since any redundancy is blamed on the
later variables.  For instance, here \VN{afterwar} has been put first
in the explanatory terms, so \code{lm} identifies \VN{year} as the
redundant variable:
\begin{Schunk}
\begin{Sinput}
> mod3 = lm( time ~ afterwar + year + sex, data=swim)
> coef(mod3)
\end{Sinput}
\begin{Soutput}
(Intercept)    afterwar        year        sexM
     66.620      -0.251          NA      -9.798
\end{Soutput}
\end{Schunk}

\index{C}{redundancy!fitted model values}
Even though the coefficients are different, the fitted model values
and the residuals are exactly the same (to within computer round-off)
regardless of the order of the
model terms.
\begin{Schunk}
\begin{Sinput}
> fitted(mod2)
\end{Sinput}
\end{Schunk}
\begin{Schunk}
\begin{Soutput}
   1    2    3    4    5    6    7    8    9   10   11   12
66.9 66.1 65.6 65.1 63.6 63.1 62.6 62.1 59.6 59.3 59.1 57.1
... for 62 cases altogether ...
\end{Soutput}
\end{Schunk}
\begin{Schunk}
\begin{Sinput}
> fitted(mod3)
\end{Sinput}
\end{Schunk}
\begin{Schunk}
\begin{Soutput}
   1    2    3    4    5    6    7    8    9   10   11   12
66.9 66.1 65.6 65.1 63.6 63.1 62.6 62.1 59.6 59.3 59.1 57.1
... for 62 cases altogether ...
\end{Soutput}
\end{Schunk}

\index{C}{redundancy!in categorical variables}
Note that whenever you use a categorical variable and an intercept
term in a model, there is a redundancy.  This is not shown explicitly.
For example, here is a model with no intercept term, and both levels
of the categorical variable \VN{sex} show up with coefficients:
\begin{Schunk}
\begin{Sinput}
> lm(time ~ sex - 1, data=swim)
\end{Sinput}
\begin{Soutput}
...
sexF  sexM
65.2  54.7
\end{Soutput}
\end{Schunk}
If the intercept term is included (as it is by default unless
\code{-1} is used in the model formula), one of the levels is simply
dropped in the report:
\begin{Schunk}
\begin{Sinput}
> lm(time ~ sex, data=swim)
\end{Sinput}
\begin{Soutput}
...
(Intercept)         sexM
       65.2        -10.5
\end{Soutput}
\end{Schunk}
Remember that this coefficient report implicitly involves a
redundancy.  If the software had been designed differently, the report
might look like this:
\begin{Schunk}
\begin{Soutput}
(Intercept)     sexF      sexM
       65.2       NA     -10.5
\end{Soutput}
\end{Schunk}


\documentclass[12pt]{article}

\usepackage[left=1cm,right=1cm,
    top=2cm,bottom=2cm,bindingoffset=0cm]{geometry}
\usepackage{braket}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{mathrsfs}
\usepackage[T2A]{fontenc}
\usepackage[utf8x]{inputenc}
\usepackage[english]{babel}
\usepackage{graphicx}
\parindent=0.5cm

\usepackage{hyperref}
\usepackage{indentfirst}

\numberwithin{equation}{section}
%\usepackage{showkeys}

\begin{document}
\section*{MSAI Statistics \& Probability – Week 7 Seminar \& HW}\\

\textbf{Problem 1:} Let $\Omega$ be countably infinite. Prove that a.s. convergence is equivalent to convergence in probability.
\\

\textbf{Problem 2:} Let $\xi_1,\,\xi_2,\,\dots$ be independent Bernoulli random variables, $\xi_k\sim\textrm{Bern}(p_k).$ Show that it is necessary and sufficient for $p_n\rightarrow0$ as $n\rightarrow\infty$ for the following things to be true:
\begin{enumerate}
    \item $\xi_n\overset{P}{\rightarrow}0$ as $n\rightarrow\infty$ ($\xi_n$ converging to zero in probability)
    \item $\xi_n\overset{L_q}{\rightarrow}0$ ($q\geq1$) as $n\rightarrow\infty$ ($\xi_n$ converging to zero in $L_q$ norm with $q\geq1$. \textit{I just used $q$ instead of $p$ in $L_p$ norm here to avoid confusion with $p_k$ – the probability of success of a trial in Bernoulli's scheme.})
\end{enumerate}
\\

\textbf{Problem 3:} Let $\{S_n,~n\in\mathbb{Z}_+\}$ be a simple random walk. Find $P(S_1\neq0,~S_2\neq0,~\dots)$ (the probability of not getting back to zero after $n$ steps for given $n$). Find the limit of this probability as $n\rightarrow\infty.$ \textit{Hint: Stirling's approximation of factorial can be useful here.}

\end{document}


\chapter{Negative Results}
\label{sec:negative}

Before developing the reflexive graph model of λST, I explored two other
modelling approaches which turned out, for different reasons, to be unsuited to
the task at hand. They are both based on the idea of interpreting size contexts
as preorder categories, types as functors from a size context category into the
category of sets and terms as natural transformation between such functors. A
model like this would yield a sort of size irrelevance in the form of the
naturality of term interpretations: if the interpretation of a term in size
context $Δ$ is natural in $⟦Δ⟧$, then $⟦Δ⟧$ must be essentially irrelevant. In
the next two sections, I briefly describe these potential models and why they do
not, in fact, model λST. This is in somewhat surprising contrast to the work of
Veltri and van der Weide \cite{veltri2019}, who model guarded recursion --
another form of type-based termination checking that is quite similar to sized
types -- using essentially the same approach that fails for λST.

\section{Covariant Presheaf Model}
\label{sec:negative:covariant}

Our first potential model starts with the observation that size contexts have a
natural interpretation as categories. Recall our previous interpretation of size
contexts as types:
\begin{Align*}
  ⟦()⟧ &=& ⊤ \\
  ⟦\ctx{Δ}{n}⟧ &=& \Sigma_{δ ∈ ⟦Δ⟧} \Size_{<⟦n⟧(δ)}.
\end{Align*}
We can extend this interpretation from types to categories: $⟦()⟧$ is the
terminal category (whose object type is $⊤$) and $⟦\ctx{Δ}{n}⟧$ is the
Grothendieck category of the functor $F ∶ ⟦Δ⟧ → \Cats$ with $F(δ) ≔
\Sizes_{<⟦n⟧(δ)}$. ($\Cats$ is the category of small categories.) Sizes are
modelled as functors $⟦n⟧ ∶ ⟦Δ⟧ → \Sizes$ where $\Sizes$ is the category of
sizes ordered by the preorder $≤$; $\Sizes_{<n}$ is the subcategory of $\Sizes$
which contains only sizes less than $n$. The objects of $⟦Δ⟧$ are then
telescopes of sizes, as before, and an arrow $f ∶ δ → δ′$ in $⟦Δ⟧$ is a proof
that the sizes in $δ$ are pointwise less than or equal to the sizes in $δ′$. The
judgment $Δ ⊢ n < m$ is modelled by a proof that $⟦n⟧(δ) < ⟦m⟧(δ)$ for arbitrary
$δ ∶ ⟦Δ⟧$.

Continuing the categorical interpretation, we model types in a size context $Δ$
as functors from $⟦Δ⟧$ to $\Sets$, the category of sets (or rather, since we work
in type theory, types). These are \enquote*{covariant presheaves}, meaning
presheaves over the opposite category of $⟦Δ⟧$, $\Op{⟦Δ⟧}$.

One problem with this approach becomes apparent already at this stage: the type
$\Stream{n}$ of sized streams has no natural interpretation as a covariant
functor from $⟦Δ⟧$ to $\Sets$. We would like to define, as before,
\begin{displaymath}
  ⟦\Stream{n}⟧(δ) ≔ ℕ_{<⟦n⟧(δ)} → ℕ
\end{displaymath}
but this is no functor: for $δ ≤ δ′$ we have $⟦n⟧(δ) ≤ ⟦n⟧(δ′)$ by functoriality
of $⟦n⟧$, but there is no appropriate function from $ℕ_{<⟦n⟧(δ)} → ℕ$ to
$ℕ_{<⟦n⟧(δ′)} → ℕ$. This is not surprising -- after all, ⟦\Stream{n}⟧(δ) is
naturally contravariant in $δ$.

Still, let us ignore this problem and move on to discover more fundamental
issues. The other types of λST have more or less natural interpretations:
\begin{Align*}
  ⟦\Nat{n}⟧(δ) &≔& ℕ_{≤⟦n⟧(δ)} \\
  ⟦T → U⟧(δ) &≔& \All{δ′ ≥ δ}{⟦T⟧(δ′) → ⟦U⟧(δ′)} \\
  ⟦\All{n}{T}⟧(δ) &≔& \All{δ′ ≥ δ}{\All{m < ⟦n⟧(δ′)}{⟦T⟧(δ′, m)}}.
\end{Align*}
Sized natural numbers $\Nat{n}$ are interpreted as before. The function space $T
→ U$ is modelled by the exponential of presheaves, which ensures that we can
also model abstractions and applications. The exponential is defined using a
monotonisation \enquote*{trick}: the function space $⟦T⟧(δ) → ⟦U⟧(δ)$ would not
be functorial due to the negative occurrence of $δ$, but we can force
functoriality by quantifying over $δ′ ≥ δ$. The same approach also allows us to
interpret size quantification, where again the natural interpretation without
monotonisation would not be functorial.

Unfortunately, while this monotonisation trick works for the exponential, it
does not yield an appropriate model of size quantification. This is not very
surprising: in the above interpretation of $\All{n}{T}$, the size that we
introduce in the model, $m$, is not, in general, smaller than $⟦n⟧(δ)$. The
bound $m < ⟦n⟧(δ′)$ does not actually restrict the domain of $m$ since $δ′ ≥ δ$
and thus $⟦n⟧(δ′) ≥ ⟦n⟧(δ)$. The reader is invited to check that this prevents
us from interpreting $\mathrm{fix}$.

\section{Contravariant Presheaf Model}
\label{sec:negative:contravariant}

Seeing that the major problem with the previous model was the need to
force-monotonise the interpretation of size quantification, we now consider a
model based on \emph{contravariant} presheaves (i.e.\ just presheaves). Size
quantification is naturally contravariant, so no trickery is necessary to
interpret it. Indeed, this approach leads to a more satisfactory interpretation
of types (sizes, size contexts etc.\ are modelled as before):
\begin{Align*}
  ⟦\Stream{n}⟧(δ) &≔& ℕ_{≤⟦n⟧(δ)} → ℕ \\
  ⟦T → U⟧(δ) &≔& \All{δ′ ≤ δ}{⟦T⟧(δ′) → ⟦U⟧(δ′)} \\
  ⟦\All{n}{T}⟧(δ) &≔& \All{m < ⟦n⟧(δ)}{⟦T⟧(δ, m)}.
\end{Align*}

With the switch to contravariant functors, we lose the ability to model sized
natural numbers, but gain the ability to model sized streams. As before, the
function space is interpreted as an exponential of presheaves. Size
quantification does not require monotonisation any more, and indeed this
approach appears, on the surface, to support natural interpretations of all
terms including $\mathrm{fix}$.\footnote{The above interpretation of size
  quantification is not quite accurate: to successfully model λST, we would need
  to restrict it to allow only size-parametric functions, as in the reflexive
  graph model. However, this is unimportant for the rest of the discussion.}

Alas, the contravariant presheaf approach still fails, this time due to a more
subtle problem: the substitution lemma for size substitution in types does not
hold. This means that in general we have
\begin{displaymath}
  ⟦\sub{T}{σ}⟧ ≠ \sub{⟦T⟧}{⟦σ⟧}.
\end{displaymath}

To see why, we first consider the interpretation of substitutions. Recall that
in the reflexive graph model, a well-typed substitution $σ ∶ Δ ⇒ Ω$ was
interpreted as a function between the types $⟦Δ⟧$ and $⟦Ω⟧$. Here, we upgrade
this interpretation to a functor between the categories $⟦Δ⟧$ and $⟦Ω⟧$, but the
underlying function remains the same. Semantic substitution is composition:
given a type $T$ in size context $Ω$, whose interpretation is a functor from
$⟦Ω⟧$ to $\Sizes$, we define
\begin{displaymath}
  \sub{⟦T⟧}{⟦σ⟧} ≔ ⟦T⟧ ∘ ⟦σ⟧.
\end{displaymath}

Now consider the substitution which assigns to the zeroth variable (in an
otherwise empty context) the size $1$:
\begin{displaymath}
  σ ≔ \Sing(\ssuc{0}) ∶ () → \ctx{()}{∞}.
\end{displaymath}
Its interpretation is $⟦σ⟧(()) = ((), 1)$, where $()$ is the sole inhabitant of
the unit type. Further, let $T$ be the following type (in the context
$\ctx{()}{∞}$) of functions from streams to an arbitrary closed type $U$:
\begin{displaymath}
  T ≔ \Stream{v_0} → U.
\end{displaymath}
Then we have
\begin{align*}
  ⟦\sub{T}{σ}⟧(())
    &= ⟦\Stream{1} → U⟧(()) \\
    &= \All{() ≤ ()}{⟦\Stream{1}⟧(()) → ⟦U⟧(())} \\
    &= \All{() ≤ ()}{(\All{k ≤ 1}{ℕ}) → ⟦U⟧(())} \\
    &≅ (\All{k ≤ 1}{ℕ}) → ⟦U⟧(())
  \\
  \sub{⟦T⟧}{⟦σ⟧}(())
    &= ⟦T⟧(⟦σ⟧(())) \\
    &= ⟦\Stream{v_0} → U⟧((), 1) \\
    &= \All{m ≤ 1}{⟦\Stream{v_0}⟧((), m) → ⟦U⟧((), m)} \\
    &= \All{m ≤ 1}{(\All{k ≤ m}{ℕ}) → ⟦U⟧(())}.
\end{align*}
These two types are not isomorphic, so substitutions do not have the desired
semantics.


\documentclass[compress, english, aspectratio=169]{beamer}

\usepackage{pythontex} % To run Python code
\usepackage[utf8]{inputenc}
\usepackage{amssymb}
%\usepackage{graphicx}
\usepackage{csquotes}
\graphicspath{{images/}}

\usepackage[scheme=plain]{ctex} % To display Chinese characters

\usetheme[navigation]{UMONS}
%\usetheme[navigation, no-subsection, no-totalframenumber]{UMONS}

\newcommand{\IR}{\mathbb{R}}

%% Presentation information
\title{Industrial Instrumentation: Design of Experiments}
\subtitle{GUI project with Python and PyQt5}
\author[V. \textsc{Stragier}]{Vincent \textsc{Stragier}}
\date{16th of June}
\institute[| FPMs]{%
  Faculty of Engineering\\
  University of  Mons
  \\[2ex]
  \includegraphics[height=6ex]{LOGO_UMONS_EN}\hspace{2em}
  \includegraphics[height=6ex]{LOGO_FPMs}
}

\begin{document}
% Setup pythontex to be able to import another module located in other path
\begin{pyconcode}
import os;
os.chdir('../')
import sys
sys.path.append("..\\src")
sys.path.append(os.getcwd())
sys.path = list(set(sys.path))
\end{pyconcode}

%% Title
\begin{frame}[plain]
  \titlepage
\end{frame}

%% Table of content
\begin{frame}
  \tableofcontents
\end{frame}

%% Proverb
\begin{frame}
\frametitle{Chinese proverb}
\begin{block}{读万卷书不如行万里路。(Dú wànjuànshū bù rú xíng wànlǐlù)}
It's better to walk thousands of miles than to read thousands of books.
\end{block}
\end{frame}

%% Theory
\section{Theory about the 2 factorial Design of Experiments}
\subsection{Factorial design}
\begin{frame}
\frametitle{Factorial design}
\begin{block}{Goals}
\begin{itemize}
\item efficient measurement:
\begin{itemize}
\item quickly arrive at the best possible results
\item omit unnecessary trials
\item give results with the lowest uncertainty
\item progress without failure
\item establish a model for the studied phenomenon
\item discover the optimal solution
\end{itemize}
\end{itemize}
\end{block}

\begin{equation}
m = m_0^{n}
\end{equation}

where $m$ is the number of measurements, $m_0$ is the number of levels and $n$ is the number of factors that you want to adjust. For the program $m_0=2$ is assumed. It will define the number of measurements to take in the experimental space.
\end{frame}

\section{Python implementation}
\subsection{How to program}
\begin{frame}
\frametitle{How to program}
\begin{block}{Setup}
\begin{itemize}
\item sheets of paper and pen
\item book(s) or internet connection
\item a computer
\item an IDE
\end{itemize}
\end{block}
\end{frame}

\begin{frame}
\frametitle{How to program}
\begin{block}{Methodology}
\begin{itemize}
\item up-to-date state-of-the-art
\item scheme of your program
\item use the classical naming standards
\item testing and debugging method
\item document your code
\item implement the minimal functions first
\item do your research before asking anything
\end{itemize}
\end{block}
\end{frame}

\subsection{Core functions}
\subsubsection{Algorithm}
\begin{frame}
\frametitle{Core functions}
\framesubtitle{Algorithm}
\begin{align*}
\hat{\underline{a}} = \left(X^T X\right)^{-1} X^T \underline{y}
\end{align*}

\noindent where:

\begin{description}
\item[$\hat{\underline{a}}$] is a vector of coefficients (of shape $p\times 1$)
\item[$\underline{y}$] is a vector of measures (of shape $p\times 1$)
\item[$X^T$] is the transposed form of the matrix $T$
\item[$\left(X^T X\right)$] is the square information matrix (of shape $p\times p$)
\item[$\left(X^T X\right)^{-1}$] is the square dispersion matrix (of shape $p\times p$)
\end{description}
\end{frame}

\subsubsection{Aim}
\begin{frame}
\frametitle{Core functions}
\framesubtitle{Aim}
The aim is to compute the estimation of the coefficients to provide a model for the experiment. In our case the following model can be used:

\begin{align*}
y = \hat{a}_0 + \sum^n_{i=1} \hat{a}_i x_i + \sum^n_{i=1} \sum^n_{j=1} \hat{a}_{ij} x_i {x}_j + ...
\end{align*}

To ease the resolution of the coefficients, $\hat{X}$ is defined as followed:
\begin{equation*}
\hat{X} = \left(X^T X\right)^{-1} X^T
\end{equation*}
\end{frame}

\subsubsection{Console full example}
\begin{frame}[fragile]
\frametitle{Core functions}
\framesubtitle{Console full example}
\begin{pyconsole}
import design_of_experiments as doe
X_hat = doe.gen_X_hat(n=3)
X_hat
\end{pyconsole}
\end{frame}

\begin{frame}[fragile]
\frametitle{Core functions}
\framesubtitle{Console full example (continued)}
\begin{pyconsole}
# Speed [mg/min]
y1 = [53, 122, 20, 125, 48, 70, 68, 134]
# Cobalt Content [ppm]
y2 = [4100, 3510, 3950, 1270, 4870, 2810, 7750, 3580]
# Compute the coefficients
import numpy as np
a_hat_1 = np.dot(X_hat, y1)
a_hat_2 = np.dot(X_hat, y2)
a_hat_1
a_hat_2
\end{pyconsole}
\end{frame}

\subsection{GUI programming (baselines)}
\begin{frame}
\frametitle{GUI programming (baselines)}
In the frame of this project, I have used the book \textit{Understanding Optics with Python, Vasudevan Lakshminarayanan, Hassen Ghalila, Ahmed Ammar, and L. Srinivasa Varadharajan,  CRC Press, 2018}.
\begin{block}{Main steps}
\begin{itemize}
\item design the GUI on the Qt Designer tool
\item convert the .ui file generated in a Python script
\item create a new script that will import the generated script and make the links between the main script and the GUI script
\end{itemize}
\end{block}
Useful resource: \url{www.learnpyqt.com/}
\end{frame}

\section{Demonstration}
\subsection{Requirements}
\begin{frame}
\frametitle{Requirements}
\begin{block}{Program and modules}
\begin{itemize}
\item Python 3.8.0 or above
\item the source code (\url{https://github.com/2010019970909/design_of_experiments})
\item any working LaTeX installation
\item Python modules:\\
\begin{description}
\item[scikit] for the statistics
\item[numpy] for the math (matrix dot product, etc.)
\item[matplotlib] for the plots
\item[PyQt5] for the GUI
\item[PyQt5-tools] to further development
\end{description}
\end{itemize}
\end{block}
\pyb{py -3.8 -m pip install --upgrade sklearn numpy matplotlib PyQt5 PyQt5-tools}
\end{frame}

\subsection{Live demo or video}
\begin{frame}
\frametitle{Live demo or video}
\begin{block}{Video}
\url{https://youtu.be/2I9Mx7gjNnI}
\end{block}
\end{frame}

\section{Conclusion}
\begin{frame}
\frametitle{Conclusion}
\begin{block}{Features}
\begin{itemize}
\item minimal module for DoE
\item GUI:
\begin{itemize}
\item input up to $2^8$ measures
\item plot charts (coefficients, Pareto, Henry)
\item save the result in a file (.csv or .xls(x))
\item open a file to compute the results
\item evaluation of mathematical expression in the input
\end{itemize}
\end{itemize}
\end{block}
\end{frame}

\begin{frame}
\frametitle{Conclusion (continued)}
\begin{block}{Improvements}
\begin{itemize}
\item add an interpolation engine (knowing the limits of the experimental space)
\item add the uncertainties on each coefficient and in the charts
\item add the possibility of studying multiple quantities at once
\item add more charts to enhance the coefficients analyse (contour plot, 2 by 2 correlation)
\item create a better import tool for the files
\item improve the design of the GUI
\item improve the runtime if possible
\end{itemize}
\end{block}
\end{frame}
\end{document}