Add auxiliary results

Fri, 28 Mar 2025 08:36:08 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Fri, 28 Mar 2025 08:36:08 -0500
changeset 59
743984f4664e
parent 58
2a86c4c98622
child 60
680e7ec7c7f8

Add auxiliary results

README.md file | annotate | diff | comparison | revisions
doc/aux_results.pdf file | annotate | diff | comparison | revisions
doc/aux_results.tex file | annotate | diff | comparison | revisions
doc/jnsao.bst file | annotate | diff | comparison | revisions
doc/jnsao.cls file | annotate | diff | comparison | revisions
doc/symbols-texonly.tex file | annotate | diff | comparison | revisions
doc/symbols.tex file | annotate | diff | comparison | revisions
--- a/README.md	Thu Jan 23 23:40:20 2025 +0100
+++ b/README.md	Fri Mar 28 08:36:08 2025 -0500
@@ -60,7 +60,7 @@
 pdflatex cylinder
 ```
 
-## Internals
+## Internals and auxiliary results
 
 If you are interested in the program internals, the integrated source code
 documentation may be built and opened with
@@ -73,3 +73,7 @@
 `rustdoc`, akin to Rust largely itself, is stuck in 80's 7-bit gringo ASCII
 world, and does not support modern markdown features, such as mathematics.
 
+In the `doc/` subdirectory, you can find `aux_results.pdf` (and `.tex`) that
+includes additional detailed geodesic formulas that are not included in the
+main manuscript. 
+
Binary file doc/aux_results.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/aux_results.tex	Fri Mar 28 08:36:08 2025 -0500
@@ -0,0 +1,492 @@
+\pdfoutput=1
+\documentclass[a4paper,english]{jnsao}
+\usepackage[utf8]{inputenc}
+\usepackage{enumerate}
+\usepackage[shortlabels]{enumitem}
+%\usepackage{lineno}\linenumbers
+\usepackage{comment}
+\usepackage[nameinlink,capitalize]{cleveref}
+\usepackage{blkarray}
+\usepackage{booktabs}
+\usepackage{float}
+\usepackage[rightcaption]{sidecap}
+\sidecaptionvpos{figure}{m}
+
+%\usepackage{changes-simple}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Symbols
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\input{symbols}
+\input{symbols-texonly}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Todos
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\setlength{\marginparwidth}{2cm}
+\usepackage[textsize=footnotesize,colorinlistoftodos]{todonotes}
+\newcommand{\hktodo}[2][]{\todo[color=DarkGreen!40,#1]{#2}}
+\newcommand{\tvtodo}[2][]{\todo[color=DarkRed!40,#1]{#2}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Set up cleveref for nicer referencing
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage[nameinlink,capitalize]{cleveref}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% New theorem-like environments
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\theoremstyle{definition}
+\newtheorem{assumption}[theorem]{Assumption}
+\newtheorem{algorithm}[theorem]{Algorithm}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% TikZ
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \usetikzlibrary{external}
+\usetikzlibrary{decorations.pathmorphing}
+\usepackage{wrapfig}
+\usepackage{tikz-3dplot}
+% \tikzexternalize[prefix=build/]
+% \tikzexternaldisable
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Manuscript information.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Manuscript title.
+\title{Geodesics on a cube and a capped cylinder}
+
+% Manuscript date.
+% Use ISO-8601 standard yyyy-mm-dd date format.
+%\date{\ISOToday}
+
+% Authorship.
+% Give affiliations and contact information using \thanks.
+% \shortauthor is a plain surname-only version for running heads.
+\author{Heikki von Koch}
+
+\shortauthor{von Koch}
+
+% Acknowledgements: funding, etc.
+% \acknowledgements{}
+
+% Licensing information
+\manuscriptcopyright{}
+\manuscriptlicense{}
+
+% Fill this information once accepted for publication and the information
+% is provided by the editors
+%\manuscriptsubmitted{2018-12-14}
+%\manuscriptaccepted{2018-12-14}
+%\manuscriptvolume{1}
+%\manuscriptnumber{0}
+%\manuscriptyear{2018}
+%\manuscriptdoi{not_assigned}
+%\manuscriptstatus{}
+
+%% You can also set the following information to include the eprint
+%% information in the header
+%\manuscripteprinttype{arXiv}
+%\manuscripteprint{1901.00001}
+%\manuscripteprinttype{HAL}
+%\manuscripteprint{hal--01969102}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{document}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\maketitle
+
+\section{Geodesics on a cube}
+
+\tdplotsetmaincoords{50}{25}
+\begin{tikzpicture}
+		[tdplot_main_coords,
+			cube/.style={very thick,black},
+			grid/.style={very thin,gray},
+			axis/.style={->,blue,thick}]
+
+	%grid
+	\foreach \x in {-1.5,-1,...,1.5}
+		\foreach \y in {-1.5,-1,...,1.5}
+		{
+			\draw[grid] (\x,-1.5) -- (\x,1.5);
+			\draw[grid] (-1.5,\y) -- (1.5,\y);
+		}
+
+	%axes
+	\draw[axis] (-1,-1,0) -- (2,-1,0) node[anchor=west]{$x$};
+	\draw[axis] (-1,-1,0) -- (-1,2,0) node[anchor=west]{$y$};
+	\draw[axis] (-1,-1,0) -- (-1,-1,3) node[anchor=west]{$z$};
+
+	%top and bottom
+	\draw[cube] (-1,-1,0) -- (-1,1,0) -- (1,1,0) -- (1,-1,0) -- cycle;
+	\draw[cube] (-1,-1,2) -- (-1,1,2) -- (1,1,2) -- (1,-1,2) -- cycle;
+	
+	%edges
+	\draw[cube] (-1,-1,0) -- (-1,-1,2);
+	\draw[cube] (-1,1,0) -- (-1,1,2);
+	\draw[cube] (1,1,0) -- (1,1,2);
+	\draw[cube] (1,-1,0) -- (1,-1,2);
+
+    %points
+    \filldraw[black] (-1,-1) circle (2pt) node[anchor=east]{$O$};
+    \filldraw[black] (1,1) circle (2pt) node[anchor=west]{$(1,1,0)$};
+    \filldraw[black] (1,1,2) circle (2pt) node[anchor=west]{$(1,1,1)$};
+    \filldraw[black] (-1,1,2) circle (2pt) node[anchor=south]{$(0,1,1)$};
+    \filldraw[black] (-1,-1,2) circle (2pt) node[anchor=east]{$(0,0,1)$};
+        
+\end{tikzpicture} \hspace{1em}
+\tdplotsetmaincoords{60}{20}
+\begin{tikzpicture}
+		[tdplot_main_coords,
+			cube/.style={very thick,black},
+			axis/.style={->,blue,thick}]
+
+	%axes
+	\draw[axis] (-1,-1,0) -- (-1,-1,1) node[anchor=east]{$y_4$};
+ 	\draw[axis] (-1,-1,0) -- (0.1,-1,0) node[anchor=north]{$x_4$};
+	\draw[axis] (-1,1,0) -- (-1,0.1,0) node[anchor=west]{$x_3$};
+ 	\draw[axis] (-1,1,0) -- (-1,1,1) node[anchor=west]{$y_3$};
+    \draw[axis] (1,1,0) -- (1,1,1) node[anchor=west]{$y_5$};
+ 	\draw[axis] (1,1,0) -- (0,1,0) node[anchor=south]{$x_5$};
+    \draw[axis] (1,-1,0) -- (1,-1,1) node[anchor=west]{$y_2$};
+ 	\draw[axis] (1,-1,0) -- (1,0,0) node[anchor=west]{$x_2$};
+
+	%top and bottom
+	\draw[cube] (-1,-1,0) -- (-1,1,0) -- (1,1,0) -- (1,-1,0) -- cycle;
+	\draw[cube] (-1,-1,2) -- (-1,1,2) -- (1,1,2) -- (1,-1,2) -- cycle;
+	
+	%edges
+	\draw[cube] (-1,-1,0) -- (-1,-1,2);
+	\draw[cube] (-1,1,0) -- (-1,1,2);
+	\draw[cube] (1,1,0) -- (1,1,2);
+	\draw[cube] (1,-1,0) -- (1,-1,2);
+
+    %label faces
+    \draw(1,0,1) node{$2$};
+    \draw(0,-1,1) node{$4$};
+    \draw(0,0,2) node{$6$};
+    \draw[gray!100](0,0,0) node{$1$};
+    \draw[gray!100](-1,0,1) node{$3$};
+    \draw[gray!100](0,1,1) node{$5$};
+
+\end{tikzpicture} \hspace{2em}
+\tdplotsetmaincoords{60}{20}
+\begin{tikzpicture}
+		[tdplot_main_coords,
+			cube/.style={very thick,black},
+			axis/.style={->,blue,thick}]
+
+	%axes
+	\draw[axis] (-1,-1,0) -- (0.1,-1,0) node[anchor=north]{$x_1$};
+	\draw[axis] (-1,-1,0) -- (-1,0.1,0) node[anchor=west]{$y_1$};
+ 	\draw[axis] (-1,-1,2) -- (0.1,-1,2) node[anchor=north]{$x_6$};
+	\draw[axis] (-1,-1,2) -- (-1,0.1,2) node[anchor=east]{$y_6$};
+
+	%top and bottom
+	\draw[cube] (-1,-1,0) -- (-1,1,0) -- (1,1,0) -- (1,-1,0) -- cycle;
+	\draw[cube] (-1,-1,2) -- (-1,1,2) -- (1,1,2) -- (1,-1,2) -- cycle;
+	
+	%edges
+	\draw[cube] (-1,-1,0) -- (-1,-1,2);
+	\draw[cube] (-1,1,0) -- (-1,1,2);
+	\draw[cube] (1,1,0) -- (1,1,2);
+	\draw[cube] (1,-1,0) -- (1,-1,2);
+
+    %label faces
+    \draw(1,0,1) node{$2$};
+    \draw(0,-1,1) node{$4$};
+    \draw(0,0,2) node{$6$};
+    \draw[gray!100](0,0,0) node{$1$};
+    \draw[gray!100](-1,0,1) node{$3$};
+    \draw[gray!100](0,1,1) node{$5$};
+
+\end{tikzpicture}
+
+We start our examples with a cube (surface) of side length $1$ with the origin of $\R^3$ and labelling of its faces as indicated by the pictures. For the standard $\R^3$-coordinates, we always use the triple $(\cdot,\cdot,\cdot)$. In addition, each face $F$ has their own fixed local two-dimensional coordinate system denoted by $(x_F,y_F)_F$, where $F \in \{1,2,3,4,5,6\}$ and $x_F,y_F \in [0,1]$ (we shall often just use the shorthand notation $(x,y)_F$). Their orientations are shown above.
+
+As an example, we have that $(0,0)_1 = (1,0)_3 =(0,0)_4$ and $(1,0)_6 = (0,1)_2 =(1,1)_4$ and, in fact, we always have $(x,y)_1 = (x,y,0)$ and $(x,y)_6 = (x,y,1)$ (permanently fixing the vertices). 
+
+\subsection{Anatomy of geodesics on a cube}
+
+All geodesics on the cube are straight lines when the cube is unfolded in any manner but not all straight lines in the unfolding are geodesics as, for example, some go through a vertex and some appear to go through a face onto the same face. The important fact is that the globally shortest straight lines are always geodesics. There are effectively three different places where the geodesic might end with respect to the starting point:
+    \begin{enumerate}
+        \item the endpoint is on the same face;
+        \item the endpoint is on an adjacent face;
+        \item the endpoint is on the opposite face.
+    \end{enumerate}
+
+Geodesics of the 1. kind are obviously regular straight lines in the plane and need no further analysis.
+
+Geodesics of the 2. kind have three options: going through the shared side or going through either of the faces that also share a side with the face of the endpoint. For example, let the starting point be on face $1$ and the endpoint on face $2$, then we have the three options: $1-2$, $1-5-2$, and $1-4-2$, where $a-b-c$ means that we start from face $a$, move to face $b$, and move to face $c$ where we stop.
+
+Geodesics of the 3. kind have 12 options: for each adjacent face, there are three options (as can be seen from the 2. kind). Note that not all of these will necessarily be actual geodesics with the same being true for geodesics of the 2. kind. However, at least one of them will be a geodesic as well as realise the globally shortest path between the start and endpoints.
+
+Now all we need are the face-to-face transformations between local coordinate systems, which can then be composed together to make longer chains between the faces. A coordinate transformation from one face to another is made by rotating (with respect to the common edge) the target face onto the same plane as the starting face (keeping this face fixed) such that there is no overlap. For the unfoldings of the different coordinate grids, we essentially need two transformations of a point $(x,y)$ on the plane:
+    \begin{itemize}
+        \item Rotation of $(x,y)$ about a point $(a,b)$ for $+90^\circ$: $(x,y) \rightarrow (b+a-y, b-a+x)$;
+        \item Rotation of $(x,y)$ about a point $(a,b)$ for $-90^\circ$: $(x,y) \rightarrow (a-b+y, a+b-x)$.
+    \end{itemize}
+The following matrix contains all of the coordinate transformations between the faces with $x,y \in [0,1]$ and their standard three-dimensional coordinates.
+
+%\begin{equation*}
+%\begin{array}{|c | c | c | c | c | c|}
+% \hline
+% (x,y)_1 & (x,y)_2 & (x,y)_3 & (x,y)_4 & (x,y)_5 & (x,y)_6\\
+% \hline
+% (y,x-1)_2 & (y+1,x)_1 & (-y,1-x)_1 & (x,-y)_1 & (1-x,y+1)_1 & (y,2-x)_2\\ 
+% 
+% (1-y,-x)_3 & (x+1,y)_4 & (x-1,y)_4 & (x-1,y)_2 & (x+1,y)_2 & (1-y,x+1)_3\\
+% 
+% (x,-y)_4 & (x-1,y)_5 & (x+1,y)_5 & (x+1,y)_3 & (x-1,y)_3 & (x,y+1)_4\\
+% 
+% (1-x,y-1)_5 & (2-y,x)_6 & (y-1,1-x)_6 & (x,y-1)_6 & (1-x,2-y)_6 & (1-x,2-y)_5\\
+% 
+% (x,y,0) & (1,x,y) & (0,1-x,y) & (x,0,y) & (1-x,1,y) & (x,y,1)\\
+% \hline
+%\end{array}
+%\end{equation*}
+%\begin{center}
+%Table 1: A local coordinate system, its representation on an adjacent face, and its %standard coordinate.
+%\end{center}
+%\vspace{2pt}
+
+\begin{center}
+\[
+\begin{blockarray}{ccccccc}
+        \R^3 & (x,y,0) & (1,x,y) & (0,1-x,y) & (x,0,y) & (1-x,1,y) & (x,y,1) \\
+        \cmidrule{1-7}
+        & 1 & 2 & 3 & 4 & 5 & 6 \\
+\begin{block}{c(cccccc)}
+        1 & (x,y)_1 & (y+1,x)_1 & (-y,1-x)_1 & (x,-y)_1 & (1-x,y+1)_1 & \\
+        2 & (y,x-1)_2 & (x,y)_2 &  & (x-1,y)_2  & (x+1,y)_2 & (y,2-x)_2 \\
+        3 & (1-y,-x)_3 &  & (x,y)_3 & (x+1,y)_3 & (x-1,y)_3 & (1-y,x+1)_3 \\
+        4 & (x,-y)_4 & (x+1,y)_4 & (x-1,y)_4 & (x,y)_4 & & (x,y+1)_4\\
+        5 & (1-x,y-1)_5 & (x-1,y)_5 & (x+1,y)_5 & & (x,y)_5 & (1-x,2-y)_5 \\
+        6 & & (2-y,x)_6 & (y-1,1-x)_6 & (x,y-1)_6 & (1-x,2-y)_6 & (x,y)_6 \\
+\end{block}
+\end{blockarray}
+\]
+\end{center}
+
+Note the abundance of regularity in the table because of the way the local coordinate systems were chosen. The side faces all share the $y$-coordinate, and the $x$-coordinate always has the same orientation, that is, the coordinate transformations from one side face to the next when going counterclockwise (or clockwise, for that matter) are the same.
+
+
+\subsection{Coordinate calculations}
+
+The distances can now be easily calculated with the Pythagorean theorem. For example, let our starting point $(x_1,y_1)_1$ be on face $1$ and endpoint $(x_2,y_2)_2$ on face $2$. First we need to figure out the three different possible coordinates of $(x_2,y_2)_2$ in the coordinate system of face $1$ by composing the transformations together using Table 1:
+    \begin{enumerate}
+        \item Path $1-2$: $(x,y)_2 \to (y+1,x)_1$;
+        \item Path $1-5-2$: $(x,y)_2 \to (x-1,y)_5 \to (2-x,y+1)_1$;
+        \item Path $1-4-2$: $(x,y)_2 \to (x+1,y)_4 \to (x+1,-y)_1$.
+    \end{enumerate}
+This gives us three possible shortest paths between them with the distances
+    \begin{enumerate}
+        \item Path $1-2$: $d((x_1,y_1)_1,(x_2,y_2)_2) = \sqrt{(x_1-(y_2+1))^2 + (y_1-x_2)^2}$;
+        \item Path $1-5-2$: $d((x_1,y_1)_1,(x_2,y_2)_2) = \sqrt{(x_1-(2-x_2))^2 + (y_1-(y_2+1))^2}$;
+        \item Path $1-4-2$: $d((x_1,y_1)_1,(x_2,y_2)_2) = \sqrt{(x_1-(x_2+1))^2 + (y_1+y_2)^2}$.
+    \end{enumerate}
+
+Let $(x_1,y_1)_1=(1/2,1/2)_1$ and the endpoint similarly be the middle point of face $2$, that is, $(1/2,1/2)_2$. Clearly the shortest distance between the start and endpoint is $1$. The distance formulas give us $1,\sqrt{2},\sqrt{2}$, respectively, that is, the shortest path is rather unsurprisingly through the common side (in fact, the other paths aren't geodesics at all since they go through vertices as can be seen from drawing a simple picture).
+
+Lets change our starting point to $(1/4,3/4)_1$ and our endpoint to $(3/4,3/4)_2$. Now we have the distances $3/2,\sqrt{2},\sqrt{18}/2$, respectively, that is, the shortest path is through face $5$.
+
+\begin{SCfigure}[1][h]
+\begin{tikzpicture}
+    \draw[step=1cm,gray,very thin] (-1,-3) grid (3,3);
+    \draw[thick,-] (-1,-1) -- (1,-1);
+    \draw[thick,-] (-1,1) -- (1,1);
+    \draw[thick,-] (1,3) -- (1,-3);
+    \draw[thick,-] (-1,-3) -- (-1,3);
+    \draw[thick,-,red] (3,-3) -- (3,-1);
+    \draw[thick,-] (3,-1) -- (3,1);
+    \draw[thick,-,blue] (3,1) -- (3,3);
+    \draw[thick,-,red] (1,-3) -- (1,-1);
+    \draw[thick,-] (1,-1) -- (1,1);
+    \draw[thick,-,blue] (1,1) -- (1,3);
+    \draw[thick,-] (-1,3) -- (1,3);
+    \draw[thick,-,blue] (1,3) -- (3,3);
+    \draw[thick,-] (-1,-3) -- (1,-3);
+    \draw[thick,-,red] (1,-3) -- (3,-3);
+    \draw(-0.85,0.8) node{$1$};
+    \draw(-0.85,2.8) node{$5$};
+    \draw(-0.85,-1.2) node{$4$};
+    \draw(1.15,0.8) node{$2$};
+    \draw(1.15,2.8) node{$2$};
+    \draw(1.15,-1.2) node{$2$};
+    \draw[decorate,decoration={zigzag, amplitude = 0.4mm},blue] (1,1) -- (3,1);
+    \draw[decorate,decoration={zigzag, amplitude = 0.4mm},red] (1,-1) -- (3,-1);
+    \draw[thick,->] (-1,0) -- (3,0) node[anchor=west] {x};
+    \draw[thick,->] (0,-3) -- (0,3) node[anchor=south] {y};
+    \filldraw[black] (-1,-1) circle (2pt) node[anchor=north east]{$(0,0)$};
+    \filldraw[black] (-0.5,0.5) circle (2pt) node[anchor=north east]{$(1/4,3/4)$};
+    \filldraw[blue] (1.5,2.5) circle (2pt) node[anchor=west]{$(5/4,7/4)$};
+    \filldraw[black] (2.5,0.5) circle (2pt) node[anchor=west]{$(7/4,3/4)$};
+    \filldraw[red] (2.5,-2.5) circle (2pt) node[anchor=west]{$(7/4,-3/4)$};
+    \draw[thick,-,blue] (-0.5,0.5) -- (1.5,2.5);
+    \draw[thick,-] (-0.5,0.5) -- (2.5,0.5);
+    \draw[dashed,-,red] (-0.5,0.5) -- (2.5,-2.5);
+    \node[fill=blue, fill opacity=0.3, scale=7.8] at (2,2) {};
+    \node[fill=red, fill opacity=0.4, scale=7.8] at (2,-2) {};
+\end{tikzpicture}
+\caption*{An unfolding of the cube with the labels of the faces marked on their upper left corners. Included are the three colour-coded paths from face $1$ to face $2$ with starting point $(1/4,3/4)_1$ and endpoint $(3/4,3/4)_2$, and their endpoints in the coordinate system of face $1$. The dashed red path is not a geodesic as it goes through the vertex $(1,0)_1$. Note that the two zigzag edges between faces $2$ are not real but merely artifacts of the drawing.}
+\end{SCfigure}
+
+
+\section{Geodesics on a capped cylinder}
+
+A cylinder (more specifically, a right circular cylinder) is a surface defined as the set of points $x,y,z \in \R$ such that $(x,y,z) = (r\cos \theta, r\sin \theta, z) = (\theta,z)$, where $r>0$ is the radius of the circle defined by $x$ and $y$. Furthermore, we will consider the capped cylinder by adding circular discs of the same radius $r$ to the top and bottom of the cylinder.
+
+\subsection{Geodesics on either the side or the top and bottom discs}
+
+Geodesics between points on the same discs are clearly straight lines and one can check (using the geodesic equation) that geodesics on the side are helices (in the degenerate cases, these include straight lines and arcs of circles). A helix is a space curve parametrised by
+    \[
+        x(\phi) = r \cos \phi, \quad y(\phi) = r \sin \phi, \quad z(\phi) = c \phi, \quad \text{for} \, \phi \in [0,d],
+    \]
+where $c$ is a constant such that $2\pi c$ gives the vertical separation of the helix's loops and $d$ a parameter depending on $c$, such that we stay on the side of the cylinder (so not in the interior of top or bottom disc). Instead of vertical separation, one could also say that the helix has a slope of $r/c$. In fact, this is its defining feature: a curve for which the tangent makes a constant angle with a fixed line (center axis for our cylinder). The helix between two points $p_1=(z_1,\phi_1)$ and $p_2=(z_2,\phi_2)$ is given by
+    \[
+        \gamma(\phi) = \bigg (r \cos \phi, r \sin \phi, \frac{z_1-z_2}{\phi_1-\phi_2}\phi + \frac{\phi_1 z_2 - \phi_2 z_1}{\phi_1 - \phi_2} \bigg )
+    \]
+and its arc length $L$ can be calculated with $L = d \sqrt{r^2 + c^2}$.
+
+\begin{example}[No vertical separation between loops]
+    Since there is no separation between loops, $2\pi c = 0 \implies c= 0$, meaning that $z(\phi) = 0$ for all $\phi$, i.e., the $z$-coordinate does not change and thus the parametrisation is that of an arc of a circle of radius $r$. The arc length is naturally $L=dr$.
+\end{example}
+
+\begin{example}[Zero angle with central axis]
+    Since the angle is zero, we have that $\tan (0) = r/c = 0 \implies r=0$, meaning that $x(\phi) = y(\phi) = 0$ for all $\phi$, i.e., the parametrisation is that of a straight line, where the points only differ by their $z$-coordinates. The arc length is now $L=dc$.
+\end{example}
+
+\begin{example}[Existence of a shortest path and arbitrary long paths]
+    Between any two points on the cylinder that, w.l.o.g., only differ in their $z$-coordinate, there exist infinitely many geodesics. Furthermore, there is no upper bound for their length but there does exist at least one shortest one. By controlling the angle $\phi$ (or $c$), we control how many rotations we take around the cylinder. For $n \geq 0$ rotations we have by Pythagoras (by unfolding the cylinder $n$ times and excluding the top and bottom), that $\tan(\phi) = nr/c \iff \phi = \arctan (nr/c)$. The shortest path is now with zero rotations while there is no longest path as we can do as many rotations as we which: $n \to \infty \implies \phi \to \pi/2 \implies L \to \infty$.
+\end{example}
+
+For now, we have only discussed geodesics lying strictly on the curved side of the cylinder or on the flat top and bottom discs. What about when we go on two or more of them?
+
+\subsection{Side -> disc geodesics}
+
+Let $p_1$ be a point on the side and $p_2$ a point on one of the discs. Denote the point where the geodesic crosses the edge by $x$; we now have a picture where the side of the cylinder is unfolded and the disc is touching this at the point $x$. The point $x$ needs to be chosen such that the line $p_1 x p_2$ is straight (in the unfolded picture), i.e., we have
+    \[
+        d(p_1,p_2) = \min_x \big \{ d_{\text{cyl}}(p_1,x) + d_{\text{disc}}(x,p_2) \big \}.
+    \]
+Denote $p_1 = (z_1,\phi_1)$, $\angle \tilde{p}_1Ox = \alpha_1$, where $\tilde{p}_1$ is the point on the boundary of the disc corresponding to $p_1$ (same phase), and $p_2 = (r_2,\phi_2)$, $\angle p_2Ox = \alpha_2$, where $d_{\text{disc}}(O,p_2)=r_2$. Assume further that $\phi_2 > \phi_1$ (mod $2\pi$). We have
+    \[
+        d_{\text{cyl}}(p_1,x) = \sqrt{z_1^2 + r^2\alpha_1^2} \quad \text{and} \quad d_{\text{disc}}(x,p_2) = \sqrt{r^2 + r_2^2 - 2rr_2 \cos \alpha_2},
+    \]
+where the first is by Pythagoras (the non $z$-coordinate side of the triangle is simply the arc length $r\alpha_1$ of the circle) and the second by the cosine rule. Since $\alpha_2 = \phi_2 - \phi_1 - \alpha_1$, we get
+    \[
+        d(p_1,p_2) = \min_{\alpha_1} \bigg \{ \sqrt{z_1^2 + r^2\alpha_1^2} + \sqrt{r^2 + r_2^2 - 2rr_2 \cos (\phi_2 - \phi_1 - \alpha_1)} \bigg \}.
+    \]
+
+To calculate its minima, set $f(\alpha_1; p_1, p_2, r) = \sqrt{z_1^2 + r^2\alpha_1^2} + \sqrt{r^2 + r_2^2 - 2rr_2 \cos (\phi_2 - \phi_1 - \alpha_1)}$ and calculate its derivatives as
+    \[
+        D_{\alpha_1} f = \frac{r^2\alpha_1}{\sqrt{z_1^2 + r^2\alpha_1^2}} - \frac{rr_2 \sin(\phi_2 - \phi_1 - \alpha_1)}{\sqrt{r^2 + r_2^2 - 2rr_2 \cos (\phi_2 - \phi_1 - \alpha_1)}}
+    \]
+and
+    \[
+        D^2_{\alpha_1} f = \frac{r^2z_1^2}{(z_1^2 + r^2\alpha_1^2)^{3/2}}
+        + \frac{rr_2(r \cos (\phi_2 - \phi_1 - \alpha_1) - r_2)(r - r_2 \cos (\phi_2 - \phi_1 - \alpha_1))}{(r^2 + r_2^2 - 2rr_2 \cos (\phi_2 - \phi_1 - \alpha_1))^{3/2}}.
+    \]
+ 
+\subsection{Disc -> side -> disc geodesics}
+
+Without loss of generality, let $p_1$ be a point on the bottom disc and $p_2$ on the top disc. Denote the points where the geodesic crosses the edges by $x_1$ and $x_2$, respectively; we now have a picture where the cylinder side is unfolded and the discs are touching the side at the points $x_1$ and $x_2$. These points need to be chosen such that the line $p_1 x_1 x_2 p_2$ is straight (in the unfolded picture), i.e., we have
+    \[
+        d(p_1,p_2) = \min_{(x_1,x_2)} \big \{ d_{\text{disc}}(p_1,x_1) + d_{\text{cyl}}(x_1,x_2) + d_{\text{disc}}(x_2,p_2) \big \}.
+    \]
+Denote $p_i = (r_i,\phi_i)$, $\angle p_iOx_i = \alpha_i$, for $i = 1,2$, where $d_{\text{disc}}(O_i,p_i)=r_i$. Since the line $p_1 x_1 x_2 p_2$ is straight, we can define a rectangle $x_1\tilde{x}_1x_2\tilde{x}_2$ such that we have the correspondence of phases: $\phi_{\tilde{x}_1} = \phi_{x_2}$ and $\phi_{\tilde{x}_2} = \phi_{x_1}$, i.e., $\angle x_1O_1\tilde{x}_1 \coloneqq \tilde{\alpha}_1 = \tilde{\alpha}_2 \eqqcolon \angle x_2O_2\tilde{x}_2$. Assume further that $\phi_2 > \phi_1$ (mod $2\pi$). We have
+    \[
+        d_{\text{disc}}(p_1,x_1) = \sqrt{r^2 + r_1^2 - 2rr_1 \cos \alpha_1}, \enskip  d_{\text{cyl}}(x_1,x_2) = \sqrt{h^2 + (\tilde{\alpha}_1r)^2}, \enskip \text{and} \enskip d_{\text{disc}}(x_2,p_2) = \sqrt{r^2 + r_2^2 - 2rr_2 \cos \alpha_2},
+    \]
+where the middle is by Pythagoras (the non $z$-coordinate side of the triangle is simply the arc length $r\tilde{\alpha}_i$ of a circle and $h$ is the height of the cylinder) and the others by the cosine rule. We have
+    \[
+        \tilde{\alpha}_1 = \phi_{\tilde{x}_1} - \alpha_1 - \phi_1 \quad \text{and} \quad \tilde{\alpha}_2 = \phi_2 - \alpha_2 - \phi_{\tilde{x}_2} \implies \tilde{\alpha}_1 +\tilde{\alpha}_2 = \phi_{\tilde{x}_1} - \phi_{\tilde{x}_2} + \phi_2 - \phi_1 - \alpha_1 - \alpha_2,
+    \]
+and since $\phi_{\tilde{x}_2} = \phi_{x_1}$ with $\phi_{\tilde{x}_1} - \phi_{x_1} = \tilde{\alpha}_1$, we get
+    \[
+        \tilde{\alpha}_2 = \phi_2 - \phi_1 - \alpha_1 - \alpha_2.
+    \]
+Putting everything together gives us
+    \[
+        d(p_1,p_2) = \min_{(\alpha_1,\alpha_2)} \bigg \{ \sqrt{r^2 + r_1^2 - 2rr_1 \cos \alpha_1} + \sqrt{h^2 + ((\phi_2 - \phi_1 - \alpha_1 - \alpha_2)r)^2} + \sqrt{r^2 + r_2^2 - 2rr_2 \cos \alpha_2} \bigg \}.
+    \]
+Here it becomes clear that the previous disc -> side calculation is simply a special/modified case of this one; the first term is nonexistent, $\alpha_1=0$, and instead of $h$, we have a $z$-coordinate for the point on the side.
+
+Finally, let us compute some derivatives. Set
+    \[
+        f(\alpha_1, \alpha_2; p_1, p_2, r, h) = \sqrt{r^2 + r_1^2 - 2rr_1 \cos \alpha_1} + \sqrt{h^2 + ((\phi_2 - \phi_1 - \alpha_1 - \alpha_2)r)^2} + \sqrt{r^2 + r_2^2 - 2rr_2 \cos \alpha_2}.
+    \]
+
+    \[
+        D_{\alpha_i} f = \frac{rr_i \sin(\alpha_i)}{\sqrt{r^2 + r_i^2 - 2rr_i \cos \alpha_i}} - \frac{r^2(\phi_2 - \phi_1 - \alpha_1 - \alpha_2)}{\sqrt{h^2+r^2(\phi_2 - \phi_1 - \alpha_1 - \alpha_2)^2}}.
+    \]
+    
+    \[
+        D^2_{\alpha_1, \alpha_2} f = \frac{r^2h^2}{(h^2 + r^2(\phi_2 - \phi_1 - \alpha_1 - \alpha_2)^2)^{3/2}}.
+    \]
+
+    \[
+        D^2_{\alpha_i} f = \frac{rr_i(r \cos \alpha_i - r_i)(r - r_i \cos \alpha_i)}{(r^2 + r_i^2 - 2rr_i \cos \alpha_i)^{3/2}} + D^2_{\alpha_1, \alpha_2} f.
+    \]
+    
+\subsection{Side -> disc -> side geodesics}
+
+Do shortest paths ever cross a disc when both of the points are on the side of the cylinder? A simple drawing shows that the answer is yes: take two points opposite (same $z$-coordinate but phase differing by $\pi$) each other on a cylinder of radius $r$. Now their distance on the side is $r\pi$ while using the disc it is $2(r+h)$, where $h$ is the $z$-coordinate of the points. By controlling $h$ and $r$ we can thus order these lengths as we wish.
+
+It's clear that whether this happens or not depends on both the radius of the disc and the $z$-coordinates and phases of the points. Let us assume that this happens and calculate the distance. Let $p_1$ and $p_2$ be two points on the side of the cylinder and $x_1$ and $x_2$ be the points where the path crosses the sides of the disc, respectively. The length to minimise is thus
+    \[
+        d(p_1,p_2) = \min_{(x_1,x_2)} \{ d_{\text{cyl}}(p_1,x_1) + d_{\text{disc}}(x_1,x_2) + d_{\text{cyl}}(x_2,p_2) \}.
+    \]
+To determine whether we stay on the side or the take a shortcut through the disc, one simply compares this distance to the one strictly on the side.
+
+\begin{remark}
+    This problem is a somewhat generalisation of the first problem where we would've had $p_2=x_2$ without the assumption that the point lies on the boundary of the disc. However, here we will deal with chords, whereas there we most likely did not.
+\end{remark}
+
+Denote $p_i = (z_i,\phi_i)$ and $\angle \tilde{p}_iOx_i = \alpha_i$, for $i=1,2$, where $\tilde{p}_i$ is the point on the boundary of the disc corresponding to $p_i$ (same phase) and assume again that $\phi_2 > \phi_1$. We have
+    \[
+        \min_{(x_1,x_2)} \{ d_{\text{cyl}}(p_1,x_1) + d_{\text{disc}}(x_1,x_2) + d_{\text{cyl}}(x_2,p_2) \} = \min_{(\alpha_1,\alpha_2)} \bigg \{ \sqrt{z_1^2 + r^2\alpha_1^2} + 2r \cos \beta + \sqrt{z_2^2 + r^2\alpha_2^2} \bigg \},
+    \]
+where $\beta = 1/2(\alpha_1 + \alpha_2 + \phi_1 - \phi_2 + \pi)$ and $\phi_2 > \phi_1$. We could equivalently write $\cos \beta = \cos (1/2(\alpha_1 + \alpha_2 + \phi_1 - \phi_2 + \pi)) = -\sin (1/2(\alpha_1 + \alpha_2 + \phi_1 - \phi_2))$ and
+    \[
+        \min_{(x_1,x_2)} \{ d_{\text{cyl}}(p_1,x_1) + d_{\text{disc}}(x_1,x_2) + d_{\text{cyl}}(x_2,p_2) \} = \min_{(\alpha_1,\alpha_2)} \bigg \{ \sqrt{z_1^2 + r^2\alpha_1^2} - 2r \sin (1/2(\alpha_1 + \alpha_2 + \phi_1 - \phi_2)) + \sqrt{z_2^2 + r^2\alpha_2^2} \bigg \}.
+    \]
+
+Set $f(\alpha_1, \alpha_2; p_1, p_2, r) = \sqrt{z_1^2 + r^2\alpha_1^2} - 2r \sin (1/2(\alpha_1 + \alpha_2 + \phi_1 - \phi_2)) + \sqrt{z_2^2 + r^2\alpha_2^2}$ and calculate its first derivatives and Hessian as
+    \[
+        D_{\alpha_i} f = \frac{r^2\alpha_i}{\sqrt{z_i^2 + r^2 \alpha_i^2 }} - r\cos (\frac{1}{2}(\alpha_1 + \alpha_2 + \phi_1 - \phi_2))
+    \]
+and
+    \[
+        \text{Hess}(f) = 
+            \begin{bmatrix}
+                \frac{r^2 z_1^2}{(z_1^2+\alpha_1^2r^2)^{\frac{3}{2}}} + \frac{r}{2} \sin (\frac{1}{2}(\alpha_1 + \alpha_2 + \phi_1 - \phi_2)) & \frac{r}{2} \sin (\frac{1}{2}(\alpha_1 + \alpha_2 + \phi_1 - \phi_2))\\
+                \frac{r}{2} \sin (\frac{1}{2}(\alpha_1 + \alpha_2 + \phi_1 - \phi_2)) & \frac{r^2 z_2^2}{(z_2^2+\alpha_2^2r^2)^{\frac{3}{2}}} + \frac{r}{2} \sin (\frac{1}{2}(\alpha_1 + \alpha_2 + \phi_1 - \phi_2))
+            \end{bmatrix}.
+    \]
+
+\begin{example}
+Take opposite points on the side so that we have $\phi_2=\phi_1+\pi$ and $\alpha_1=\alpha=\alpha_2$ and thus
+    \[
+        \min_{(x_1,x_2)} \{ d_{\text{cyl}}(p_1,x_1) + d_{\text{disc}}(x_1,x_2) + d_{\text{cyl}}(x_2,p_2) \} = \min_{\alpha} \bigg \{ \sqrt{z_1^2 + r^2\alpha^2} + 2r \cos \alpha + \sqrt{z_2^2 + r^2\alpha^2} \bigg \}.
+    \]
+Differentiating this with respect to $\alpha$ and setting the derivative to zero gives us
+    \[
+        \frac{r^2\alpha}{\sqrt{z_1^2+\alpha^2r^2}} -2r \sin \alpha + \frac{r^2\alpha}{\sqrt{z_2^2+\alpha^2r^2}} = 0.
+    \]
+This holds, at least, when $\alpha = 0$. To see whether this is a maximum or a minimum, we take another derivative
+    \[
+        \frac{r^2 z_1^2}{(z_1^2+\alpha^2r^2)^{\frac{3}{2}}} - 2r \cos \alpha + \frac{r^2 z_2^2}{(z_2^2+\alpha^2r^2)^{\frac{3}{2}}}
+    \]
+and set $\alpha=0$ to get
+    \[
+        r(\frac{r(z_1 + z_2)}{z_1 z_2} - 2).
+    \]
+We thus have a maximum when $(z_1 + z_2)/(z_1 z_2) < 2/r$ and a minimum when $(z_1 + z_2)/(z_1 z_2) > 2/r$. Furthermore, if the heights are equal ($z_1=z=z_2$), then the minimum is only achieved when $z<r$.
+\end{example}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\end{document}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/jnsao.bst	Fri Mar 28 08:36:08 2025 -0500
@@ -0,0 +1,1146 @@
+%% jnsao.bst
+%% Copyright (c) Christian Clason and Tuomo Valkonen, 2019.
+%
+% BibTeX style corresponding to the LaTeX class for the
+%
+%    Journal of Nonsmooth Analysis and Optimization
+%
+% Web: http://jnsao.episciences.org
+% E-mail: jnsao@episciences.org
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) any later version.
+% The latest version of this license is in the file
+%
+%   http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "JNSAO journal template" (The work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Version 0.8 (2019-06-19).
+% Based on BibTeX standard bibliography style `abbrv'.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+ENTRY
+{ address
+    author
+    booktitle
+    chapter
+    edition
+    editor
+    howpublished
+    institution
+    journal
+    key
+    month
+    note
+    number
+    organization
+    pages
+    publisher
+    school
+    series
+    title
+    type
+    volume
+    year
+    doi          % only doi; https://dx.doi.org is added later
+    eprinttype   % repository: currently, arxiv or hal are supported
+    eprint       % eprint ID as in repository URL
+    version      % eprint version, appended as, e.g., `v1` to URL
+    url          % external URL if neither doi nor eprint is available
+    urldate      % date visited (for web pages etc.)
+    date         % futureproof: biblatex uses date over year
+    journaltitle % futureproof: biblatex uses journaltitle over journal
+}
+{}
+{ label }
+
+INTEGERS { output.state before.all mid.sentence after.sentence after.block }
+
+FUNCTION {init.state.consts}
+{ #0 'before.all :=
+    #1 'mid.sentence :=
+    #2 'after.sentence :=
+    #3 'after.block :=
+}
+
+STRINGS { s t }
+
+FUNCTION {output.nonnull}
+{ 's :=
+    output.state mid.sentence =
+    { ", " * write$ }
+    { output.state after.block =
+        { add.period$ write$
+            newline$
+            "\newblock " write$
+        }
+        { output.state before.all =
+            'write$
+            { add.period$ " " * write$ }
+            if$
+        }
+        if$
+        mid.sentence 'output.state :=
+    }
+    if$
+    s
+}
+
+FUNCTION {output}
+{ duplicate$ empty$
+    'pop$
+    'output.nonnull
+    if$
+}
+
+FUNCTION {output.check}
+{ 't :=
+    duplicate$ empty$
+    { pop$ "empty " t * " in " * cite$ * warning$ }
+    'output.nonnull
+    if$
+}
+
+FUNCTION {add.blank}
+{  " " * before.all 'output.state :=
+}
+
+FUNCTION {output.bibitem}
+{ newline$
+    "\bibitem{" write$
+    cite$ write$
+    "}" write$
+    newline$
+    ""
+    before.all 'output.state :=
+}
+
+FUNCTION {fin.entry}
+{ add.period$
+    write$
+    newline$
+}
+
+FUNCTION {new.block}
+{ output.state before.all =
+    'skip$
+    { after.block 'output.state := }
+    if$
+}
+
+FUNCTION {new.sentence}
+{ output.state after.block =
+    'skip$
+    { output.state before.all =
+        'skip$
+        { after.sentence 'output.state := }
+        if$
+    }
+    if$
+}
+
+FUNCTION {not}
+{   { #0 }
+    { #1 }
+    if$
+}
+
+FUNCTION {and}
+{   'skip$
+    { pop$ #0 }
+    if$
+}
+
+FUNCTION {or}
+{   { pop$ #1 }
+    'skip$
+    if$
+}
+
+FUNCTION {new.block.checka}
+{ empty$
+    'skip$
+    'new.block
+    if$
+}
+
+FUNCTION {new.block.checkb}
+{ empty$
+    swap$ empty$
+    and
+    'skip$
+    'new.block
+    if$
+}
+
+FUNCTION {new.sentence.checka}
+{ empty$
+    'skip$
+    'new.sentence
+    if$
+}
+
+FUNCTION {new.sentence.checkb}
+{ empty$
+    swap$ empty$
+    and
+    'skip$
+    'new.sentence
+    if$
+}
+
+FUNCTION {field.or.null}
+{ duplicate$ empty$
+    { pop$ "" }
+    'skip$
+    if$
+}
+
+FUNCTION {smallcaps}
+{ duplicate$ empty$
+    { pop$ "" }
+    { "\textsc{" swap$ * "}" * }
+    if$
+}
+
+FUNCTION {emphasize}
+{ duplicate$ empty$
+    { pop$ "" }
+    { "\emph{" swap$ * "}" * }
+    if$
+}
+
+INTEGERS { nameptr namesleft numnames }
+
+FUNCTION {format.names}
+{ 's :=
+    #1 'nameptr :=
+    s num.names$ 'numnames :=
+    numnames 'namesleft :=
+    { namesleft #0 > }
+    { s nameptr "{f{.\,}{.\nobreak\kern 0.33333em}}{vv~}{ll}{, jj}" format.name$ 't :=
+        nameptr #1 >
+        { namesleft #1 >
+            { ", " * t * }
+            { numnames #2 >
+                { "," * }
+                'skip$
+                if$
+                t "others" =
+                { " et~al." * }
+                { " and " * t * }
+                if$
+            }
+            if$
+        }
+        't
+        if$
+        nameptr #1 + 'nameptr :=
+        namesleft #1 - 'namesleft :=
+    }
+    while$
+}
+
+FUNCTION {format.authors}
+{ author empty$
+    { "" }
+    { author format.names }
+    if$
+}
+
+FUNCTION {format.editors}
+{ editor empty$
+    { "" }
+    { editor format.names
+        editor num.names$ #1 >
+        { " (eds.)" * }
+        { " (ed.)" * }
+        if$
+    }
+    if$
+}
+
+FUNCTION {format.title}
+{ title empty$
+    { "" }
+    { title}
+    if$
+}
+
+FUNCTION {n.dashify}
+{ 't :=
+    ""
+    { t empty$ not }
+    { t #1 #1 substring$ "-" =
+        { t #1 #2 substring$ "--" = not
+            { "--" *
+                t #2 global.max$ substring$ 't :=
+            }
+            {   { t #1 #1 substring$ "-" = }
+                { "-" *
+                    t #2 global.max$ substring$ 't :=
+                }
+                while$
+            }
+            if$
+        }
+        { t #1 #1 substring$ *
+            t #2 global.max$ substring$ 't :=
+        }
+        if$
+    }
+    while$
+}
+
+FUNCTION {year.or.date}
+{
+    year empty$
+    {date}
+    {year}
+    if$
+}
+
+FUNCTION {format.journal}
+{
+    journal empty$
+    {journaltitle}
+    {journal}
+    if$
+    emphasize
+}
+
+FUNCTION {format.date}
+{
+    ""
+    duplicate$ empty$
+    year.or.date duplicate$ empty$
+    { swap$ 'skip$
+        { "there's a month but no year in " cite$ * warning$ }
+        if$
+        *
+    }
+    { swap$ 'skip$
+        {
+            swap$
+            " " * swap$
+        }
+        if$
+        *
+    }
+    if$
+}
+
+FUNCTION {format.vol.year}
+{ volume field.or.null
+    " (" format.date * ")" * * 
+}
+
+
+FUNCTION {format.btitle}
+{ title emphasize
+}
+
+FUNCTION {tie.or.space.connect}
+{ duplicate$ text.length$ #3 <
+    { "~" }
+    { " " }
+    if$
+    swap$ * *
+}
+
+FUNCTION {either.or.check}
+{ empty$
+    'pop$
+    { "can't use both " swap$ * " fields in " * cite$ * warning$ }
+    if$
+}
+
+FUNCTION {format.bvolume}
+{ volume empty$
+    { "" }
+    { "volume" volume tie.or.space.connect
+        series empty$
+        'skip$
+        { " of " * series * }
+        if$
+        "volume and number" number either.or.check
+    }
+    if$
+}
+
+FUNCTION {format.number.series}
+{ volume empty$
+    { number empty$
+        { series field.or.null }
+        { output.state mid.sentence =
+            { "number" }
+            { "Number" }
+            if$
+            number tie.or.space.connect
+            series empty$
+            { "there's a number but no series in " cite$ * warning$ }
+            { " in " * series * }
+            if$
+        }
+        if$
+    }
+    { "" }
+    if$
+}
+
+FUNCTION {format.edition}
+{ edition empty$
+    { "" }
+    { output.state mid.sentence =
+        { edition "l" change.case$ " edition" * }
+        { edition "t" change.case$ " edition" * }
+        if$
+    }
+    if$
+}
+
+INTEGERS { multiresult }
+
+FUNCTION {multi.page.check}
+{ 't :=
+    #0 'multiresult :=
+    { multiresult not
+        t empty$ not
+        and
+    }
+    { t #1 #1 substring$
+        duplicate$ "-" =
+        swap$ duplicate$ "," =
+        swap$ "+" =
+        or or
+        { #1 'multiresult := }
+        { t #2 global.max$ substring$ 't := }
+        if$
+    }
+    while$
+    multiresult
+}
+
+FUNCTION {format.pages}
+{ pages empty$
+    { "" }
+    { pages multi.page.check
+        { "" pages n.dashify tie.or.space.connect }
+        { "" pages tie.or.space.connect }
+        if$
+    }
+    if$
+}
+
+FUNCTION {format.vol.num.pages}
+{ volume field.or.null
+    number empty$
+    'skip$
+    { "(" number * ")" * *
+        volume empty$
+        { "there's a number but no volume in " cite$ * warning$ }
+        'skip$
+        if$
+    }
+    if$
+    pages empty$
+    'skip$
+    { duplicate$ empty$
+        { pop$ format.pages }
+        { ":" * pages n.dashify * }
+        if$
+    }
+    if$
+}
+
+FUNCTION {format.chapter.pages}
+{ chapter empty$
+    'format.pages
+    { type empty$
+        { "chapter" }
+        { type "l" change.case$ }
+        if$
+        chapter tie.or.space.connect
+        pages empty$
+        'skip$
+        { ", " * format.pages * }
+        if$
+    }
+    if$
+}
+
+FUNCTION {format.in.ed.booktitle}
+{ booktitle empty$
+    { "" }
+    { editor empty$
+        { "in " booktitle emphasize * }
+        { "in " booktitle emphasize * ", " * format.editors * }
+        if$
+    }
+    if$
+}
+
+FUNCTION {empty.misc.check}
+{ author empty$ title empty$ howpublished empty$
+    month empty$ year empty$ note empty$
+    and and and and and
+    key empty$ not and
+    { "all relevant fields are empty in " cite$ * warning$ }
+    'skip$
+    if$
+}
+
+FUNCTION {format.thesis.type}
+{ type empty$
+    'skip$
+    { pop$
+        type "t" change.case$
+    }
+    if$
+}
+
+FUNCTION {format.tr.number}
+{ type empty$
+    { "Technical Report" }
+    'type
+    if$
+    number empty$
+    { "t" change.case$ }
+    { number tie.or.space.connect }
+    if$
+}
+
+FUNCTION {format.article.crossref}
+{ key empty$
+    { journal empty$
+        { "need key or journal for " cite$ * " to crossref " * crossref *
+            warning$
+            ""
+        }
+        { "in \emph{" journal * "\/}" * }
+        if$
+    }
+    { "in " key * }
+    if$
+    " \cite{" * crossref * "}" *
+}
+
+FUNCTION {format.crossref.editor}
+{ editor #1 "{vv~}{ll}" format.name$
+    editor num.names$ duplicate$
+    #2 >
+    { pop$ " et~al." * }
+    { #2 <
+        'skip$
+        { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
+            { " et~al." * }
+            { " and " * editor #2 "{vv~}{ll}" format.name$ * }
+            if$
+        }
+        if$
+    }
+    if$
+}
+
+FUNCTION {format.book.crossref}
+{ volume empty$
+    { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
+        "in "
+    }
+    { "Volume" volume tie.or.space.connect
+        " of " *
+    }
+    if$
+    editor empty$
+    editor field.or.null author field.or.null =
+    or
+    { key empty$
+        { series empty$
+            { "need editor, key, or series for " cite$ * " to crossref " *
+                crossref * warning$
+                "" *
+            }
+            { "\emph{" * series * "\/}" * }
+            if$
+        }
+        { key * }
+        if$
+    }
+    { format.crossref.editor * }
+    if$
+    " \cite{" * crossref * "}" *
+}
+
+FUNCTION {format.incoll.inproc.crossref}
+{ editor empty$
+    editor field.or.null author field.or.null =
+    or
+    { key empty$
+        { booktitle empty$
+            { "need editor, key, or booktitle for " cite$ * " to crossref " *
+                crossref * warning$
+                ""
+            }
+            { "in \emph{" booktitle * "\/}" * }
+            if$
+        }
+        { "in " key * }
+        if$
+    }
+    { "in " format.crossref.editor * }
+    if$
+    " \cite{" * crossref * "}" *
+}
+
+FUNCTION {eprint.version}
+{
+    eprint empty$
+    { "" }
+    { version empty$
+        { eprint }
+        { eprint "v" * version * }
+        if$
+    }
+    if$
+}
+
+FUNCTION {format.hal}
+{ eprint empty$
+    { "" }
+    { "\href{https://hal.archives-ouvertes.fr/" eprint.version * 
+        "}{\nolinkurl{hal-" * eprint.version "L" change.case$ * "}}" * 
+    }
+    if$
+}
+
+FUNCTION {format.arxiv}
+{ eprint empty$
+    { "" }
+    { "\href{https://arxiv.org/abs/" eprint.version * 
+        "}{\nolinkurl{arXiv:" * eprint.version * "}}" * 
+    }
+    if$
+}
+
+FUNCTION {format.eprint}
+{ eprinttype empty$
+    { "" }
+    { eprinttype "l" change.case$ "hal" =
+       { format.hal }
+       { format.arxiv }
+       if$
+    }
+    if$
+}
+
+FUNCTION {format.doi}
+{ doi empty$
+    { "" }
+    { "\href{https://dx.doi.org/" doi * "}{\nolinkurl{doi:" * doi "l" change.case$ * "}}" * }
+    if$
+}
+
+FUNCTION {format.url}
+{ url empty$
+    { "" }
+    { urldate empty$
+        { "\url{" url * "}" * }
+        { "\url{" url * "} (visited " * urldate * ")" * }
+        if$
+    }
+    if$
+}
+
+FUNCTION {article}
+{ output.bibitem
+    format.authors "author" output.check
+    format.title "title" output.check
+    format.journal "journal" output.check add.blank
+    format.vol.year output
+    format.pages output
+    format.doi output
+    format.eprint output
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {book}
+{ output.bibitem
+    author empty$
+    { format.editors "author and editor" output.check }
+    { format.authors output.nonnull
+        "author and editor" editor either.or.check 
+    }
+    if$
+    format.btitle "title" output.check
+    format.bvolume output
+    format.number.series output
+    publisher "publisher" output.check
+    address output
+    format.edition output
+    format.date output
+    format.doi output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {booklet}
+{ output.bibitem
+    format.authors output
+    format.title "title" output.check
+    howpublished address new.block.checkb
+    howpublished output
+    address output
+    format.date output
+    format.doi output
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {inbook}
+{ output.bibitem
+    author empty$
+    { format.editors "author and editor" output.check }
+    { format.authors output.nonnull
+        crossref missing$
+        { "author and editor" editor either.or.check }
+        'skip$
+        if$
+    }
+    if$
+    format.title "title" output.check
+    crossref missing$
+    { format.in.ed.booktitle "booktitle" output.check
+        format.bvolume output
+        format.number.series output
+        publisher "publisher" output.check
+        address output
+    }
+    { format.book.crossref output.nonnull }
+    if$
+    format.edition output
+    format.date "year" output.check
+    format.chapter.pages "chapter and pages" output.check
+    format.doi output
+    format.eprint output
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {incollection}
+{ output.bibitem
+    format.authors "author" output.check
+    format.title "title" output.check
+    crossref missing$
+    { format.in.ed.booktitle "booktitle" output.check
+        format.bvolume output
+        format.number.series output
+        publisher "publisher" output.check
+        address output
+        format.edition output
+        format.date "year" output.check
+    }
+    { format.incoll.inproc.crossref output.nonnull
+        format.chapter.pages output
+    }
+    if$
+    format.chapter.pages output
+    format.doi output
+    format.eprint output
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {proceedings}
+{ output.bibitem
+    editor empty$
+    { organization output }
+    { format.editors output.nonnull }
+    if$
+    format.btitle "title" output.check
+    format.bvolume output
+    format.number.series output
+    address empty$
+    { editor empty$
+        'skip$
+        { organization output }
+        if$
+        publisher output
+        format.date "year" output.check
+    }
+    { address output.nonnull
+        format.date "year" output.check
+        editor empty$
+        'skip$
+        { organization output }
+        if$
+        publisher output
+    }
+    if$
+    format.doi output
+    format.eprint output
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {inproceedings}
+{ output.bibitem
+    format.authors "author" output.check
+    format.title "title" output.check
+    crossref missing$
+    { format.in.ed.booktitle "booktitle" output.check
+        format.bvolume output
+        format.number.series output
+        publisher "publisher" output.check
+        address output
+        format.edition output
+        format.date output
+    }
+    { format.incoll.inproc.crossref output.nonnull }
+    if$
+    format.pages output
+    format.doi output
+    format.eprint output
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {conference} { inproceedings }
+
+FUNCTION {manual}
+{ output.bibitem
+    author empty$
+    { organization empty$
+        'skip$
+        { organization output.nonnull }
+        if$
+    }
+    { format.authors output.nonnull }
+    if$
+    format.btitle "title" output.check
+    author empty$
+        'skip$
+        { organization output }
+    if$
+    address output
+    format.edition output
+    format.date output
+    format.doi output
+    format.eprint output
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {mastersthesis}
+{ output.bibitem
+    format.authors "author" output.check
+    format.btitle "title" output.check
+    "Master's thesis" format.thesis.type output.nonnull
+    school "school" output.check
+    address output
+    format.date "year" output.check
+    format.doi output
+    format.eprint output
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {phdthesis}
+{ output.bibitem
+    format.authors "author" output.check
+    format.btitle "title" output.check
+    "PhD thesis" format.thesis.type output.nonnull
+    school "school" output.check
+    address output
+    format.date "year" output.check
+    format.doi output
+    format.eprint output
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {techreport}
+{ output.bibitem
+    format.authors "author" output.check
+    format.title "title" output.check
+    format.tr.number output.nonnull
+    institution "institution" output.check
+    address output
+    format.date "year" output.check
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {unpublished}
+{ output.bibitem
+    format.authors "author" output.check
+    format.title "title" output.check add.blank
+    format.vol.year output
+    format.eprint output
+    format.url output
+    new.block
+    note output
+    fin.entry
+}
+
+FUNCTION {misc}
+{ output.bibitem
+    format.authors output
+    format.title output
+    howpublished output
+    format.date output
+    format.doi output
+    format.eprint output
+    format.url output
+    new.block
+    note output
+    fin.entry
+    empty.misc.check
+}
+
+FUNCTION {default.type} { misc }
+
+MACRO {jan} {"Jan."}
+
+MACRO {feb} {"Feb."}
+
+MACRO {mar} {"Mar."}
+
+MACRO {apr} {"Apr."}
+
+MACRO {may} {"May"}
+
+MACRO {jun} {"June"}
+
+MACRO {jul} {"July"}
+
+MACRO {aug} {"Aug."}
+
+MACRO {sep} {"Sept."}
+
+MACRO {oct} {"Oct."}
+
+MACRO {nov} {"Nov."}
+
+MACRO {dec} {"Dec."}
+
+READ
+
+FUNCTION {sortify}
+{ purify$
+    "l" change.case$
+}
+
+INTEGERS { len }
+
+FUNCTION {chop.word}
+{ 's :=
+    'len :=
+    s #1 len substring$ =
+    { s len #1 + global.max$ substring$ }
+    's
+    if$
+}
+
+FUNCTION {sort.format.names}
+{ 's :=
+    #1 'nameptr :=
+    ""
+    s num.names$ 'numnames :=
+    numnames 'namesleft :=
+    { namesleft #0 > }
+    { nameptr #1 >
+        { "   " * }
+        'skip$
+        if$
+        s nameptr "{vv{ } }{ll{ }}{  f{ }}{  jj{ }}" format.name$ 't :=
+        nameptr numnames = t "others" = and
+        { "et al" * }
+        { t sortify * }
+        if$
+        nameptr #1 + 'nameptr :=
+        namesleft #1 - 'namesleft :=
+    }
+    while$
+}
+
+FUNCTION {sort.format.title}
+{ 't :=
+    "A " #2
+    "An " #3
+    "The " #4 t chop.word
+    chop.word
+    chop.word
+    sortify
+    #1 global.max$ substring$
+}
+
+FUNCTION {author.sort}
+{ author empty$
+    { key empty$
+        { "to sort, need author or key in " cite$ * warning$
+            ""
+        }
+        { key sortify }
+        if$
+    }
+    { author sort.format.names }
+    if$
+}
+
+FUNCTION {author.editor.sort}
+{ author empty$
+    { editor empty$
+        { key empty$
+            { "to sort, need author, editor, or key in " cite$ * warning$
+                ""
+            }
+            { key sortify }
+            if$
+        }
+        { editor sort.format.names }
+        if$
+    }
+    { author sort.format.names }
+    if$
+}
+
+FUNCTION {author.organization.sort}
+{ author empty$
+    { organization empty$
+        { key empty$
+            { "to sort, need author, organization, or key in " cite$ * warning$
+                ""
+            }
+            { key sortify }
+            if$
+        }
+        { "The " #4 organization chop.word sortify }
+        if$
+    }
+    { author sort.format.names }
+    if$
+}
+
+FUNCTION {editor.organization.sort}
+{ editor empty$
+    { organization empty$
+        { key empty$
+            { "to sort, need editor, organization, or key in " cite$ * warning$
+                ""
+            }
+            { key sortify }
+            if$
+        }
+        { "The " #4 organization chop.word sortify }
+        if$
+    }
+    { editor sort.format.names }
+    if$
+}
+
+FUNCTION {presort}
+{ type$ "book" =
+    type$ "inbook" =
+    or
+    'author.editor.sort
+    { type$ "proceedings" =
+        'editor.organization.sort
+        { type$ "manual" =
+            'author.organization.sort
+            'author.sort
+            if$
+        }
+        if$
+    }
+    if$
+    "    "
+    *
+    year field.or.null sortify
+    *
+    "    "
+    *
+    title field.or.null
+    sort.format.title
+    *
+    #1 entry.max$ substring$
+    'sort.key$ :=
+}
+
+ITERATE {presort}
+
+SORT
+
+STRINGS { longest.label }
+
+INTEGERS { number.label longest.label.width }
+
+FUNCTION {initialize.longest.label}
+{ "" 'longest.label :=
+    #1 'number.label :=
+    #0 'longest.label.width :=
+}
+
+FUNCTION {longest.label.pass}
+{ number.label int.to.str$ 'label :=
+    number.label #1 + 'number.label :=
+    label width$ longest.label.width >
+    { label 'longest.label :=
+        label width$ 'longest.label.width :=
+    }
+    'skip$
+    if$
+}
+
+EXECUTE {initialize.longest.label}
+
+ITERATE {longest.label.pass}
+
+FUNCTION {begin.bib}
+{ preamble$ empty$
+    'skip$
+    { preamble$ write$ newline$ }
+    if$
+    "\begin{thebibliography}{"  longest.label  * "}" * write$ newline$
+}
+
+EXECUTE {begin.bib}
+
+EXECUTE {init.state.consts}
+
+ITERATE {call.type$}
+
+FUNCTION {end.bib}
+{ newline$
+    "\end{thebibliography}" write$ newline$
+}
+
+EXECUTE {end.bib}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/jnsao.cls	Fri Mar 28 08:36:08 2025 -0500
@@ -0,0 +1,608 @@
+%% jnsao.cls
+%% Copyright (c) Christian Clason and Tuomo Valkonen, 2019-2025.
+%
+% LaTeX class file for articles in the
+%
+%    Journal of Nonsmooth Analysis and Optimization
+%
+% Web: http://jnsao.episciences.org
+% E-mail: jnsao@episciences.org
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) any later version.
+% The latest version of this license is in the file
+%
+%   http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "JNSAO journal template" (The work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{jnsao}[2025/01/28 v0.12 JNSAO article]
+
+\ProcessOptions\relax
+
+\LoadClass[
+    a4paper,
+    fontsize=11pt,
+    oneside
+]{scrartcl}
+\KOMAoptions{DIV=12}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Define colors
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\RequirePackage[svgnames]{xcolor}
+\definecolor{hrefcolor}{rgb}{0.0,0.4,0.7}
+\definecolor{citecolor}{rgb}{0.0,0.35,0.2}
+\definecolor{structure}{rgb}{0.09,0.09,0.44}
+\definecolor{halfgray}{gray}{0.55}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Load amsmath, amsthm, thmtools, mathtools, hyperref (in this order!)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\RequirePackage[leqno,tbtags]{amsmath} % This *must* be *before* cleveref!
+\RequirePackage{amsthm}
+\RequirePackage{thmtools}
+\RequirePackage[centercolon]{mathtools}
+\numberwithin{equation}{section} % This *must* be *before* cleveref!
+
+\RequirePackage[
+    colorlinks=true,
+    linkcolor=citecolor,
+    citecolor=citecolor,
+    filecolor=hrefcolor,
+    urlcolor=hrefcolor,
+    pdfencoding=auto,
+    hypertexnames=false,
+]{hyperref}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Load and set up fonts
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\RequirePackage[T1]{fontenc}
+\RequirePackage[proportional]{libertine}
+\RequirePackage[libertine,liby,vvarbb]{newtxmath}
+\RequirePackage[scaled=0.95,varqu,varl]{inconsolata}
+\useosf
+\frenchspacing
+\RequirePackage[kerning,spacing]{microtype}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Format: title, sectioning in colored sans smallcaps
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\renewcommand*{\sectfont}{\color{structure}\sffamily}
+\setkomafont{title}{\color{structure}\normalfont\sffamily\scshape}
+\setkomafont{author}{\large\normalfont\sffamily}
+\setkomafont{date}{\large\normalfont\sffamily}
+\addtokomafont{section}{\scshape}
+\addtokomafont{subsection}{\scshape}
+\addtokomafont{subsubsection}{\scshape\itshape}
+%\addtokomafont{footnote}{\sffamily}
+
+% title in small caps (requires lowercasing, label abstract
+\RequirePackage[overload]{textcase}
+
+% Prefix appendices with "Appendix"
+\newcommand{\jnsao@appname}{\relax}
+\newcommand*{\appendixmore}{%
+    \renewcommand{\jnsao@appname}{Appendix~}
+    \renewcommand{\thesection}{{\scshape\alph{section}}}
+}
+
+% section headers in small caps (requires lowercasing)
+\renewcommand*\sectionformat{\MakeLowercase{\jnsao@appname\thesection}\enskip}
+\renewcommand*\subsectionformat{\MakeLowercase{\jnsao@appname\thesubsection}\enskip}
+\renewcommand*\subsectionformat{\MakeLowercase{\jnsao@appname\thesubsection}\enskip}
+\renewcommand*\subsubsectionformat{\upshape\MakeLowercase{\jnsao@appname\thesubsubsection}\enskip}
+
+\let\jnsao@old@section\section
+\renewcommand*{\section}{%
+    \@ifstar {\star@section}{\@dblarg\nonstar@section}%
+}
+\newcommand*{\star@section}[1]{%
+    \jnsao@old@section*{\MakeLowercase{#1}}%
+}
+\newcommand*{\nonstar@section}[2][]{%
+    \jnsao@old@section[{#1}]{\MakeLowercase{#2}}%
+}
+\let\jnsao@old@subsection\subsection
+\renewcommand*{\subsection}{%
+    \@ifstar {\star@subsection}{\@dblarg\nonstar@subsection}%
+}
+\newcommand*{\star@subsection}[1]{%
+    \jnsao@old@subsection*{\MakeLowercase{#1}}%
+}
+\newcommand*{\nonstar@subsection}[2][]{%
+    \jnsao@old@subsection[{#1}]{\MakeLowercase{#2}}%
+}
+\let\jnsao@old@subsubsection\subsubsection
+\renewcommand*{\subsubsection}{%
+    \@ifstar {\star@subsubsection}{\@dblarg\nonstar@subsubsection}%
+}
+\newcommand*{\star@subsubsection}[1]{%
+    \jnsao@old@subsubsection*{\MakeLowercase{#1}}%
+}
+\newcommand*{\nonstar@subsubsection}[2][]{%
+    \jnsao@old@subsubsection[{#1}]{\MakeLowercase{#2}}%
+}
+
+% Format (sub) figure labels
+\RequirePackage[labelfont={color=structure,sf}]{caption}
+\RequirePackage[labelfont={color=structure,sf}]{subcaption}
+
+% Url
+\renewcommand{\UrlFont}{\normalfont\sffamily}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Format of theorem-like environments.
+% These used to have to be *after* the loading of cleveref, but no longer
+% (2018-12-15) seems to be the case.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def\jnsao@thmformat{\NAME~{\scshape{\NUMBER}}\NOTE}
+
+\declaretheoremstyle[
+    headfont={\upshape\sffamily\color{structure}},
+    headformat=\jnsao@thmformat,
+    bodyfont={\normalfont\itshape},
+]{plain}
+
+\declaretheoremstyle[
+    headfont={\upshape\sffamily\color{structure}},
+    headformat=\jnsao@thmformat,
+    bodyfont={\normalfont\upshape},
+]{definition}
+
+\declaretheoremstyle[
+    headfont={\upshape\sffamily\color{structure}},
+    headformat=\jnsao@thmformat,
+    bodyfont={\normalfont\upshape},
+]{remark}
+
+% Define basic theorem-like environments
+\theoremstyle{plain}
+\newtheorem{theorem}{Theorem}[section]
+\newtheorem{proposition}[theorem]{Proposition}
+\newtheorem{corollary}[theorem]{Corollary}
+\newtheorem{lemma}[theorem]{Lemma}
+
+\theoremstyle{remark}
+\newtheorem{remark}[theorem]{Remark}
+
+\theoremstyle{definition}
+\newtheorem{definition}[theorem]{Definition}
+\newtheorem{example}[theorem]{Example}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Footnotes: separation, special format for \thanks
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Store length in base font size
+\newlength{\jnsao@footnotesep}
+\newlength{\jnsao@footnotetopsep}
+\newlength{\jnsao@standardfootins}
+\setlength{\jnsao@footnotesep}{0.5\baselineskip}
+\setlength{\jnsao@footnotetopsep}{\jnsao@footnotesep}
+\setlength{\jnsao@standardfootins}{\jnsao@footnotesep+\baselineskip}
+\setlength{\footnotesep}{\baselineskip}
+
+% Footnote rule for other pages than the first page
+\def\jnsao@footnoterule{\relax%
+    \vskip-\jnsao@footnotesep%
+    {\color{gray}\hrule\@width 1cm}%
+    \vskip\jnsao@footnotetopsep%
+    }%
+
+% Footnote rule for the first page
+\def\jnsao@footnoterule@firstpage{\relax%
+    \jnsao@headfootrule%
+    %\vskip 2pt
+    }
+
+% Change font for \thanks
+\def\thanks#1{\footnotemark
+    \protected@xdef\@thanks{\@thanks
+        \protect\jnsao@thankstext[\the\c@footnote]{\sffamily #1}}%
+}
+\def\jnsao@thankstext{\sffamily%
+     \@ifnextchar [\@xfootnotenext
+       {\protected@xdef\@thefnmark{\thempfn}%
+    \@footnotetext}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Vertical alignment. This hacks and wraps \@outputpage and
+% and latex.ltx limitations to have different geometry for
+% the first page
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Flush to bottom
+\flushbottom
+
+% Various lengths
+\newlength{\jnsao@fullheight}
+\newlength{\jnsao@headsep}
+\newlength{\jnsao@firstpagehead}
+\newlength{\jnsao@firstpageheadplus}
+\newlength{\jnsao@headheight}
+\newlength{\jnsao@headlineheight}
+
+% Maximum available space for text, header, and footer
+\setlength{\jnsao@fullheight}{\textheight+\footskip+\headheight+\headsep}
+% Space between header and text
+\setlength{\jnsao@headsep}{\baselineskip}
+% Height of text lines in header/footer font
+\setlength{\jnsao@headlineheight}{11pt}
+% First page header height
+\setlength{\jnsao@firstpagehead}{2\jnsao@headlineheight}
+% ... plus extra for rule and separation
+\setlength{\jnsao@firstpageheadplus}{\jnsao@firstpagehead+2.4pt}
+% Other pages header (and footer) height plus extra for rule and separation
+\setlength{\jnsao@headheight}{\jnsao@headlineheight+2.4pt}
+
+% Recalculate header, footer, and text area heights from:
+% #1: header material height
+% #2: header separator white space
+% #3: footer material height
+% #4: footer separator white space
+\def\jnsao@setheadfoot#1#2#3#4{%
+    \global\headheight=#1%
+    \global\headsep=#2%
+    \global\footskip=#3%
+    \global\advance\footskip by #4%
+    \global\footheight=#3% KOMA-script seems to blow up things without this
+    \global\textheight=\jnsao@fullheight%
+    \global\advance\textheight by -\footskip%
+    \global\advance\textheight by -\headheight%
+    \global\advance\textheight by -\headsep%
+}
+
+% First page settings
+\setlength{\skip\footins}{\jnsao@footnotesep+0.5\splittopskip}
+\let\footnoterule\jnsao@footnoterule@firstpage
+\jnsao@setheadfoot{\jnsao@firstpageheadplus}{\jnsao@headsep}{0em}{0em}
+
+% Other pages' settings
+\def\jnsao@geometry@otherpages{%
+    % Set up geometry of following pages
+    \global\skip\footins=\jnsao@standardfootins
+    \global\let\footnoterule\jnsao@footnoterule
+    \jnsao@setheadfoot{\jnsao@headheight}{\jnsao@headsep}{\jnsao@headheight}{\jnsao@headsep}
+}
+
+% \@outputpage hack to reset settings after first page
+\let\jnsao@old@outputpage\@outputpage
+\def\jnsao@output@firstpage{
+    \jnsao@old@outputpage%
+    \jnsao@geometry@otherpages%
+    % This is needed for something to actually happen after the reset above,
+    % as standard \@outputpage does the same thing at the end
+    \global\@colht\textheight%
+    % Reset page output routine
+    \global\let\jnsao@output@page\jnsao@old@outputpage%
+}
+
+\def\@outputpage{\jnsao@output@page}
+\let\jnsao@output@page\jnsao@output@firstpage
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Date
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\RequirePackage{scrdate}
+\date{\ISOToday}
+
+% Over-ride \today with \ISOdate when we insert it. This is needed because Babel
+% reset \date{\ISOToday} into a locale format. 
+\def\jnsao@insertdate{{\let\today\ISOToday\@date}}
+%\def\date#1{\gdef\@date{\let\today\ISOToday#1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Publication information
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\let\jnsao@submitted\empty
+\let\jnsao@accepted\empty
+\let\jnsao@journal\empty
+\let\jnsao@volume\empty
+\let\jnsao@number\empty
+\let\jnsao@year\empty
+\let\jnsao@doi\empty
+\let\jnsao@eprinttype\empty
+\let\jnsao@eprint\empty
+\let\jnsao@shortauthor\empty
+\let\jnsao@shorttitle\empty
+\let\jnsao@ack\empty
+\def\jnsao@journal{Journal of Nonsmooth Analysis and Optimization}
+\def\jnsao@journalabbrev{J.~Nonsmooth Anal.~Optim.}
+\def\jnsao@license{CC-BY-SA 4.0}
+\def\jnsao@copyright{{\copyright} the authors}
+\def\jnsao@status{Manuscript}
+
+\newcommand{\manuscriptsubmitted}[1]{\gdef\jnsao@submitted{#1}}
+\newcommand{\manuscriptaccepted}[1]{\gdef\jnsao@accepted{#1}}
+\newcommand{\manuscriptvolume}[1]{\gdef\jnsao@volume{#1}}
+\newcommand{\manuscriptnumber}[1]{\gdef\jnsao@number{#1}}
+\newcommand{\manuscriptjournal}[1]{\gdef\jnsao@journal{#1}}
+\newcommand{\manuscriptlicense}[1]{\gdef\jnsao@license{#1}}
+\newcommand{\manuscriptcopyright}[1]{\gdef\jnsao@copyright{#1}}
+\newcommand{\manuscriptyear}[1]{\gdef\jnsao@year{#1}}
+\newcommand{\manuscriptdoi}[1]{\gdef\jnsao@doi{#1}}
+\newcommand{\manuscripteprinttype}[1]{\gdef\jnsao@eprinttype{#1}}
+\newcommand{\manuscripteprint}[1]{\gdef\jnsao@eprint{#1}}
+\newcommand{\manuscriptstatus}[1]{\gdef\jnsao@status{#1}}
+\newcommand{\shortauthor}[1]{\gdef\jnsao@shortauthor{#1}}
+\newcommand{\shorttitle}[1]{\gdef\jnsao@shorttitle{#1}}
+\newcommand{\acknowledgements}[1]{\gdef\jnsao@ack{#1}}
+\newcommand{\acknowledgments}[1]{\gdef\jnsao@ack{#1}}
+
+\def\jnsao@licenseurl#1#2{%
+    \expandafter\def\csname jnsao@licenseurl@#1 \endcsname{#2}%
+}
+
+\RequirePackage{xstring}
+\def\jnsao@printeprint{%
+    % lowercase is not expandable, so we have to be tricky (https://tex.stackexchange.com/a/87130)
+    \lowercase\expandafter{\expandafter\def\expandafter\@tempe\expandafter{\jnsao@eprinttype}}%
+    \IfStrEqCase{\@tempe}{%
+        {arxiv}{\arxiv{\jnsao@eprint}}%
+        {hal}{\hal{\jnsao@eprint}}%
+    }[{\sffamily \textsc{\MakeLowercase{\jnsao@eprinttype:}}\,\jnsao@eprint}]%
+}
+\jnsao@licenseurl{CC-BY}{https://creativecommons.org/licenses/by/4.0/}
+\jnsao@licenseurl{CC-BY 4.0}{https://creativecommons.org/licenses/by/4.0/}
+\jnsao@licenseurl{CC-BY-SA}{https://creativecommons.org/licenses/by-sa/4.0/}
+\jnsao@licenseurl{CC-BY-SA 4.0}{https://creativecommons.org/licenses/by-sa/4.0/}
+\jnsao@licenseurl{CC-BY-NC-SA}{https://creativecommons.org/licenses/by-nc-sa/4.0/}
+\jnsao@licenseurl{CC-BY-NC-SA 4.0}{https://creativecommons.org/licenses/by-nc-sa/4.0/}
+\jnsao@licenseurl{CC-BY-NC}{https://creativecommons.org/licenses/by-nc/4.0/}
+\jnsao@licenseurl{CC-BY-NC 4.0}{https://creativecommons.org/licenses/by-nc/4.0/}
+\jnsao@licenseurl{CC-BY-NC-ND}{https://creativecommons.org/licenses/by-nc-nd/4.0/}
+\jnsao@licenseurl{CC-BY-NC-ND 4.0}{https://creativecommons.org/licenses/by-nc-nd/4.0/}
+
+\def\jnsao@linklicense#1{%
+    \ifcsname jnsao@licenseurl@#1 \endcsname%
+        \expandafter\let\expandafter\@tempa\csname jnsao@licenseurl@#1 \endcsname%
+        \href{\@tempa}{\scshape \MakeLowercase{#1}}%
+    \else%
+        #1%
+    \fi
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Headers and footers
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\RequirePackage{lastpage}
+\RequirePackage[fit]{truncate}
+
+\addtokomafont{pageheadfoot}{\normalfont\sffamily\footnotesize}
+
+\def\jnsao@headfootrule{\hrule width \textwidth height 0.4pt}
+\def\jnsao@ruledhead#1{\vbox to \headheight{\usekomafont{pageheadfoot}\hbox to \textwidth{#1}\vskip 2pt\jnsao@headfootrule\vfill}}
+\def\jnsao@ruledfoot#1{\vbox to \footheight{\usekomafont{pageheadfoot}\vfill\jnsao@headfootrule\vskip 2pt\hbox to \textwidth{#1}}}
+
+\def\ps@jnsao{%
+    \def\@oddhead{\jnsao@ruledhead{%
+        \ifx\jnsao@accepted\empty{%
+            \ifx\jnsao@eprint\empty{%
+            \jnsao@status, \jnsao@insertdate%
+        }\else{%
+            \jnsao@printeprint, \jnsao@insertdate%
+        }\fi%
+        }\else{%
+            \jnsao@journalabbrev%
+            \ifx\jnsao@volume\empty{\relax}\else{ \jnsao@volume}\fi%
+            \ifx\jnsao@year\empty{\relax}\else{ (\jnsao@year)}\fi%
+            \ifx\jnsao@number\empty{\relax}\else{, \jnsao@number}\fi%
+        }\fi%
+        \hfill%
+        page~\thepage~of~\pageref*{LastPage}%
+    }}
+    \def\@oddfoot{\jnsao@ruledfoot{%
+        \truncate{0.5\textwidth}{\ifx\jnsao@shortauthor\empty{}\else{\jnsao@shortauthor}\fi}%
+        \hfill%
+        \truncate{0.5\textwidth}{\ifx\jnsao@shorttitle\empty{\@title}\else{\jnsao@shorttitle}\fi}%
+    }}
+}
+
+\pagestyle{jnsao}
+
+\def\ps@jnsaotitlepage{%
+    \def\@oddhead{\jnsao@ruledhead{%
+        \parbox[b][\jnsao@firstpagehead][t]{0.75\textwidth}{%
+            \ifx\jnsao@accepted\empty{%
+            \ifx\jnsao@eprint\empty{%
+                \jnsao@status\\
+                date: \jnsao@insertdate \\
+            }\else{%
+                \jnsao@printeprint\\
+                date: \jnsao@insertdate \\
+            }\fi%
+            }\else{%
+                \jnsao@journalabbrev%
+                \ifx\jnsao@volume\empty{\relax}\else{ \jnsao@volume}\fi%
+                \ifx\jnsao@year\empty{\relax}\else{ (\jnsao@year)}\fi%
+                \ifx\jnsao@number\empty{\relax}\else{, \jnsao@number}\fi%
+                \ifx\jnsao@doi\empty{\relax}\else{, \expandafter\doi\expandafter{\jnsao@doi}}\fi%
+                \\%
+                \ifx\jnsao@date\empty{%
+                     \ifx\jnsao@accepted\empty{\relax}\else{Accepted: \jnsao@accepted}\fi%
+                }\else{%
+                    Submitted: \jnsao@submitted\ifx\jnsao@accepted\empty{}\else, accepted: \jnsao@accepted\fi%
+                }\fi%
+                \\
+            }\fi%
+        }%
+        \hfill%
+        \parbox[b][\jnsao@firstpagehead][t]{0.25\textwidth}{%
+            \hfill page~1~of~\pageref*{LastPage}\\%
+            \null\hfill\jnsao@copyright
+            \ifx\jnsao@license\empty{\relax}
+            \else{, \jnsao@linklicense{\jnsao@license}}
+            \fi
+        }%
+    }}
+    \def\@oddfoot{}
+}
+
+\renewcommand{\titlepagestyle}{jnsaotitlepage}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Abstract and article title
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% \maketitle customisations:
+% - Locally convert \@title to lower case for ``all small caps'' to work right
+% - Reset \@date to stop babel from messing things up with its silly enforced
+%   date formats.
+% - Include acknowledgements before \thanks footnotes
+% This version \@maketitle is simply based on scrartcl.cls with unsupported
+% features removed.
+
+\def\jnsao@insert@ack{\insert\footins{%
+    \reset@font\footnotesize%
+    \interlinepenalty\interfootnotelinepenalty%
+    \splittopskip\footnotesep%
+    \splitmaxdepth \dp\strutbox \floatingpenalty \@MM%
+    \hsize\columnwidth \@parboxrestore%
+    \color@begingroup%
+    \hb@xt@1.8em{\rule\z@\footnotesep\ignorespaces\parbox[t]{\textwidth}{\jnsao@ack}\@finalstrut\strutbox}%
+    \color@endgroup}}
+
+\renewcommand*{\@maketitle}{%
+  \global\@topnum=\z@
+  \setparsizes{\z@}{\z@}{\z@\@plus 1fil}\par@updaterelative
+  \null
+  \vskip 2em%
+  \if\jnsao@ack\empty\else\jnsao@insert@ack\fi%
+  \begin{center}%
+    {\usekomafont{title}{\huge \MakeLowercase{\@title} \par}}%
+    \vskip .5em
+    {\ifx\@subtitle\@empty\else\usekomafont{subtitle}\@subtitle\par\fi}%
+    \vskip 1em
+    {%
+      \usekomafont{author}{%
+        \lineskip .5em%
+        \begin{tabular}[t]{c}
+          \@author
+        \end{tabular}\par
+      }%
+    }%
+    \vskip \z@ \@plus 2em
+    \ifx\@dedication\@empty \else
+      \vskip 2em
+      {\usekomafont{dedication}{\@dedication \par}}%
+    \fi
+  \end{center}%
+  \par
+  \vskip 2em
+}%
+
+% Set up abstract formatting
+\renewenvironment{abstract}{%
+    \vspace*{-0.75cm}
+    \small%
+    \quotation%
+    \noindent%
+    {\normalfont\sectfont\nobreak\abstractname\quad}%
+    }{%
+    \endquotation%
+    \vskip 0.7cm
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Possibly missing commands
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\providecommand{\arxiv}[1]{\mbox{\scshape\sffamily arxiv:}\,\href{https://arxiv.org/abs/#1}{#1}}
+\providecommand{\hal}[1]{\href{https://hal.archives-ouvertes.fr/#1}{#1}}
+\providecommand{\doi}[1]{\mbox{\scshape\sffamily doi:}\,\href{https://dx.doi.org/#1}{\detokenize{#1}}}
+\providecommand{\orcid}[1]{\mbox{\scshape\sffamily orcid:}\,\href{https://orcid.org/#1}{\detokenize{#1}}}
+\def\email#1{\href{mailto:#1}{\sffamily#1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Potential additional customizations
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \RequirePackage{mdframed}
+%
+% \mdfdefinestyle{examplebg}{
+%     backgroundcolor=structure!7,%
+%     hidealllines=true,%
+%     innertopmargin=-.3em,%
+%     innerbottommargin=.7em,%
+%     innerleftmargin=.7em,%
+%     innerrightmargin=.7em,%
+% }
+%
+% \surroundwithmdframed[style=examplebg]{example}
+% \surroundwithmdframed[style=examplebg]{algorithm}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Adaptations of optional packages on startup.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\PassOptionsToPackage{nameinlink,capitalise}{cleveref}
+\AfterPackage{cleveref}{%
+    % cleveref: tell it about the plural of Figure
+    \crefname{figure}{Figure}{Figures}
+
+    % cleveref: fix "Eq. (1)" to "(1)"
+    \crefname{equation}{}{}
+
+    % cleveref: fix "Item. (i)" to "(i)"
+    \crefname{enumi}{}{}
+
+    % fix for broken hyperref hooks on Nov-2024 kernel
+    \AddToHook{env/proposition/begin}{\crefalias{theorem}{proposition}}
+    \AddToHook{env/corollary/begin}{\crefalias{theorem}{corollary}}
+    \AddToHook{env/lemma/begin}{\crefalias{theorem}{lemma}}
+    \AddToHook{env/remark/begin}{\crefalias{theorem}{remark}}
+    \AddToHook{env/definition/begin}{\crefalias{theorem}{definition}}
+    \AddToHook{env/example/begin}{\crefalias{theorem}{example}}
+}
+
+% patch incompatible AMS environments for lineno
+\AfterPackage{lineno}{%
+    \newcommand*\patchAmsMathEnvironmentForLineno[1]{%
+        \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname
+        \expandafter\let\csname oldend#1\expandafter\endcsname\csname end#1\endcsname
+        \renewenvironment{#1}%
+        {\linenomath\csname old#1\endcsname}%
+    {\csname oldend#1\endcsname\endlinenomath}}% 
+    \newcommand*\patchBothAmsMathEnvironmentsForLineno[1]{%
+        \patchAmsMathEnvironmentForLineno{#1}%
+    \patchAmsMathEnvironmentForLineno{#1*}}%
+    \AtBeginDocument{%
+        \patchBothAmsMathEnvironmentsForLineno{equation}%
+        \patchBothAmsMathEnvironmentsForLineno{align}%
+        \patchBothAmsMathEnvironmentsForLineno{flalign}%
+        \patchBothAmsMathEnvironmentsForLineno{alignat}%
+        \patchBothAmsMathEnvironmentsForLineno{gather}%
+        \patchBothAmsMathEnvironmentsForLineno{multline}%
+    }
+    \renewcommand{\linenumberfont}{\normalfont\scriptsize\sffamily\color{gray}}
+    \renewcommand\thelinenumber{\tabularnumsf{\arabic{linenumber}}}
+}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% PDF metadata
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\AtBeginDocument{
+    \begingroup
+    % Override \and and \thanks to clean up author
+    \def\and{ and }
+    \def\thanks#1{\relax}
+    \hypersetup{
+        pdftitle = {\@title},
+        pdfauthor = {\@author},
+    }
+    \endgroup
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/symbols-texonly.tex	Fri Mar 28 08:36:08 2025 -0500
@@ -0,0 +1,15 @@
+
+\renewrobustcmd{\downto}{{{\mathchoice%
+            {\rotatebox[origin=c]{-20}{$\to$}}% display
+            {\rotatebox[origin=c]{-20}{$\to$}}% text
+            {\rotatebox[origin=c]{-20}{\scalebox{0.75}{$\to$}}}% subscript
+            {\rotatebox[origin=c]{-20}{\scalebox{0.6}{$\to$}}}% subsubscript
+}}}
+
+\renewrobustcmd{\upto}{{{\mathchoice%
+            {\rotatebox[origin=c]{20}{$\to$}}% display
+            {\rotatebox[origin=c]{20}{$\to$}}% text
+            {\rotatebox[origin=c]{20}{\scalebox{0.75}{$\to$}}}% subscript
+            {\rotatebox[origin=c]{20}{\scalebox{0.6}{$\to$}}}% subsubscript
+}}}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/symbols.tex	Fri Mar 28 08:36:08 2025 -0500
@@ -0,0 +1,166 @@
+\newcommand{\term}{\emph}
+
+\newcommand{\field}[1]{\mathbb{#1}}
+\newcommand{\N}{\mathbb{N}}
+\newcommand{\Z}{\mathbb{Z}}
+\newcommand{\Q}{\field{Q}}
+\newcommand{\R}{\field{R}}
+\newcommand{\extR}{\overline \R}
+\newcommand{\Complex}{\field{C}}
+\newcommand{\B}{\mathbb{B}}
+\newcommand{\OB}{\mathbb{O}}
+%\newcommand{\UU}{\mathbb{U}}
+% Trust regions are just normal balls.
+\let\UU\B
+\newcommand{\norm}[1]{\|#1\|}
+\newcommand{\adaptnorm}[1]{\left\|#1\right\|}
+\newcommand{\bignorm}[1]{\bigl\|#1\bigr\|}
+\newcommand{\Bignorm}[1]{\Bigl\|#1\Bigr\|}
+\newcommand{\abs}[1]{|#1|}
+\newcommand{\adaptabs}[1]{\left|#1\right|}
+\newcommand{\bigabs}[1]{\bigl|#1\bigr|}
+\newcommand{\inv}[1]{#1^{-1}}
+\newcommand{\grad}{\nabla}
+\newcommand{\freevar}{\,\boldsymbol\cdot\,}
+\newcommand{\Union}\bigcup
+\newcommand{\Isect}\bigcap
+\newcommand{\union}\cup
+\newcommand{\isect}\cap
+\newcommand{\bigunion}\bigcup
+\newcommand{\bigisect}\bigcap
+\newcommand{\powerset}{\mathcal{P}}
+\newcommand{\defeq}{:=}
+\newcommand{\set}[1]{\{#1\}}
+\newcommand{\downto}{\searrow}
+\newcommand{\upto}{\nearrow}
+\newcommand{\subdiff}{\partial}
+\newcommand{\pinv}[1]{#1^\dag}
+\newcommand{\overbar}[1]{\mkern 1.5mu\overline{\mkern-1.5mu#1\mkern-1.5mu}\mkern 1.5mu}
+
+\DeclareMathOperator*{\lip}{lip}
+\DeclareMathOperator*{\argmin}{arg\,min}
+\DeclareMathOperator*{\argmax}{arg\,max}
+\DeclareMathOperator{\interior}{int}
+\DeclareMathOperator{\ri}{ri}
+\DeclareMathOperator{\rbd}{rbd}
+\DeclareMathOperator{\closure}{cl}
+\DeclareMathOperator{\bd}{bd}
+\DeclareMathOperator{\sign}{sign}
+\DeclareMathOperator{\Sign}{Sign}
+\DeclareMathOperator{\rank}{rank}
+\DeclareMathOperator{\range}{ran}
+\DeclareMathOperator{\dom}{dom}
+\DeclareMathOperator{\cod}{cod}
+\DeclareMathOperator{\lev}{lev}
+\DeclareMathOperator{\conv}{conv}
+\DeclareMathOperator{\diam}{diam}
+\DeclareMathOperator{\epi}{epi}
+\DeclareMathOperator{\tr}{tr}
+\DeclareMathOperator{\diag}{diag}
+\DeclareMathOperator{\graph}{graph}
+\DeclareMathOperator{\cond}{cond}
+\DeclareMathOperator{\esssup}{ess\,sup}
+\DeclareMathOperator{\support}{supp}
+\DeclareMathOperator{\divergence}{div}
+\DeclareMathOperator{\Id}{Id}
+\DeclareMathOperator{\dist}{dist}
+\DeclareMathOperator{\Sym}{Sym}
+\DeclareMathOperator{\prox}{prox}
+\DeclareMathOperator{\gdesc}{g-desc}
+\DeclareMathOperator{\gexp}{g-exp}
+\DeclareMathOperator{\desc}{desc}
+
+\newcommand{\mathvar}[1]{\textup{#1}}
+
+\newcommand{\iprod}[2]{\langle #1,#2\rangle}
+%\newcommand{\dualprod}[2]{\langle #1 | #2\rangle}
+\newcommand{\dualprod}[2]{\langle #1,#2\rangle}
+\newcommand{\adaptiprod}[2]{\left\langle #1,#2\right\rangle}
+
+\newcommand{\weakto}{\mathrel{\rightharpoonup}}
+%\makeatletter
+\def \weaktostarSym{\setbox0=\hbox{$\rightharpoonup$}\rlap{\hbox 
+        to\wd0{\hss\raise1ex\hbox{$\scriptscriptstyle{*\,}$}\hss}}\box0}
+    \def \weaktostar    {\mathrel{\weaktostarSym}}
+%\makeatother
+
+\newcommand{\setto}{\rightrightarrows}
+
+\def\opt#1{\bar #1}
+\def\realopt#1{\widehat #1}
+\def\dir#1{\Delta #1}
+\def\alt#1{\tilde #1}
+\def\altalt#1{#1'}
+\def\this#1{#1^k}
+\def\nexxt#1{#1^{k+1}}
+\def\overnext#1{\bar #1^{k+1}}
+\def\prev#1{#1^{k-1}}
+\def\thisstar#1{#1^k^*}
+\def\nextstar#1{#1^{k+1}^*}
+\def\optstar#1{\opt{#1}^*}
+\def\realoptstar#1{\realopt{#1}^*}
+
+\def\optu{{\opt{u}}}
+\def\optv{{\opt{v}}}
+\def\optw{{\opt{w}}}
+\def\optx{{\opt{x}}}
+\def\opty{{\opt{y}}}
+\def\optz{{\opt{z}}}
+
+\def\realoptu{{\realopt{u}}}
+\def\realoptv{{\realopt{v}}}
+\def\realoptw{{\realopt{w}}}
+\def\realoptx{{\realopt{x}}}
+\def\realopty{{\realopt{y}}}
+\def\realoptz{{\realopt{z}}}
+
+\def\nextu{\nexxt{u}}
+\def\nextv{\nexxt{v}}
+\def\nextw{\nexxt{w}}
+\def\nextx{\nexxt{x}}
+\def\nexty{\nexxt{y}}
+\def\nextz{\nexxt{z}}
+
+\def\thisu{\this{u}}
+\def\thisv{\this{v}}
+\def\thisw{\this{w}}
+\def\thisx{\this{x}}
+\def\thisy{\this{y}}
+\def\thisz{\this{z}}
+
+\def\prevu{\prev{u}}
+\def\prevv{\prev{v}}
+\def\prevw{\prev{w}}
+\def\prevx{\prev{x}}
+\def\prevy{\prev{y}}
+\def\prevz{\prev{z}}
+
+\def\overnextu{\overnext{u}}
+\def\overnextx{\overnext{x}}
+
+\def\d{\,\mathrm{d}}
+
+\let\altphi\phi
+\let\phi\varphi
+\let\altepsilon\epsilon
+\let\epsilon\varepsilon
+
+\newcommand{\frechetNormal}{\widehat N}
+\newcommand{\frechetCod}{\widehat D^*}
+\newcommand{\clarkeTangent}{\widehat T}
+\newcommand{\clarkeGD}{\widehat D}
+\newcommand{\coderivative}{D^*}
+\newcommand{\polar}[1]{#1^{\circ}}
+\newcommand{\bipolar}[1]{#1^{\circ\circ}}
+\newcommand{\upperadj}[1]{#1^{\circ+}}
+\newcommand{\loweradj}[1]{#1^{\circ-}}
+
+\def\invstar#1{{#1}^{-1,*}}
+\def\pinvstar#1{{#1}^{\dagger*}}
+\def\starpinv#1{{#1}^{*\dagger}}
+
+\def\linear{\mathbb{L}}
+ 
+\def\QL{\mathop{QL}\nolimits}
+
+\def\lebesgue{\mathcal{L}}

mercurial