\documentclass[12pt]{cdblatex}
\usepackage{fancyhdr}
\usepackage{footer}

\begin{document}

% =================================================================================================
% create checkpoint file

\bgroup
\CdbSetup{action=hide}
\begin{cadabra}
   import cdblib
   checkpoint_file = 'tests/semantic/output/metric-inv.json'
   cdblib.create (checkpoint_file)
   checkpoint = []
\end{cadabra}
\egroup

% =================================================================================================
\section*{The inverse metric tensor in Riemann normal coordinates}

Here we calculate the Riemann normal expansion of the inverse metric, $g^{ab}$, by developing
the recursive sequences
\begin{align}
\label{eq:pdgab}
g^{ab}{}_{,d\ue} &= - \left(g^{cb}\Gamma^{a}{}_{c(d}\right){}_{,\ue)}
                    - \left(g^{ac}\Gamma^{b}{}_{c(d}\right){}_{,\ue)}\\[10pt]
\label{eq:pdGamma}
(n+3)\Gamma^a{}_{d(b,c\ue)} &= (n+1)\left(R^a{}_{(bc\Dot d,\ue)} - \left(\Gamma^a{}_{f(c}\Gamma^f{}_{b{\Dot d}}\right){}_{,\ue)}\right)
\end{align}
for $n=1,2,3,\cdots$. Note in these equations that the (extended) index $\ue$ contains $n$
normal indices.

We then construct a Taylor series for the metric using
\begin{dmath*}[spread=5pt]
g^{ab}(x) = g^{ab} + g^{ab}{}_{,c}x^c + \frac{1}{2!} g^{ab}{}_{,cd}x^cx^d + \frac{1}{3!} g^{ab}{}_{,cde}x^cx^dx^e + \cdots
          = g^{ab} + \sum_{n=1}^\infty\> \frac{1}{n!}\>g^{ab}{}_{,\uc}\>x^{.\uc}
\end{dmath*}

% =================================================================================================
\section*{Stage 1: Symmetrised partial derivatives of $g^{ab}$}

In this stage, equation (\ref{eq:pdgab}) is used to express the symmetrised partial derivatives
of the metric in terms of the symmetrised partial derivatives of the connection.

\begin{dgroup*}
   \begin{dmath*} g^{ab}{}_{,c} A^{c} = \cdb{term1.200} \end{dmath*}
   \begin{dmath*} g^{ab}{}_{,cd} A^{c} A^{d} = \cdb{term2.200} \end{dmath*}
   \begin{dmath*} g^{ab}{}_{,cde} A^{c} A^{d} A^{e} = \cdb{term3.200} \end{dmath*}
\end{dgroup*}

% =================================================================================================
\section*{Stage 2: Replace derivatives of $\Gamma$ with partial derivs of $R$}

Now we use the results from {\verb|dGamma|} to replace derivatives of $\Gamma$ with
partial derivatives of $R$. These were computed in {\verb|dGamma|} using equation
(\ref{eq:pdGamma}) above.

\begin{dgroup*}
   \begin{dmath*} g^{ab}{}_{,c} A^{c} = \cdb{term1.200} \end{dmath*}
   \begin{dmath*} g^{ab}{}_{,cd} A^{c} A^{d} = \cdb{term2.303} \end{dmath*}
   \begin{dmath*} g^{ab}{}_{,cde} A^{c} A^{d} A^{e} = \cdb{term3.305} \end{dmath*}
\end{dgroup*}

% =================================================================================================
\section*{Stage 3: Replace partial derivs of $R$ with covariant derivs of $R$}

Next we use the results from {\verb|dRabcd|} to replace the partial derivatives of $R$ with
covariant deriavtives.

\begin{dgroup*}
   \begin{dmath*} g^{ab}{}_{,c} A^{c} = \cdb{term1.404} \end{dmath*}
   \begin{dmath*} g^{ab}{}_{,cd} A^{c} A^{d} = \cdb{term2.404} \end{dmath*}
   \begin{dmath*} g^{ab}{}_{,cde} A^{c} A^{d} A^{e} = \cdb{term3.403} \end{dmath*}
\end{dgroup*}

% =================================================================================================
\section*{Stage 4: Build the Taylor series for $g_{ab}$, reformatting and output}

Each of the above expressions constitutues one term in the Taylor series for the metric.
We also make the trivial change $A\rightarrow x$. Then we do some trivial reformatting.

\begin{align*}
   g_{ab}(x) &=   g^{ab}
                + g^{ab}{}_{,c} x^c
                + \frac{1}{2!} g^{ab}{}_{,cd} x^c x^d
                + \frac{1}{3!} g^{ab}{}_{,cde} x^c x^d x^e +  \BigO{\eps^4}\\
             &= \cdb{metric4.501} + \BigO{\eps^4}
\end{align*}

\clearpage

% =================================================================================================
\section*{Shared properties}

\begin{cadabra}
   import time

   def flatten_Rabcd (obj):
       substitute (obj,$R^{a}_{b c d}   -> g^{a e} R_{e b c d}$)
       substitute (obj,$R_{a}^{b}_{c d} -> g^{b e} R_{a e c d}$)
       substitute (obj,$R_{a b}^{c}_{b} -> g^{c e} R_{a b e d}$)
       substitute (obj,$R_{a b c}^{d}   -> g^{d e} R_{a b c e}$)
       unwrap     (obj)
       sort_product   (obj)
       rename_dummies (obj)
       return obj

   def impose_rnc (obj):
       # hide the derivatives of Gamma
       substitute (obj,$\partial_{d}{\Gamma^{a}_{b c}} -> zzz_{d}^{a}_{b c}$,repeat=True)
       substitute (obj,$\partial_{d e}{\Gamma^{a}_{b c}} -> zzz_{d e}^{a}_{b c}$,repeat=True)
       substitute (obj,$\partial_{d e f}{\Gamma^{a}_{b c}} -> zzz_{d e f}^{a}_{b c}$,repeat=True)
       substitute (obj,$\partial_{d e f g}{\Gamma^{a}_{b c}} -> zzz_{d e f g}^{a}_{b c}$,repeat=True)
       substitute (obj,$\partial_{d e f g h}{\Gamma^{a}_{b c}} -> zzz_{d e f g h}^{a}_{b c}$,repeat=True)
       # set Gamma to zero
       substitute (obj,$\Gamma^{a}_{b c} -> 0$,repeat=True)
       # recover the derivatives Gamma
       substitute (obj,$zzz_{d}^{a}_{b c} -> \partial_{d}{\Gamma^{a}_{b c}}$,repeat=True)
       substitute (obj,$zzz_{d e}^{a}_{b c} -> \partial_{d e}{\Gamma^{a}_{b c}}$,repeat=True)
       substitute (obj,$zzz_{d e f}^{a}_{b c} -> \partial_{d e f}{\Gamma^{a}_{b c}}$,repeat=True)
       substitute (obj,$zzz_{d e f g}^{a}_{b c} -> \partial_{d e f g}{\Gamma^{a}_{b c}}$,repeat=True)
       substitute (obj,$zzz_{d e f g h}^{a}_{b c} -> \partial_{d e f g h}{\Gamma^{a}_{b c}}$,repeat=True)
       return obj

   def get_xterm (obj,n):

       x^{a}::Weight(label=numx).

       foo := @(obj).
       bah  = Ex("numx = " + str(n))
       keep_weight (foo,bah)

       return foo

   # note: keeping numbering as is (out of order) to ensure R appears before \nabla R etc.
   def product_sort (obj):
       substitute (obj,$ A^{a}                             -> A001^{a}                  $)
       substitute (obj,$ x^{a}                             -> A002^{a}                  $)
       substitute (obj,$ g_{a b}                           -> A003_{a b}                $)
       substitute (obj,$ g^{a b}                           -> A004^{a b}                $)
       substitute (obj,$ \nabla_{e f g h}{R_{a b c d}}     -> A010_{a b c d e f g h}    $)
       substitute (obj,$ \nabla_{e f g}{R_{a b c d}}       -> A009_{a b c d e f g}      $)
       substitute (obj,$ \nabla_{e f}{R_{a b c d}}         -> A008_{a b c d e f}        $)
       substitute (obj,$ \nabla_{e}{R_{a b c d}}           -> A007_{a b c d e}          $)
       substitute (obj,$ \partial_{e f g h}{R_{a b c d}}   -> A014_{a b c d e f g h}    $)
       substitute (obj,$ \partial_{e f g}{R_{a b c d}}     -> A013_{a b c d e f g}      $)
       substitute (obj,$ \partial_{e f}{R_{a b c d}}       -> A012_{a b c d e f}        $)
       substitute (obj,$ \partial_{e}{R_{a b c d}}         -> A011_{a b c d e}          $)
       substitute (obj,$ \partial_{e f g h}{R^{a}_{b c d}} -> A018^{a}_{b c d e f g h}  $)
       substitute (obj,$ \partial_{e f g}{R^{a}_{b c d}}   -> A017^{a}_{b c d e f g}    $)
       substitute (obj,$ \partial_{e f}{R^{a}_{b c d}}     -> A016^{a}_{b c d e f}      $)
       substitute (obj,$ \partial_{e}{R^{a}_{b c d}}       -> A015^{a}_{b c d e}        $)
       substitute (obj,$ R_{a b c d}                       -> A005_{a b c d}            $)
       substitute (obj,$ R^{a}_{b c d}                     -> A006^{a}_{b c d}          $)
       sort_product   (obj)
       rename_dummies (obj)
       substitute (obj,$ A001^{a}                  -> A^{a}                             $)
       substitute (obj,$ A002^{a}                  -> x^{a}                             $)
       substitute (obj,$ A003_{a b}                -> g_{a b}                           $)
       substitute (obj,$ A004^{a b}                -> g^{a b}                           $)
       substitute (obj,$ A005_{a b c d}            -> R_{a b c d}                       $)
       substitute (obj,$ A006^{a}_{b c d}          -> R^{a}_{b c d}                     $)
       substitute (obj,$ A007_{a b c d e}          -> \nabla_{e}{R_{a b c d}}           $)
       substitute (obj,$ A008_{a b c d e f}        -> \nabla_{e f}{R_{a b c d}}         $)
       substitute (obj,$ A009_{a b c d e f g}      -> \nabla_{e f g}{R_{a b c d}}       $)
       substitute (obj,$ A010_{a b c d e f g h}    -> \nabla_{e f g h}{R_{a b c d}}     $)
       substitute (obj,$ A011_{a b c d e}          -> \partial_{e}{R_{a b c d}}         $)
       substitute (obj,$ A012_{a b c d e f}        -> \partial_{e f}{R_{a b c d}}       $)
       substitute (obj,$ A013_{a b c d e f g}      -> \partial_{e f g}{R_{a b c d}}     $)
       substitute (obj,$ A014_{a b c d e f g h}    -> \partial_{e f g h}{R_{a b c d}}   $)
       substitute (obj,$ A015^{a}_{b c d e}        -> \partial_{e}{R^{a}_{b c d}}       $)
       substitute (obj,$ A016^{a}_{b c d e f}      -> \partial_{e f}{R^{a}_{b c d}}     $)
       substitute (obj,$ A017^{a}_{b c d e f g}    -> \partial_{e f g}{R^{a}_{b c d}}   $)
       substitute (obj,$ A018^{a}_{b c d e f g h}  -> \partial_{e f g h}{R^{a}_{b c d}} $)

       return obj

   def reformat_xterm (obj,scale):
      foo  = Ex(str(scale))
      bah := @(foo) @(obj).
      distribute     (bah)
      bah = product_sort (bah)
      rename_dummies (bah)
      canonicalise   (bah)
      factor_out     (bah,$x^{a?}$)
      ans := @(bah) / @(foo).
      return ans

   def rescale_xterm (obj,scale):
      foo  = Ex(str(scale))
      bah := @(foo) @(obj).
      distribute  (bah)
      factor_out  (bah,$x^{a?}$)
      return bah

   def add_tags (obj,tag):
      n = 0
      ans = Ex('0')
      for i in obj.top().terms():
         foo = obj[i]
         bah = Ex(tag+'_{'+str(n)+'}')
         ans := @(ans) + @(bah) @(foo).
         n = n + 1
      return ans

   def clear_tags (obj,tag):
      ans := @(obj).
      foo  = Ex(tag+'_{a?} -> 1')
      substitute (ans,foo)
      return ans

   {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w#}::Indices(position=independent).

   \nabla{#}::Derivative.
   \partial{#}::PartialDerivative.

   g_{a b}::Metric.
   g^{a b}::InverseMetric.
   g_{a}^{b}::KroneckerDelta.
   g^{a}_{b}::KroneckerDelta.

   R_{a b c d}::RiemannTensor.
   R^{a}_{b c d}::RiemannTensor.
   R_{a b c}^{d}::RiemannTensor.

   \Gamma^{a}_{b c}::TableauSymmetry(shape={2}, indices={1,2}).

   g_{a b}::Depends(\partial{#}).
   R_{a b c d}::Depends(\partial{#}).
   R^{a}_{b c d}::Depends(\partial{#}).
   \Gamma^{a}_{b c}::Depends(\partial{#}).

   R_{a b c d}::Depends(\nabla{#}).
   R^{a}_{b c d}::Depends(\nabla{#}).

\end{cadabra}

\clearpage

% =================================================================================================
\section*{Stage 1: Symmetrised partial derivatives of $g^{ab}$}

\begin{cadabra}
   beg_stage_1 = time.time()

   # symmetrised partial derivatives of g^{ab}

   gab00:=g^{a b}.                                              # cdb (gab00.101,gab00)

   gab01:= - g^{c b}\Gamma^{a}_{c d} - g^{a c}\Gamma^{b}_{c d}. # cdb (gab01.101,gab01)

   gab02:=\partial_{e}{ @(gab01) }.                             # cdb (gab02.101,gab02)
   distribute   (gab02)                                         # cdb (gab02.102,gab02)
   product_rule (gab02)                                         # cdb (gab02.103,gab02)
   substitute   (gab02, $\partial_{d}{g^{a b}} -> @(gab01)$)    # cdb (gab02.104,gab02)
   distribute   (gab02)                                         # cdb (gab02.105,gab02)

   gab03:=\partial_{f}{ @(gab02) }.                             # cdb (gab03.101,gab03)
   distribute   (gab03)                                         # cdb (gab03.102,gab03)
   product_rule (gab03)                                         # cdb (gab03.103,gab03)
   substitute   (gab03, $\partial_{d}{g^{a b}} -> @(gab01)$)    # cdb (gab03.104,gab03)
   distribute   (gab03)                                         # cdb (gab03.105,gab03)

   gab04:=\partial_{g}{ @(gab03) }.                             # cdb (gab04.101,gab04)
   distribute   (gab04)                                         # cdb (gab04.102,gab04)
   product_rule (gab04)                                         # cdb (gab04.103,gab04)
   substitute   (gab04, $\partial_{d}{g^{a b}} -> @(gab01)$)    # cdb (gab04.104,gab04)
   distribute   (gab04)                                         # cdb (gab04.105,gab04)

   gab05:=\partial_{h}{ @(gab04) }.                             # cdb (gab05.101,gab05)
   distribute   (gab05)                                         # cdb (gab05.102,gab05)
   product_rule (gab05)                                         # cdb (gab05.103,gab05)
   substitute   (gab05, $\partial_{d}{g^{a b}} -> @(gab01)$)    # cdb (gab05.104,gab05)
   distribute   (gab05)                                         # cdb (gab05.105,gab05)

   gab00 = impose_rnc (gab00)   # cdb (gab00.102,gab00)
   gab01 = impose_rnc (gab01)   # cdb (gab01.102,gab01)
   gab02 = impose_rnc (gab02)   # cdb (gab02.106,gab02)
   gab03 = impose_rnc (gab03)   # cdb (gab03.106,gab03)
   gab04 = impose_rnc (gab04)   # cdb (gab04.106,gab04)
   gab05 = impose_rnc (gab05)   # cdb (gab05.106,gab05)

\end{cadabra}

\clearpage

\begin{dgroup*}
   \begin{dmath*} \cdb*{gab00.101} \end{dmath*}
   \begin{dmath*} \cdb*{gab00.102} \end{dmath*}
   \begin{dmath*} \cdb*{gab01.101} \end{dmath*}
   \begin{dmath*} \cdb*{gab01.102} \end{dmath*}
\end{dgroup*}

\begin{dgroup*}
   \begin{dmath*} \cdb*{gab02.101} \end{dmath*}
   \begin{dmath*} \cdb*{gab02.102} \end{dmath*}
   \begin{dmath*} \cdb*{gab02.103} \end{dmath*}
   \begin{dmath*} \cdb*{gab02.104} \end{dmath*}
   \begin{dmath*} \cdb*{gab02.105} \end{dmath*}
   \begin{dmath*} \cdb*{gab02.106} \end{dmath*}
\end{dgroup*}

\begin{dgroup*}
   \begin{dmath*} \cdb*{gab03.101} \end{dmath*}
   \begin{dmath*} \cdb*{gab03.102} \end{dmath*}
   \begin{dmath*} \cdb*{gab03.103} \end{dmath*}
   \begin{dmath*} \cdb*{gab03.104} \end{dmath*}
   \begin{dmath*} \cdb*{gab03.105} \end{dmath*}
   \begin{dmath*} \cdb*{gab03.106} \end{dmath*}
\end{dgroup*}

\begin{dgroup*}
   \begin{dmath*} \cdb*{gab04.101} \end{dmath*}
   \begin{dmath*} \cdb*{gab04.102} \end{dmath*}
   \begin{dmath*} \cdb*{gab04.103} \end{dmath*}
   \begin{dmath*} \cdb*{gab04.104} \end{dmath*}
   \begin{dmath*} \cdb*{gab04.105} \end{dmath*}
   \begin{dmath*} \cdb*{gab04.106} \end{dmath*}
\end{dgroup*}

\begin{cadabra}
   # prepare first six terms in the Taylor series expansion of g^{ab}(x)

   term0:= @(gab00).
   distribute (term0)                             # cdb(term0.200,term0)

   term1:= @(gab01) A^d.
   distribute (term1)                             # cdb(term1.200,term1)

   term2:= @(gab02) A^d A^e.
   distribute (term2)                             # cdb(term2.200,term2)

   term3:= @(gab03) A^d A^e A^f.
   distribute (term3)                             # cdb(term3.200,term3)

   term4:= @(gab04) A^d A^e A^f A^g.
   distribute (term4)                             # cdb(term4.200,term4)

   term5:= @(gab05) A^d A^e A^f A^g A^h.
   distribute (term5)                             # cdb(term5.200,term5)

   end_stage_1 = time.time()
\end{cadabra}

\begin{dgroup*}
   \begin{dmath*} \cdb*{term0.200} \end{dmath*}
   \begin{dmath*} \cdb*{term1.200} \end{dmath*}
   \begin{dmath*} \cdb*{term2.200} \end{dmath*}
   \begin{dmath*} \cdb*{term3.200} \end{dmath*}
   % \begin{dmath*} \cdb*{term4.200} \end{dmath*}
   % \begin{dmath*} \cdb*{term5.200} \end{dmath*}
\end{dgroup*}

\clearpage

% =================================================================================================
\section*{Stage 2: Replace derivatives of $\Gamma$ with partial derivs of $R$}

\begin{cadabra}
   import cdblib

   beg_stage_2 = time.time()

   dGamma01 = cdblib.get ('dGamma01','dGamma.json')  # cdb(dGamma01.300,dGamma01)
   dGamma02 = cdblib.get ('dGamma02','dGamma.json')  # cdb(dGamma02.300,dGamma02)
   dGamma03 = cdblib.get ('dGamma03','dGamma.json')  # cdb(dGamma03.300,dGamma03)
   dGamma04 = cdblib.get ('dGamma04','dGamma.json')  # cdb(dGamma04.300,dGamma04)
   dGamma05 = cdblib.get ('dGamma05','dGamma.json')  # cdb(dGamma05.300,dGamma05)

   # replace partial derivs of \Gamma with products and derivs of Riemann tensor

   substitute (term2,$\partial_{c}{\Gamma^{a}_{b d}}A^{c}A^{b} -> @(dGamma01)$,repeat=True)                       # cdb(term2.301,term2)
   substitute (term2,$\partial_{c}{\Gamma^{a}_{d b}}A^{c}A^{b} -> @(dGamma01)$,repeat=True)                       # cdb(term2.302,term2)
   distribute (term2)                                                                                # cdb(term2.303,term2)

   substitute (term3,$\partial_{c e}{\Gamma^{a}_{d b}}A^{c}A^{b}A^{e} -> @(dGamma02)$,repeat=True)                # cdb(term3.301,term3)
   substitute (term3,$\partial_{c e}{\Gamma^{a}_{b d}}A^{c}A^{b}A^{e} -> @(dGamma02)$,repeat=True)                # cdb(term3.302,term3)
   substitute (term3,$\partial_{c}{\Gamma^{a}_{b d}}A^{c}A^{b} -> @(dGamma01)$,repeat=True)                       # cdb(term3.303,term3)
   substitute (term3,$\partial_{c}{\Gamma^{a}_{d b}}A^{c}A^{b} -> @(dGamma01)$,repeat=True)                       # cdb(term3.304,term3)
   distribute (term3)                                                                                # cdb(term3.305,term3)

   substitute (term4,$\partial_{c e f}{\Gamma^{a}_{d b}}A^{c}A^{b}A^{e}A^{f} -> @(dGamma03)$,repeat=True)         # cdb(term4.301,term4)
   substitute (term4,$\partial_{c e f}{\Gamma^{a}_{b d}}A^{c}A^{b}A^{e}A^{f} -> @(dGamma03)$,repeat=True)         # cdb(term4.302,term4)
   substitute (term4,$\partial_{c e}{\Gamma^{a}_{d b}}A^{c}A^{b}A^{e} -> @(dGamma02)$,repeat=True)                # cdb(term4.303,term4)
   substitute (term4,$\partial_{c e}{\Gamma^{a}_{b d}}A^{c}A^{b}A^{e} -> @(dGamma02)$,repeat=True)                # cdb(term4.304,term4)
   substitute (term4,$\partial_{c}{\Gamma^{a}_{b d}}A^{c}A^{b} -> @(dGamma01)$,repeat=True)                       # cdb(term4.305,term4)
   substitute (term4,$\partial_{c}{\Gamma^{a}_{d b}}A^{c}A^{b} -> @(dGamma01)$,repeat=True)                       # cdb(term4.306,term4)
   distribute (term4)                                                                                # cdb(term4.307,term4)

   substitute (term5,$\partial_{c e f g}{\Gamma^{a}_{d b}}A^{c}A^{b}A^{e}A^{f}A^{g} -> @(dGamma04)$,repeat=True)  # cdb(term5.301,term5)
   substitute (term5,$\partial_{c e f g}{\Gamma^{a}_{b d}}A^{c}A^{b}A^{e}A^{f}A^{g} -> @(dGamma04)$,repeat=True)  # cdb(term5.302,term5)
   substitute (term5,$\partial_{c e f}{\Gamma^{a}_{d b}}A^{c}A^{b}A^{e}A^{f} -> @(dGamma03)$,repeat=True)         # cdb(term5.303,term5)
   substitute (term5,$\partial_{c e f}{\Gamma^{a}_{b d}}A^{c}A^{b}A^{e}A^{f} -> @(dGamma03)$,repeat=True)         # cdb(term5.304,term5)
   substitute (term5,$\partial_{c e}{\Gamma^{a}_{d b}}A^{c}A^{b}A^{e} -> @(dGamma02)$,repeat=True)                # cdb(term5.305,term5)
   substitute (term5,$\partial_{c e}{\Gamma^{a}_{b d}}A^{c}A^{b}A^{e} -> @(dGamma02)$,repeat=True)                # cdb(term5.306,term5)
   substitute (term5,$\partial_{c}{\Gamma^{a}_{b d}}A^{c}A^{b} -> @(dGamma01)$,repeat=True)                       # cdb(term5.307,term5)
   substitute (term5,$\partial_{c}{\Gamma^{a}_{d b}}A^{c}A^{b} -> @(dGamma01)$,repeat=True)                       # cdb(term5.308,term5)
   distribute (term5)                                                                                # cdb(term5.309,term5)

   # ------------------------------------------------------------------------------------
   # this block only produces formatted output, it is not part of the main computation
   # ------------------------------------------------------------------------------------

   # the metric in terms of partial derivatives of Rabcd

   metric:=@(term0)
         + (1/1) @(term1)
         + (1/2) @(term2)
         + (1/6) @(term3)
         + (1/24) @(term4)
         + (1/120) @(term5).  # cdb(metric.301,metric)

   substitute (metric,$A^{a} -> x^{a}$)  # cdb (metric.302,metric)

   # reformat and tidy up

   Xterm0 := @(term0).
   Xterm1 := (1/1) @(term1).     # zero
   Xterm2 := (1/2) @(term2).
   Xterm3 := (1/6) @(term3).
   Xterm4 := (1/24) @(term4).
   Xterm5 := (1/120) @(term5).

   substitute (Xterm0,$A^{a} -> x^{a}$)
   substitute (Xterm1,$A^{a} -> x^{a}$)
   substitute (Xterm2,$A^{a} -> x^{a}$)
   substitute (Xterm3,$A^{a} -> x^{a}$)
   substitute (Xterm4,$A^{a} -> x^{a}$)
   substitute (Xterm5,$A^{a} -> x^{a}$)

   # Manipulating these expressions is hampered by the presence of the partial derivative on Rabcd.
   # Thus we can't freely rasie/lower indices on the dRabcd terms. But we can do so on the first
   # derivatives (since these are evaluated at x=0 where the connection vanishes).

   substitute       (Xterm2,$g^{a b} R^{c}_{d e b} -> R^{c}_{d e}^{a}}$)  # cdb(Xterm2.301,Xterm2)
   substitute       (Xterm3,$g^{a b} R^{c}_{d e b} -> R^{c}_{d e}^{a}}$)  # cdb(Xterm3.301,Xterm3)
   substitute       (Xterm4,$g^{a b} R^{c}_{d e b} -> R^{c}_{d e}^{a}}$)  # cdb(Xterm4.301,Xterm4)
   substitute       (Xterm5,$g^{a b} R^{c}_{d e b} -> R^{c}_{d e}^{a}}$)  # cdb(Xterm5.301,Xterm5)

   substitute       (Xterm2,$g^{b a} R^{c}_{d e b} -> R^{c}_{d e}^{a}}$)  # cdb(Xterm2.302,Xterm2)
   substitute       (Xterm3,$g^{b a} R^{c}_{d e b} -> R^{c}_{d e}^{a}}$)  # cdb(Xterm3.302,Xterm3)
   substitute       (Xterm4,$g^{b a} R^{c}_{d e b} -> R^{c}_{d e}^{a}}$)  # cdb(Xterm4.302,Xterm4)
   substitute       (Xterm5,$g^{b a} R^{c}_{d e b} -> R^{c}_{d e}^{a}}$)  # cdb(Xterm5.302,Xterm5)

   substitute       (Xterm2,$g^{a b} \partial_{c}{R^{d}_{e f b}} -> \partial_{c}{R^{d}_{e f}^{a}$)  # cdb(Xterm2.303,Xterm2)
   substitute       (Xterm3,$g^{a b} \partial_{c}{R^{d}_{e f b}} -> \partial_{c}{R^{d}_{e f}^{a}$)  # cdb(Xterm3.303,Xterm3)
   substitute       (Xterm4,$g^{a b} \partial_{c}{R^{d}_{e f b}} -> \partial_{c}{R^{d}_{e f}^{a}$)  # cdb(Xterm4.303,Xterm4)
   substitute       (Xterm5,$g^{a b} \partial_{c}{R^{d}_{e f b}} -> \partial_{c}{R^{d}_{e f}^{a}$)  # cdb(Xterm5.303,Xterm5)

   substitute       (Xterm2,$g^{b a} \partial_{c}{R^{d}_{e f b}} -> \partial_{c}{R^{d}_{e f}^{a}$)  # cdb(Xterm2.304,Xterm2)
   substitute       (Xterm3,$g^{b a} \partial_{c}{R^{d}_{e f b}} -> \partial_{c}{R^{d}_{e f}^{a}$)  # cdb(Xterm3.304,Xterm3)
   substitute       (Xterm4,$g^{b a} \partial_{c}{R^{d}_{e f b}} -> \partial_{c}{R^{d}_{e f}^{a}$)  # cdb(Xterm4.304,Xterm4)
   substitute       (Xterm5,$g^{b a} \partial_{c}{R^{d}_{e f b}} -> \partial_{c}{R^{d}_{e f}^{a}$)  # cdb(Xterm5.304,Xterm5)

   sort_product     (Xterm2)  # cdb(Xterm2.305,Xterm2)
   sort_product     (Xterm3)  # cdb(Xterm3.305,Xterm3)
   sort_product     (Xterm4)  # cdb(Xterm4.305,Xterm4)
   sort_product     (Xterm5)  # cdb(Xterm5.305,Xterm5)

   rename_dummies   (Xterm2)  # cdb(Xterm2.306,Xterm2)
   rename_dummies   (Xterm3)  # cdb(Xterm3.306,Xterm3)
   rename_dummies   (Xterm4)  # cdb(Xterm4.306,Xterm4)
   rename_dummies   (Xterm5)  # cdb(Xterm5.306,Xterm5)

   canonicalise     (Xterm2)  # cdb(Xterm2.307,Xterm2)
   canonicalise     (Xterm3)  # cdb(Xterm3.307,Xterm3)
   canonicalise     (Xterm4)  # cdb(Xterm4.307,Xterm4)
   canonicalise     (Xterm5)  # cdb(Xterm5.307,Xterm5)

   # We can simplify Xterm2 and Xterm3 by careful juggling of the indices (swapping free indices on selected terms)

   tmp = add_tags (Xterm2,'\\mu')       # cdb (tmp.001,tmp)
   zoom (tmp, $\mu_{1} Q??$)            # cdb (tmp.002,tmp)
   substitute (tmp, $R^{b}_{c d}^{a} x^{c} x^{d} -> R^{a}_{c d}^{b} x^{c} x^{d}$)  # cdb (tmp.003,tmp)
   unzoom (tmp)
   Xterm2 = clear_tags (tmp,'\\mu')     # cdb (Xterm2.401,Xterm2)

   tmp = add_tags (Xterm3,'\\mu')       # cdb (tmp.011,tmp)
   zoom (tmp, $\mu_{1} Q??$)            # cdb (tmp.012,tmp)
   substitute (tmp, $\partial_{c}{R^{b}_{d e}^{a}} x^{c} x^{d} x^{e} -> \partial_{c}{R^{a}_{d e}^{b}} x^{c} x^{d} x^{e}$)  # cdb (tmp.013,tmp)
   unzoom (tmp)
   Xterm3 = clear_tags (tmp,'\\mu')     # cdb (Xterm3.401,Xterm3)

   Xterm0 = reformat_xterm (Xterm0,  1)    # cdb(Xterm0.308,Xterm0)
   Xterm2 = reformat_xterm (Xterm2,  3)    # cdb(Xterm2.308,Xterm2)
   Xterm3 = reformat_xterm (Xterm3,  6)    # cdb(Xterm3.308,Xterm3)
   Xterm4 = reformat_xterm (Xterm4,360)    # cdb(Xterm4.308,Xterm4)
   Xterm5 = reformat_xterm (Xterm5,360)    # cdb(Xterm5.308,Xterm5)

   # metric to 4th and 6th order terms in powers of x^a

   Metric3 := @(Xterm0) + @(Xterm2).                                      # cdb (Metric3.301,Metric3)
   Metric4 := @(Xterm0) + @(Xterm2) + @(Xterm3).                          # cdb (Metric4.301,Metric4)
   Metric5 := @(Xterm0) + @(Xterm2) + @(Xterm3) + @(Xterm4).              # cdb (Metric5.301,Metric5)
   Metric6 := @(Xterm0) + @(Xterm2) + @(Xterm3) + @(Xterm4) + @(Xterm5).  # cdb (Metric6.301,Metric6)

   # ------------------------------------------------------------------------------------
   # end of format block
   # ------------------------------------------------------------------------------------

   end_stage_2 = time.time()
\end{cadabra}

\clearpage

\begin{dgroup*}
   \begin{dmath*} \cdb*{term2.301} \end{dmath*}
   \begin{dmath*} \cdb*{term2.302} \end{dmath*}
   \begin{dmath*} \cdb*{term2.303} \end{dmath*}
\end{dgroup*}

\begin{dgroup*}
   \begin{dmath*} \cdb*{term3.301} \end{dmath*}
   \begin{dmath*} \cdb*{term3.302} \end{dmath*}
   \begin{dmath*} \cdb*{term3.303} \end{dmath*}
   \begin{dmath*} \cdb*{term3.304} \end{dmath*}
   \begin{dmath*} \cdb*{term3.305} \end{dmath*}
\end{dgroup*}

\begin{dgroup*}
   \begin{dmath*} \cdb*{term4.301} \end{dmath*}
   \begin{dmath*} \cdb*{term4.302} \end{dmath*}
   \begin{dmath*} \cdb*{term4.303} \end{dmath*}
   \begin{dmath*} \cdb*{term4.304} \end{dmath*}
   \begin{dmath*} \cdb*{term4.305} \end{dmath*}
   \begin{dmath*} \cdb*{term4.306} \end{dmath*}
   \begin{dmath*} \cdb*{term4.307} \end{dmath*}
\end{dgroup*}

\clearpage

\begin{dgroup*}
   \begin{dmath*} g^{ab}(x) = \cdb{Metric3.301} \end{dmath*}
   \begin{dmath*} g^{ab}(x) = \cdb{Metric4.301} \end{dmath*}
   \begin{dmath*} g^{ab}(x) = \cdb{Metric5.301} \end{dmath*}
   \begin{dmath*} g^{ab}(x) = \cdb{Metric6.301} \end{dmath*}
\end{dgroup*}

\clearpage

% =================================================================================================
\section*{Stage 3: Replace partial derivs of $R$ with covariant derivs of $R$}

\begin{cadabra}
   beg_stage_3 = time.time()

   # now convert partial derivs of Rabcd to covariant derivs

   dRabcd01 = cdblib.get ('dRabcd01','dRabcd.json')  # cdb(dRabcd01.400,dRabcd01)
   dRabcd02 = cdblib.get ('dRabcd02','dRabcd.json')  # cdb(dRabcd02.400,dRabcd02)
   dRabcd03 = cdblib.get ('dRabcd03','dRabcd.json')  # cdb(dRabcd03.400,dRabcd03)

   # term1 & term2 need no special care, just a bit of tidying

   eliminate_metric (term1)   # cdb(term1.401,term1)
   sort_product     (term1)   # cdb(term1.402,term1)
   rename_dummies   (term1)   # cdb(term1.403,term1)
   canonicalise     (term1)   # cdb(term1.404,term1)

   eliminate_metric (term2)   # cdb(term2.401,term2)
   sort_product     (term2)   # cdb(term2.402,term2)
   rename_dummies   (term2)   # cdb(term2.403,term2)
   canonicalise     (term2)   # cdb(term2.404,term2)

   # replace partial derivatives of Riemann tensor in term3, term4 etc. with covariant derivatives of Rabcd

   tmp01 := @(dRabcd01).      # cdb(tmp01.403,tmp01)
   tmp02 := @(dRabcd02).      # cdb(tmp02.403,tmp02)
   tmp03 := @(dRabcd03).      # cdb(tmp03.403,tmp03)

   substitute (term3,$A^{c}A^{d}A^{e}\partial_{e}{R^{a}_{c d b}} ->   @(tmp01)$,repeat=True)         # cdb(term3.401,term3)
   substitute (term3,$A^{c}A^{d}A^{e}\partial_{e}{R^{a}_{c b d}} -> - @(tmp01)$,repeat=True)         # cdb(term3.402,term3)
   distribute (term3)                                                                                # cdb(term3.403,term3)

   substitute (term4,$A^{c}A^{d}A^{e}A^{f}\partial_{e f}{R^{a}_{c d b}} ->   @(tmp02)$,repeat=True)  # cdb(term4.401,term4)
   substitute (term4,$A^{c}A^{d}A^{e}A^{f}\partial_{e f}{R^{a}_{c b d}} -> - @(tmp02)$,repeat=True)  # cdb(term4.402,term4)
   substitute (term4,$A^{c}A^{d}A^{e}\partial_{e}{R^{a}_{c d b}} ->   @(tmp01)$,repeat=True)         # cdb(term4.403,term4)
   substitute (term4,$A^{c}A^{d}A^{e}\partial_{e}{R^{a}_{c b d}} -> - @(tmp01)$,repeat=True)         # cdb(term4.404,term4)
   distribute (term4)                                                                                # cdb(term4.405,term4)

   substitute (term5,$A^{c}A^{d}A^{e}A^{f}A^{g}\partial_{e f g}{R^{a}_{c d b}} ->   @(tmp03)$,repeat=True)
   substitute (term5,$A^{c}A^{d}A^{e}A^{f}A^{g}\partial_{e f g}{R^{a}_{c b d}} -> - @(tmp03)$,repeat=True)
   substitute (term5,$A^{c}A^{d}A^{e}A^{f}\partial_{e f}{R^{a}_{c d b}} ->   @(tmp02)$,repeat=True)
   substitute (term5,$A^{c}A^{d}A^{e}A^{f}\partial_{e f}{R^{a}_{c b d}} -> - @(tmp02)$,repeat=True)
   substitute (term5,$A^{c}A^{d}A^{e}\partial_{e}{R^{a}_{c d b}} ->   @(tmp01)$,repeat=True)
   substitute (term5,$A^{c}A^{d}A^{e}\partial_{e}{R^{a}_{c b d}} -> - @(tmp01)$,repeat=True)
   distribute (term5)

   end_stage_3 = time.time()
\end{cadabra}

\begin{dgroup*}
   \begin{dmath*} \cdb*{tmp01.403} \end{dmath*}
   \begin{dmath*} \cdb*{tmp02.403} \end{dmath*}
   \begin{dmath*} \cdb*{tmp03.403} \end{dmath*}
\end{dgroup*}

\clearpage

\begin{dgroup*}
   \begin{dmath*} \cdb*{term1.401} \end{dmath*}
   \begin{dmath*} \cdb*{term1.402} \end{dmath*}
   \begin{dmath*} \cdb*{term1.403} \end{dmath*}
   \begin{dmath*} \cdb*{term1.404} \end{dmath*}
\end{dgroup*}

\begin{dgroup*}
   \begin{dmath*} \cdb*{term2.401} \end{dmath*}
   \begin{dmath*} \cdb*{term2.402} \end{dmath*}
   \begin{dmath*} \cdb*{term2.403} \end{dmath*}
   \begin{dmath*} \cdb*{term2.404} \end{dmath*}
\end{dgroup*}

\begin{dgroup*}
   \begin{dmath*} \cdb*{term3.401} \end{dmath*}
   \begin{dmath*} \cdb*{term3.402} \end{dmath*}
   \begin{dmath*} \cdb*{term3.403} \end{dmath*}
\end{dgroup*}

\begin{dgroup*}
   \begin{dmath*} \cdb*{term4.401} \end{dmath*}
   \begin{dmath*} \cdb*{term4.402} \end{dmath*}
   \begin{dmath*} \cdb*{term4.403} \end{dmath*}
   \begin{dmath*} \cdb*{term4.404} \end{dmath*}
   \begin{dmath*} \cdb*{term4.405} \end{dmath*}
\end{dgroup*}

\clearpage

% =================================================================================================
\section*{Stage 4: Build the Taylor series for $g_{ab}$, reformatting and output}

\begin{cadabra}
   beg_stage_4 = time.time()

   # final housekeeping

   # lower the ^{ab} indices to _{uv}

   tmp0 := g_{a u} g_{b v} @(term0).
   tmp1 := g_{a u} g_{b v} @(term1).
   tmp2 := g_{a u} g_{b v} @(term2).
   tmp3 := g_{a u} g_{b v} @(term3).
   tmp4 := g_{a u} g_{b v} @(term4).
   tmp5 := g_{a u} g_{b v} @(term5).

   distribute           (tmp1)  # cdb(tmp1.501,tmp1)
   eliminate_metric     (tmp1)  # cdb(tmp1.502,tmp1)
   eliminate_kronecker  (tmp1)  # cdb(tmp1.503,tmp1)
   tmp1 = flatten_Rabcd (tmp1)
   canonicalise         (tmp1)  # cdb(tmp1.506,tmp1)

   distribute           (tmp2)  # cdb(tmp2.501,tmp2)
   eliminate_metric     (tmp2)  # cdb(tmp2.502,tmp2)
   eliminate_kronecker  (tmp2)  # cdb(tmp2.503,tmp2)
   tmp2 = flatten_Rabcd (tmp2)
   canonicalise         (tmp2)  # cdb(tmp2.506,tmp2)

   distribute           (tmp3)  # cdb(tmp3.501,tmp3)
   eliminate_metric     (tmp3)  # cdb(tmp3.502,tmp3)
   eliminate_kronecker  (tmp3)  # cdb(tmp3.503,tmp3)
   tmp3 = flatten_Rabcd (tmp3)
   canonicalise         (tmp3)  # cdb(tmp3.506,tmp3)

   distribute           (tmp4)  # cdb(tmp4.501,tmp4)
   eliminate_metric     (tmp4)  # cdb(tmp4.502,tmp4)
   eliminate_kronecker  (tmp4)  # cdb(tmp4.503,tmp4)
   tmp4 = flatten_Rabcd (tmp4)
   canonicalise         (tmp4)  # cdb(tmp4.506,tmp4)

   distribute           (tmp5)  # cdb(tmp5.501,tmp5)
   eliminate_metric     (tmp5)  # cdb(tmp5.502,tmp5)
   eliminate_kronecker  (tmp5)  # cdb(tmp5.503,tmp5)
   tmp5 = flatten_Rabcd (tmp5)
   canonicalise         (tmp5)  # cdb(tmp5.506,tmp5)

   # this is out final answer

   # raise the _{uv} indices to ^{ab}

   metric:= g^{a u} g^{b v} (  @(tmp0)
                              + (1/1) @(tmp1)
                              + (1/2) @(tmp2)
                              + (1/6) @(tmp3)
                              + (1/24) @(tmp4)
                              + (1/120) @(tmp5) ).  # cdb(metric.500,metric)

   distribute             (metric)   # cdb(metric.501,metric)
   eliminate_metric       (metric)   # cdb(metric.502,metric)
   eliminate_kronecker    (metric)   # cdb(metric.503,metric)
   metric = flatten_Rabcd (metric)   # cdb(metric.504,metric)
   canonicalise           (metric)   # cdb(metric.505,metric)

   substitute          (metric,$g_{a b} g^{b c} -> g_{a}^{c}$)
   substitute          (metric,$g_{b a} g^{b c} -> g_{a}^{c}$)
   substitute          (metric,$g_{b a} g^{c b} -> g_{a}^{c}$)
   substitute          (metric,$g_{a b} g^{c b} -> g_{a}^{c}$)
   eliminate_kronecker (metric)   # cdb(metric.506,metric)
   canonicalise        (metric)   # cdb(metric.507,metric)

   substitute (metric,$A^{a} -> x^{a}$)  # cdb (metric.508,metric)

   cdblib.create ('metric-inv.json')

   cdblib.put ('g^ab',metric,'metric-inv.json')

   # extract the terms of the metric in powers of x

   term0 = get_xterm (metric,0)   # cdb(term0.501,term0)
   term1 = get_xterm (metric,1)   # cdb(term1.501,term1)
   term2 = get_xterm (metric,2)   # cdb(term2.501,term2)
   term3 = get_xterm (metric,3)   # cdb(term3.501,term3)
   term4 = get_xterm (metric,4)   # cdb(term4.501,term4)
   term5 = get_xterm (metric,5)   # cdb(term5.501,term5)

   cdblib.put ('g^ab_0',term0,'metric-inv.json')
   cdblib.put ('g^ab_1',term1,'metric-inv.json')
   cdblib.put ('g^ab_2',term2,'metric-inv.json')
   cdblib.put ('g^ab_3',term3,'metric-inv.json')
   cdblib.put ('g^ab_4',term4,'metric-inv.json')
   cdblib.put ('g^ab_5',term5,'metric-inv.json')

   # this version of "metric" is used only in the commentary at the start of this notebook

   metric4:=@(term0) + @(term1) + @(term2) + @(term3).  # cdb(metric4.501,metric4)

\end{cadabra}

\clearpage

\begin{dgroup*}
   \begin{dmath*} \cdb*{term0.501} \end{dmath*}
   \begin{dmath*} \cdb*{term1.501} \end{dmath*}
   \begin{dmath*} \cdb*{term2.501} \end{dmath*}
   \begin{dmath*} \cdb*{term3.501} \end{dmath*}
   \begin{dmath*} \cdb*{term4.501} \end{dmath*}
   \begin{dmath*} \cdb*{term5.501} \end{dmath*}
\end{dgroup*}

\clearpage

\begin{dgroup*}
   \begin{dmath*} \cdb*{tmp2.501} \end{dmath*}
   \begin{dmath*} \cdb*{tmp2.502} \end{dmath*}
   \begin{dmath*} \cdb*{tmp2.503} \end{dmath*}
   \begin{dmath*} \cdb*{tmp2.506} \end{dmath*}
\end{dgroup*}

\begin{dgroup*}
   \begin{dmath*} \cdb*{tmp3.501} \end{dmath*}
   \begin{dmath*} \cdb*{tmp3.502} \end{dmath*}
   \begin{dmath*} \cdb*{tmp3.503} \end{dmath*}
   \begin{dmath*} \cdb*{tmp3.506} \end{dmath*}
\end{dgroup*}

\clearpage

\begin{dgroup*}
   \begin{dmath*} \cdb*{tmp4.501} \end{dmath*}
   \begin{dmath*} \cdb*{tmp4.502} \end{dmath*}
   \begin{dmath*} \cdb*{tmp4.503} \end{dmath*}
   \begin{dmath*} \cdb*{tmp4.506} \end{dmath*}
\end{dgroup*}

\clearpage

\begin{dgroup*}
   \begin{dmath*} \cdb*{tmp5.506} \end{dmath*}
\end{dgroup*}

\clearpage

\begin{dgroup*}
   \begin{dmath*} \cdb*{metric.500} \end{dmath*}
   \begin{dmath*} \cdb*{metric.501} \end{dmath*}
   \begin{dmath*} \cdb*{metric.502} \end{dmath*}
   \begin{dmath*} \cdb*{metric.503} \end{dmath*}
   \begin{dmath*} \cdb*{metric.504} \end{dmath*}
   \begin{dmath*} \cdb*{metric.505} \end{dmath*}
   \begin{dmath*} \cdb*{metric.506} \end{dmath*}
   \begin{dmath*} \cdb*{metric.507} \end{dmath*}
   \begin{dmath*} \cdb*{metric.508} \end{dmath*}
\end{dgroup*}

% =================================================================================================
% the remaining code is just for pretty printing

\clearpage

\begin{cadabra}
   Rterm0 := @(term0).
   Rterm1 := @(term1).  # zero
   Rterm2 := @(term2).
   Rterm3 := @(term3).
   Rterm4 := @(term4).
   Rterm5 := @(term5).

   Rterm0 = reformat_xterm (Rterm0,  1)    # cdb(Rterm0.601,Rterm0)
   Rterm2 = reformat_xterm (Rterm2,  3)    # cdb(Rterm2.601,Rterm2)
   Rterm3 = reformat_xterm (Rterm3,  6)    # cdb(Rterm3.601,Rterm3)
   Rterm4 = reformat_xterm (Rterm4, 60)    # cdb(Rterm4.601,Rterm4)
   Rterm5 = reformat_xterm (Rterm5, 90)    # cdb(Rterm5.601,Rterm5)

   Metric := @(Rterm0) + @(Rterm2) + @(Rterm3) + @(Rterm4) + @(Rterm5).  # cdb (Metric.601,Metric)

   scaled0 = rescale_xterm (Rterm0,  1)    # cdb(scaled0.601,scaled0)
   scaled2 = rescale_xterm (Rterm2,  3)    # cdb(scaled2.601,scaled2)
   scaled3 = rescale_xterm (Rterm3,  6)    # cdb(scaled3.601,scaled3)
   scaled4 = rescale_xterm (Rterm4, 60)    # cdb(scaled4.601,scaled4)
   scaled5 = rescale_xterm (Rterm5, 90)    # cdb(scaled5.601,scaled5)

   end_stage_4 = time.time()
\end{cadabra}

\clearpage

% =================================================================================================
\section*{The inverse metric in Riemann normal coordinates}

\begin{dgroup*}
   \begin{dmath*} g^{a b}(x) = \cdb{Metric.601}+\BigO{\eps^6} \end{dmath*}
\end{dgroup*}

\clearpage

% =================================================================================================
\section*{Curvature expansion of the inverse metric}
\begin{align*}
     g^{a b}(x) =
     \ngab{0}^{a b}
   + \ngab{2}^{a b}
   + \ngab{3}^{a b}
   + \ngab{4}^{a b}
   + \ngab{5}^{a b}+\BigO{\eps^6}
\end{align*}
\begin{dgroup*}
   \begin{dmath*}    \ngab{0}^{a b} = \cdb{scaled0.601} \end{dmath*}
   \begin{dmath*}  3 \ngab{2}^{a b} = \cdb{scaled2.601} \end{dmath*}
   \begin{dmath*}  6 \ngab{3}^{a b} = \cdb{scaled3.601} \end{dmath*}
   \begin{dmath*} 60 \ngab{4}^{a b} = \cdb{scaled4.601} \end{dmath*}
   \begin{dmath*} 90 \ngab{5}^{a b} = \cdb{scaled5.601} \end{dmath*}
\end{dgroup*}

\clearpage

% =================================================================================================
% export selected objects, these will later be imported into a library
% these are the objects that will appear in the paper

\begin{cadabra}
   cdblib.create ('metric-inv.export')

   cdblib.put ('g^ab_3',Metric3,'metric-inv.export')  # R and \partial R
   cdblib.put ('g^ab_4',Metric4,'metric-inv.export')
   cdblib.put ('g^ab_5',Metric5,'metric-inv.export')
   cdblib.put ('g^ab_6',Metric6,'metric-inv.export')

   cdblib.put ('g^ab',  Metric, 'metric-inv.export')  # R and \nabla R

   cdblib.put ('g^ab_scaled0',scaled0,'metric-inv.export')
   cdblib.put ('g^ab_scaled2',scaled2,'metric-inv.export')
   cdblib.put ('g^ab_scaled3',scaled3,'metric-inv.export')
   cdblib.put ('g^ab_scaled4',scaled4,'metric-inv.export')
   cdblib.put ('g^ab_scaled5',scaled5,'metric-inv.export')

   checkpoint.append (Metric4)
   checkpoint.append (Metric6)

   checkpoint.append (Metric)

   checkpoint.append (scaled0)
   checkpoint.append (scaled2)
   checkpoint.append (scaled3)
   checkpoint.append (scaled4)
   checkpoint.append (scaled5)

   # cdbBeg (timing)
   print ("Stage 1: {:7.1f} secs\\hfill\\break".format(end_stage_1-beg_stage_1))
   print ("Stage 2: {:7.1f} secs\\hfill\\break".format(end_stage_2-beg_stage_2))
   print ("Stage 3: {:7.1f} secs\\hfill\\break".format(end_stage_3-beg_stage_3))
   print ("Stage 4: {:7.1f} secs".format(end_stage_4-beg_stage_4))
   # cdbEnd (timing)

\end{cadabra}

\clearpage

% =================================================================================================
\section*{Timing}

\cdb{timing}

% =================================================================================================
% export checkpoints in json format

\bgroup
\CdbSetup{action=hide}
\begin{cadabra}
   for i in range( len(checkpoint) ):
      cdblib.put ('check{:03d}'.format(i),checkpoint[i],checkpoint_file)
\end{cadabra}
\egroup

\end{document}


\section{Expectation-Maximization}
\subsection{Mixture of Gaussians}
\subsection{Factor Analysis}


\documentclass{article}
\input{article-setting}
%------------------------------------------------------------------------------%
\newcommand\artversion{2.2.2.0414}
\title{Math-Symbols-in-\LaTeX{}-Manual}
\author{polossk}
\date{Version: v\artversion, Last Update: \today}
%------------------------------------------------------------------------------%
\begin{document}
%------------------------------------------------------------------------------%
\maketitle

Add \lstinline`\usepackage{math-symbols}` in your document's preamble.

And you will no longer need use other math package in most instances.

% \tableofcontents
\thispagestyle{fancy}
\renewcommand{\baselinestretch}{1.25}
%------------------------------------------------------------------------------%

%------------------------------------------------------------------------------%
\section{Constants and Useful Symbols}
%------------------------------------------------------------------------------%
\begin{tabular}{*{10}{l}}
    $\mi$    & \lstinline`\mi`  & $\mnatr$ & \lstinline`\mnatr`  & $\mcmpx$  & \lstinline`\mcmpx`  & $\mscab$      & \lstinline`\mscab`  & $\mslbg[{[a, b]}]{m}$ & \lstinline`\mslbg[{[a, b]}]{m}`  \\
    $\mj$    & \lstinline`\mj`  & $\mintg$ & \lstinline`\mintg`  & $\mhilb$  & \lstinline`\mhilb`  & $\mscon{(I)}$ & \lstinline`\mscon{(I)}` & $\mssbl[{[a, b]}]{m}$ & \lstinline`\mssbl[{[a, b]}]{m}` \\
    $\me$    & \lstinline`\me` & $\mrato$ & \lstinline`\mrato` & $\mcond$  & \lstinline`\mcond` & $\mslbg{2}$   & \lstinline`\mslbg{2}` &                                                 \\
    $1\mdeg$ & \lstinline`1\mdeg` & $\mreal$ & \lstinline`\mreal` & $\mconst$ & \lstinline`\mconst` & $\mssbl{2}$   & \lstinline`\mssbl{2}` &                                                 \\
\end{tabular}
%------------------------------------------------------------------------------%

%------------------------------------------------------------------------------%
\section{Vector and Matrix Defination}
%------------------------------------------------------------------------------%

%------------------------------------------------------------------------------%
\subsection{Vector Notations}
%------------------------------------------------------------------------------%
Use \lstinline`\mv<name>` as the abbr of ``\underline{M}ath \underline{V}ector''.

\begin{tabular}{*{12}{l}}
    $\mva$ & \lstinline`\mva` & $\mvk$ & \lstinline`\mvk` & $\mvu$ & \lstinline`\mvu` & $\mvalpha$   & \lstinline`\mvalpha` & $\mvlambda$  & \lstinline`\mvlambda` & $\mvchi$        & \lstinline`\mvchi` \\
    $\mvb$ & \lstinline`\mvb` & $\mvl$ & \lstinline`\mvl` & $\mvv$ & \lstinline`\mvv` & $\mvbeta$    & \lstinline`\mvbeta` & $\mvmu$      & \lstinline`\mvmu` & $\mvpsi$        & \lstinline`\mvpsi` \\
    $\mvc$ & \lstinline`\mvc` & $\mvm$ & \lstinline`\mvm` & $\mvw$ & \lstinline`\mvw` & $\mvgamma$   & \lstinline`\mvgamma` & $\mvnu$      & \lstinline`\mvnu` & $\mvomega$      & \lstinline`\mvomega` \\
    $\mvd$ & \lstinline`\mvd` & $\mvn$ & \lstinline`\mvn` & $\mvx$ & \lstinline`\mvx` & $\mvdelta$   & \lstinline`\mvdelta` & $\mvxi$      & \lstinline`\mvxi` & $\mvvarepsilon$ & \lstinline`\mvvarepsilon` \\
    $\mve$ & \lstinline`\mve` & $\mvo$ & \lstinline`\mvo` & $\mvy$ & \lstinline`\mvy` & $\mvepsilon$ & \lstinline`\mvepsilon` & $\mvpi$      & \lstinline`\mvpi` & $\mvvarkappa$   & \lstinline`\mvvarkappa` \\
    $\mvf$ & \lstinline`\mvf` & $\mvp$ & \lstinline`\mvp` & $\mvz$ & \lstinline`\mvz` & $\mvzeta$    & \lstinline`\mvzeta` & $\mvrho$     & \lstinline`\mvrho` & $\mvvarphi$     & \lstinline`\mvvarphi` \\
    $\mvg$ & \lstinline`\mvg` & $\mvq$ & \lstinline`\mvq` &        &                         & $\mveta$     & \lstinline`\mveta` & $\mvsigma$   & \lstinline`\mvsigma` & $\mvvarpi$      & \lstinline`\mvvarpi` \\
    $\mvh$ & \lstinline`\mvh` & $\mvr$ & \lstinline`\mvr` &        &                         & $\mvtheta$   & \lstinline`\mvtheta` & $\mvtau$     & \lstinline`\mvtau` & $\mvvarrho$     & \lstinline`\mvvarrho` \\
    $\mvi$ & \lstinline`\mvi` & $\mvs$ & \lstinline`\mvs` &        &                         & $\mviota$    & \lstinline`\mviota` & $\mvupsilon$ & \lstinline`\mvupsilon` & $\mvvartheta$   & \lstinline`\mvvartheta` \\
    $\mvj$ & \lstinline`\mvj` & $\mvt$ & \lstinline`\mvt` &        &                         & $\mvkappa$   & \lstinline`\mvkappa` & $\mvphi$     & \lstinline`\mvphi` &                                           \\
\end{tabular}
%------------------------------------------------------------------------------%

%------------------------------------------------------------------------------%
\subsection{Matrix/Tensor Notations}
%------------------------------------------------------------------------------%
Use \lstinline`\mm<name>` or \lstinline`\mt<name>` as the abbr of ``\underline{M}ath \underline{M}atrix/\underline{T}ensor''.

\begin{tabular}{*{14}{l}}
    $\mma$ & \lstinline`\mma`  & $\mmg$ & \lstinline`\mmg`  & $\mmm$ & \lstinline`\mmm`  & $\mms$ & \lstinline`\mms`  & $\mmy$ & \lstinline`\mmy` & $\mmgamma$  & \lstinline`\mmgamma`  & $\mmsigma$   & \lstinline`\mmsigma`  \\
    $\mmb$ & \lstinline`\mmb`  & $\mmh$ & \lstinline`\mmh`  & $\mmn$ & \lstinline`\mmn`  & $\mmt$ & \lstinline`\mmt`  & $\mmz$ & \lstinline`\mmz` & $\mmdelta$  & \lstinline`\mmdelta`  & $\mmupsilon$ & \lstinline`\mmupsilon`  \\
    $\mmc$ & \lstinline`\mmc`  & $\mmi$ & \lstinline`\mmi`  & $\mmo$ & \lstinline`\mmo`  & $\mmu$ & \lstinline`\mmu`  &        &                         & $\mmtheta$  & \lstinline`\mmtheta`  & $\mmphi$     & \lstinline`\mmphi`  \\
    $\mmd$ & \lstinline`\mmd`  & $\mmj$ & \lstinline`\mmj`  & $\mmp$ & \lstinline`\mmp` & $\mmv$ & \lstinline`\mmv` &        &                         & $\mmlambda$ & \lstinline`\mmlambda` & $\mmpsi$     & \lstinline`\mmpsi` \\
    $\mme$ & \lstinline`\mme` & $\mmk$ & \lstinline`\mmk` & $\mmq$ & \lstinline`\mmq` & $\mmw$ & \lstinline`\mmw` &        &                         & $\mmxi$     & \lstinline`\mmxi` & $\mmomega$   & \lstinline`\mmomega` \\
    $\mmf$ & \lstinline`\mmf` & $\mml$ & \lstinline`\mml` & $\mmr$ & \lstinline`\mmr` & $\mmx$ & \lstinline`\mmx` &        &                         & $\mmpi$     & \lstinline`\mmpi` &                                         \\
\end{tabular}
%------------------------------------------------------------------------------%

%------------------------------------------------------------------------------%
\subsection{Transposed Matrix Notations}
%------------------------------------------------------------------------------%
Use \lstinline`\mm<name>t` as the abbr of ``\underline{M}ath \underline{M}atrix \underline{T}ransposed''.

\begin{tabular}{*{12}{l}}
    $\mmat$ & \lstinline`\mmat` & $\mmht$ & \lstinline`\mmht` & $\mmot$ & \lstinline`\mmot` & $\mmvt$ & \lstinline`\mmvt` & $\mmgammat$  & \lstinline`\mmgammat` & $\mmupsilont$ & \lstinline`\mmupsilont` \\
    $\mmbt$ & \lstinline`\mmbt` & $\mmit$ & \lstinline`\mmit` & $\mmpt$ & \lstinline`\mmpt` & $\mmwt$ & \lstinline`\mmwt` & $\mmdeltat$  & \lstinline`\mmdeltat` & $\mmphit$     & \lstinline`\mmphit` \\
    $\mmct$ & \lstinline`\mmct` & $\mmjt$ & \lstinline`\mmjt` & $\mmqt$ & \lstinline`\mmqt` & $\mmxt$ & \lstinline`\mmxt` & $\mmthetat$  & \lstinline`\mmthetat` & $\mmpsit$     & \lstinline`\mmpsit` \\
    $\mmdt$ & \lstinline`\mmdt` & $\mmkt$ & \lstinline`\mmkt` & $\mmrt$ & \lstinline`\mmrt` & $\mmyt$ & \lstinline`\mmyt` & $\mmlambdat$ & \lstinline`\mmlambdat` & $\mmomegat$   & \lstinline`\mmomegat` \\
    $\mmet$ & \lstinline`\mmet` & $\mmlt$ & \lstinline`\mmlt` & $\mmst$ & \lstinline`\mmst` & $\mmzt$ & \lstinline`\mmzt` & $\mmxit$     & \lstinline`\mmxit` &                                          \\
    $\mmft$ & \lstinline`\mmft` & $\mmmt$ & \lstinline`\mmmt` & $\mmtt$ & \lstinline`\mmtt` &         &                          & $\mmpit$     & \lstinline`\mmpit` &                                          \\
    $\mmgt$ & \lstinline`\mmgt` & $\mmnt$ & \lstinline`\mmnt` & $\mmut$ & \lstinline`\mmut` &         &                          & $\mmsigmat$  & \lstinline`\mmsigmat` &                                          \\
\end{tabular}
%------------------------------------------------------------------------------%

%------------------------------------------------------------------------------%
\subsection{Special Vector and Matrix Notations}
%------------------------------------------------------------------------------%
\begin{tabular}{*{4}{l}}
    $\mvzero$ & \lstinline`\mvzero` & \lstinline`\mmzero` & \lstinline`\mtzero` \\
    $\mvone$  & \lstinline`\mvone` & \lstinline`\mmone` & \lstinline`\mtone` \\
\end{tabular}
%------------------------------------------------------------------------------%

%------------------------------------------------------------------------------%
\section{Useful Functions and Operators}
%------------------------------------------------------------------------------%
\begin{tabular}{*{12}{l}}
    $\diff$   & \lstinline`\diff` & $\eig$  & \lstinline`\eig` & $\mean$ & \lstinline`\mean` & $\card$   & \lstinline`\card` & $\dist$       & \lstinline`\dist` & \\
    $\Diff$   & \lstinline`\Diff` & $\tr$   & \lstinline`\tr` & $\var$  & \lstinline`\var` & $\argmin$ & \lstinline`\argmin` & $\rot$        & \lstinline`\rot` & \\
    $\Expect$ & \lstinline`\Expect` & $\lcm$  & \lstinline`\lcm` & $\corr$ & \lstinline`\corr` & $\argmax$ & \lstinline`\argmax` & $\curl$       & \lstinline`\curl` & \\
    $\diag$   & \lstinline`\diag` & $\rand$ & \lstinline`\rand` & $\conv$ & \lstinline`\conv` & $\argopt$ & \lstinline`\argopt` & $\divergence$ & \lstinline`\divergence` & \\
\end{tabular}
%------------------------------------------------------------------------------%

%------------------------------------------------------------------------------%
\section{Useful Aliases and Generators}
%------------------------------------------------------------------------------%
\begin{itemize}
    \item \textbf{Derivatives.} Command: \lstinline`\[d]frac(diff|partial)(s|{var1}){var2}`. \lstinline`var1` and \lstinline`var2` is numerator and denominator, respectively. \lstinline`[d]` is just like the \lstinline`\dfrac` providing a display mode. \lstinline`(diff|partial)` provides derivative or partial derivative. \lstinline`(s|{var1})` means that the numerator is skippable. For example,

          \renewcommand{\arraystretch}{2}
          \begin{tabular}{*{4}{l}}
              \toprule
              Text                     & \TeX                     & Text                      & \TeX                     \\
              \midrule
              $\fracdiff{u}{x}$        & \lstinline`\fracdiff{u}{x}` & $\dfracdiff{u}{x}$        & \lstinline`\dfracdiff{u}{x}` \\
              $\fracdiff{^2u}{x^2}$    & \lstinline`\fracdiff{^2u}{x^2}` & $\dfracdiff{^2u}{x^2}$    & \lstinline`\dfracdiff{^2u}{x^2}` \\
              $\fracdiffs{x}$          & \lstinline`\fracdiffs{x}` & $\dfracdiffs{x}$          & \lstinline`\dfracdiffs{x}` \\
              $\fracpartial{u}{x}$     & \lstinline`\fracpartial{u}{x}` & $\dfracpartial{u}{x}$     & \lstinline`\dfracpartial{u}{x}` \\
              $\fracpartial{^2u}{x^2}$ & \lstinline`\fracpartial{^2u}{x^2}` & $\dfracpartial{^2u}{x^2}$ & \lstinline`\dfracpartial{^2u}{x^2}` \\
              $\fracpartials{x}$       & \lstinline`\fracpartials{x}` & $\dfracpartials{x}$       & \lstinline`\dfracpartials{x}` \\
              \bottomrule
          \end{tabular}
          \renewcommand{\arraystretch}{1.25}

    \item \textbf{Function vaules at exact point.} Command: \lstinline`\mfwhen{var1}{var2}`. \lstinline`var1` and \lstinline`var2` is function and point position, respectively. For example, \lstinline`\mfwhen{\fracpartial{u}{t}}{x=5}` gets $\mfwhen{\fracpartial{u}{t}}{x=5}$.

    \item \textbf{Auto sized brackets.} Command: \lstinline`\mclosure{}` for \lstinline`()`, \lstinline`\mclosuresquare{}` for \lstinline`[]`, \lstinline`\mclosurebrace{}` for \lstinline`{}`. For example, $\mclosurebrace{ \mclosuresquare{ \mclosure{a^2 + b^2}^2 }^3 }$.

    \item \textbf{Vector(Sequence) generator.} Command \lstinline`\mvct[z][t]{var1}{var2}`. \lstinline`var1` and \lstinline`var2` is variable name and the last index, respectively. The index is begin from 1 in default. \lstinline`[z]` makes index begins from 0. \lstinline`[t]` makes this vector transposed into a column vector. For example,

          \begin{tabular}{*{4}{l}}
              \toprule
              Text           & \TeX                     & Text            & \TeX                     \\
              \midrule
              $\mvct{a}{n}$  & \lstinline`\mvct{a}{n}` & $\mvctz{a}{n}$  & \lstinline`\mvctz{a}{n}` \\
              $\mvctt{a}{n}$ & \lstinline`\mvctt{a}{n}` & $\mvctzt{a}{n}$ & \lstinline`\mvctzt{a}{n}` \\
              \bottomrule
          \end{tabular}

    \item \textbf{A list of equations group by a brace.} Command \lstinline`\mequlist{...}`. Also provide environment \lstinline`equlist`, which is similar with the \lstinline`cases` environment. For example, \lstinline`\mequlist{x + y &= 10 \\ 4x + 2y &= 30}` gets $\mequlist{x + y &= 10 \\ 4x + 2y &= 30}$.
\end{itemize}
%------------------------------------------------------------------------------%
\end{document}


\section{On existing voting systems}
We want to tap into the rich pool of established knowledge on voting systems, to inform about our options and guide our decisions in designing suitable algorithms. For an introductory textbook on this theory, see \cite{voting}.

\subsection{Formalization of voting systems}
(tbd specify, for which elections - 2 candidates etc - the following holds)

In this section we recall the basic established definitions and then reflect upon our needs. For the dApp-voting system, the term \textit{voters} does refer to the users of the dApp-store and \textit{candidates} does refer to the dApps available there. \\

\subsubsection{Demanded fairness properties}
Commonly, the three properties that a voting system should fulfill in order to be \textit{fair} are anonymity, neutrality and monotonicity, see pp. 3-4. in \cite{voting}. (tbd make jumping links out of this citations) For the election of one out of two possible candidates, these properties are formalized as follows.
\begin{itemize}
\item {\textbf{Anonymity:}
\footnote{This notion of anonymity is unrelated to the anonymity of a user using an app.}}
A voting system is said to be anonymous if it treats all voters equally. In other words, if any two voters trade ballots, this shouldn't change the election's outcome. \\
Concerning a dApp-voting-system, it is up for discussion in what way this property is wanted and how it should be implemented. For example, it could be sensible to have not total anonymity, but to give users who have a high reputation, which indicates their knowledge, or users who hold a large stake and therefore are likely to want the best for the platform, more voting power than others. Certainly it would establish an inequality between users if the relation between voting power on one side, and reputation or stake on the other side, was a linear one. We discuss this topic further in (tbd reference-label).
\item {\textbf{Neutrality:}} A voting system is said to be neutral if it treats all candidates equally. This means that if every voter switched their vote from one candidate to another, the outcome should change accordingly.
This point is not about the voters.\\
For dApp-rating, the neutrality property is about whether the voting-evaluation algorithm treats all the dApps that are applicable to partake in the voting round equally.
\item {\textbf{Monotonicity:}} A voting system is said to be monotone if it is impossible for a candidate to change from winning to losing by gaining additional votes and to change from losing to winning by losing votes without gaining others.
\end{itemize}

\subsubsection{Classical voting systems}
We discuss the classical voting systems together with their properties and their applicability for many of the ranking systems we previously outlined. (tbd: Which ranking systems did we outline?)
\begin{itemize}[leftmargin = 0pt]
\item {\textbf{Majority rule:}} This is the name of a voting system that elects the candidate who receives more than half of the votes, if such a candidate exists. If there is no such candidate, then majority rule results in a tie, with no winner elected.
\end{itemize}

\noindent The so-called
\href{https://en.wikipedia.org/wiki/May%27s_theorem}{\textbf{May's Theorem}}
states that majority rule (tbd see ref)
is the only voting system for two-candidate-elections that is anonymous, neutral, and monotone, and that avoids the possibility of ties. For more than two candidates this is not true, since it is not guaranteed that one of the candidates is voted for by more than half of all voters. \\
Because on the dApp-platform there will be more than two candidates, and not only a winner but a whole ranking is needed, majority rule isn't the voting system to go for.\\

(tbd \cite{Handsonapproach} The Mathematics of Voting and Elections: A Hands-On Approach. Chapter One;)\\
(tbd: quota systems)\\

\begin{itemize}[leftmargin = 0pt, nosep]
\item {\textbf{Plurality rule:}} A class of methods of which majority rule can be viewed as a special case of. It is the voting system that elects the candidate who receives the highest number of votes, even if that number is less than half of the total number of votes being cast. Here, only when two or more candidates receive the same number of votes (and more than the number of votes received by any of the other candidates) then the method does result in a tie. See \cite{voting}, pp. 5-20. (tbd ??)
\end{itemize}
\noindent Regarding a voting system for the dApp-ranking, the possibility of ties is no downside as there is no need to determine a single winner. Rather, what is needed is a system that leads to some sort of preference order of all dApps. \\

\noindent The preference order produced by this voting system is called {\textbf{societal preference order}} since it can be thought of as the ranking of the candidates that, according to the voting system being used, reflects the voters' will the best.
There are various systems that can be used to determine the societal preference order. One property of such systems that might appear sensible at first, is the following: A voting system is said to satisfy the {\textit{majority criterion}} if whenever a candidate is ranked first by a majority of the voters, that candidate will also be ranked first in the corresponding societal preference order. \\

\begin{itemize}[leftmargin = 0pt, nosep]
\item \textbf{Borda count:} One voting system that does not fulfill the majority criterion is the so-called Borda count, which uses a non-trivial {\emph{point system}} to determine the overall rankings.
It is often used in collegiate sports polls, for example. In an election with $n$ candidates it works as follows.\\
Firstly, each voter submits a ballot that contains his or her individual preference order of all the candidates.
Then points are awarded to each candidate for each ballot cast, according to the following rule:
An $m$-place rank is worth $n-m$ points (where $1\leq{m}\leq{n}$). In other words, a first-place rank is worth $n-1$ points, a second-place rank is worth $n-2$ points, and so on.
Finally the candidate whose total number of points from all of the ballots is the largest is declared the winner and the corresponding societal preference order is determined by the number of points each candidate has got from largest to smallest.
If there is more than one candidate with the largest number of points, a tie occurs.
Some sort of tie occurs in the societal preference order whenever candidates receive the same number of total points.
These candidates then occupy indistinguishable positions in the preference order and are listed consecutively.\\
See \cite{voting}, pp. 20-26. Intuitively, Borda count appears to be quite fair. However, note that it violates the majority criterion. \\
\end{itemize}

For the purpose of the dApp-voting-system, using a variation of the Borda count is more appropriate than demanding that the majority criterion is fulfilled: If we consider an extreme situation in which a small majority of users ranks a specific dApp at the top position while all other voters rank it last on their personal preference, then it would make no sense to automatically rank this dApp first in the resulting societal preference order. Determining its rank according to the Borda count seems more legitimate. Thus, we argue that a voting system for ranking dApps does not need to fulfill the majority criterion. It will not use the plurality method, but rather use a variant of Borda count to guarantee a sensible societal preference order. \\

\subsubsection{Further popular conditions on voting systems}
Taking account of personal and societal preference orders, the three properties of fair voting systems have to be redefined for elections with more than two candidates. In this definition, the second and third property now are no longer about winning or losing, but about the ranks of the candidates in the societal preference order resulting from the personal preference orders:
\begin{itemize}
\item \textbf{Anonymity:} This property stays the same.
\item \textbf{Neutrality:} A voting system is said to be neutral if it treats all candidates equally. This means that if every voter switched the positions of two specific candidates on their personal preference orders, the positions of these two candidates in the resulting societal preference order would be switched accordingly.
\item\textbf{Monotonicity:} A voting system is said to be monotone if it is impossible for a candidate to experience a decrease in rank on the resulting societal preference order whenever changes in favor of that candidate but no changes in disadvantage of that candidate, occur on individual preference ballots.
See \cite{voting}, pp. 26-27.
\end{itemize}
We will also come back to those criteria when we discuss the proposed voting algorithm at the end of this work. (tbd) \\

Two additional properties that appear to express a sensible requirement for a voting system are now presented. Therefore, two preliminary definitions are required: \\

A candidate who would defeat every other candidate in a head-to-head election under majority rule is called a {\textbf{Condorcet winner}}. \\
If a candidate would lose to every other candidate in a head-to-head contest (under majority rule), he is called a {\textbf{Condorcet loser}}.
\begin{itemize}
\item {\textbf{Condorcet winner criterion (CWC):}}
A voting system is said to satisfy the CWC, if it always elects the Condorcet winner whenever one exists.
\item {\textbf{Condorcet loser criterion (CLC):}}
A voting system is said to satisfy the CLC, if it never elects the Condorcet loser whenever one exists.
\end{itemize}
These definitions involve two-candidate-elections. It can be challenging to design a voting system with more than two candidates in a way that it fulfills at least one of the Condorcet criterions. The Borda count, for example, does not, as it violates majority rule. \\

\noindent Since the Condorcet properties clearly are valuable requirements concerning a voting system, the dApp-store-voting system should fulfil them. The so-called sequential pairwise voting, which is explained in the following lines, does and the voting system we propose at the end of this paper, turns out to do so, too.\\ (tbd: später zeigen, dass es das Kriterium erfüllt)\\

\subsection{Two more advanced voting systems}
\begin{itemize}[leftmargin = 0pt, nosep]
\item \textbf{Sequential pairwise voting:}
To determine the winner and the societal preference order according to sequential pairwise voting, at first, the voters have to choose between two candidates. Majority rule is used to decide the winner. Next, the voters have to choose between the winner of the preceding contest and the next candidate. Then they have to choose between the winner of the latter contest and the next candidate and so on, whereby the winner always is decided according to majority rule. Finally, the winner from the last two-candidate-contest is declared the winner of the whole election. \\
Though sequential pairwise voting has the benefit of always electing a Condorcet winner if one exists, it comes with great downsides. First of all, it would produce a societal preference order that doesn't have the mathematical property of transitivity and therefore would not be sensible. Furthermore, in sequential pairwise voting, an order in which new candidates are to be introduced into the head-to-head comparisons has to be specified beforehand. In elections where no Condorcet winner exists, exactly this order, called agenda, has an enormous influence on who wins the election. In other words, if there is no Condorcet winner, this system is highly manipulable and violates the fundamental property of neutrality, which is why sequential pairwise voting clearly can't be said to be a fair method. \\
(see pp. 48-57 in \cite{voting})
\item \textbf{Single transferable vote:}
Another voting system that seems sensible at first glance and is even used in the election of some government offices, is the single transferable vote system. Thereby, each voter submits his personal preference order. Then the candidates with the least number of first-place votes are eliminated from the preference orders and ranked last in the societal preference order, while all remaining candidates are moved up. Then again, those candidates with the smallest number of first-place votes are eliminated and so on, until only one candidate remains and is declared the winner. \\
This system is somehow manipulable, too, since the participation of one ore more additional candidates can change the resulting societal preference order in a way that the ranking of the other candidates gets interchanged and therefore a candidate who wouldn't get elected without the participation of the additional ones, wins the election. The property of I.I.A., which is discussed in the following, targets to avoid this problem.
\end{itemize}

\subsection{Arrow's impossibility theorem}
Another criterion that is related to the assessment of the utility and sensibility of a voting system is the {\textbf{Independence of Irrelevant Alternatives - criterion (IIA)}}, which is defined as follows: \\
A voting system is said to satisfy the IIA, if the societal preference between any two candidates is only dependent on the individual voters' preferences between those two candidates. I.e. it is not affected by the candidacy of any other candidate.
However, none of the voting systems discussed so far satisfies this criterion. \\

In fact, there is no voting system that has the properties of being monotone, anonymous and neutral and is also satisfying I.I.A., as the so-called
\href{https://en.wikipedia.org/wiki/Arrow%27s_impossibility_theorem}{\textbf{Arrow's impossibility theorem}},
declares. \\
\noindent Before this theorem can be desribed more precisely, it has to be expressed in mathematical terms, what a voting system is: \\
\noindent One can consider a voting system to be a rule that assigns to each possible collection of preference orders for a poll some kind of societal preference order. More concretely, this rule is defined as a function that takes as input a collection of transitive preference orders of all the voters and produces as output a transitive societal preference order that represents the will of the electorate. \\
\noindent This definition does not rule out the possibility of ties, neither ties in individual preference ballots nor ties in the resulting societal preference orders. So if one defines the societal preference order of pairwise sequential voting as the winner followed by a tie of all the other candidates, even pairwise sequential voting fits in with that defintion of a voting system.
The mathematical conditions Arrow had in mind can be interpreted as follows: \\

(tbd)
	from the voting book, page 68;
	andere Kriterien auf Wikipedia:
	(tbd hidden link)%https://en.wikipedia.org/wiki/Kenneth_Arrow,
	(tbd hidden link)%https://en.wikipedia.org/wiki/Arrow%27s_impossibility_theorem
	(tbd hidden link)%https://plato.stanford.edu/entries/ arrows-theorem/
Arrow's theorem	(tbd hidden link)%shttp://pi.math.cornell.edu/~mec/Summer2008/anema/maystheorem.html

\begin{enumerate}
\item Universality: Voting systems should place no restrictions apart from transitivity on how voters can rank the candidates in an election. There should be no kind of dictatorship presetting that only specific preference orders are acceptable or are not. Every possible collection of transitive preference ballots must yield a transitive societal preference order.
\item Positive Association of Social and Individual Values: Voting systems should be monotone.
\item Independence of Irrelevant Alternatives: Voting systems should satisfy the IIA - criterion.
\item Citizen Sovereignty: Voting systems should not be imposed in any way. I.e., there should never be a pair of candidates in an election such that one of these candidates is preferred over or tied with the other in the resulting societal preference order in defiance of any vote.
\item Nondictatorship: Voting systems should not be dictatorial. I.e., there should never be a voter such that, for any pair of candidates, if that voter prefers one of the candidates over the other, then society will also have the same preference order regarding these two candidates.
\end{enumerate}
The second condition had been called monotonicity so far. The third one is the one we introduced before. The fourth condition is close to neutrality and the fifth is similar to anonymity.
The first of these conditions is one that we haven't stated before, but which we have been assuming anyways. \\
However, according to the first condition a voting system must always output a transitive societal preference order, but some potential voting systems - e.g. sequential pairwise voting - yield cyclic societal preference orders when receiving certain inputs. So one could postulate that only systems which output transitive societal preference orders are called voting systems by definition or one could handle the problem with systems of this kind by excluding inputs that yield preferential orders which are not transitive through restrictions. The latter option then in some way would violate universality. \\
What Kenneth arrow discovered is the following: For an election with three or more candidates, it is impossible for a voting system to satisfy all five of the conditions above. (tbd we have a sentence above this lines above - also, why is this told as a story?) \\
In other words, there is no "perfect" voting system for polls with more than two candidates, at least one sensible condition always will be violated. But there is a great variety of interpretations of Arrow's Theorem, what it really means and how it should be viewed in light of the search for a voting system that is truly fair.
One of these is Pareto's Unanimity condition, which replaces the conditions of Positive Association of Social and Individual Values and Citizen Sovereignty. It postulates that if there is a pair of candidates in an election such that every voter prefers the same one over the other, then that one should be ranked higher than the other in the resulting societal preference order.
Since the holding true of Unanimity implies that Positive Association of Social and Individual Values and Citizen Sovereignty also are fulfilled, one can formulate a stronger form aof Arrow's Theorem: \\
For an election with more than two candidates, a voting system can't satisfy Universality, Independence of Irrelevant Alternatives, Nondictatorship and Unanimity all at once. \\

This stronger version is easier to prove. In order to do so, the following Lemma is needed: \\

Assume having an electin with three or more candidates and a voting system that satisfies universality, IIA and unanimity. Suppose that A is a candidate in the election and that every voter ranks A either first or last on their individual preference order (whereby some can rank him first and some last, not all have to rank him the same; furthermore this assumption excludes ties between A and any other candidate). Then the societal preference order the voting system yields, must also rank A either first or last. \\

Proof: % TODO: rethink it
\begin{enumerate}
\item If A was neither ranked alone first nor last in the societal preference order, there would have to be some other candidates B and C, so that B was ranked higher than or tied with A, and C was ranked lower than or tied with A in the societal preference order.
Due to universality, transitivity holds and so B would be ranked higher than C or would be tied with him. \\

\item Furthermore, if the assumption of the Lemma holds and every voter changed the position of C above B in their personal preference order, the societal preference between A and B as well as A and C wouldn't be affected since A was ranked highest or lowest and thus the relation between A and B as well as A and C wouldn't change. Due to unanimity, we know that C would be ranked higher than B in the societal preference order then, too.

\item So we get the contradiction that (1) says that B was ranked higher than or tied with C and (2) says that C would be ranked higher than B. Clearly, both relations can't be true at once, so it's not possible that the voting system yields a societal preference order in which A is ranked neither first nor last. So the Lemma is proven.
\end{enumerate}

We will prove the strong form of Arrow's theorem by assuming that universality, IIA and unanimity hold and showing that the system can't be non-dictatorial under this assumption by finding a dictator. To do so, we assume without loss of generality that A is ranked last by all of the voters (and therefore is ranked last in the societal preference order, too). The voters are labeled $v_1, \cdots, v_n$. \\
If some of the voters changed A from last place to first place on their individual preference orders, according to the Lemma above A then is either still ranked last or ranked first. But if all of the voters changed A from last place to first place, A would definitely be ranked first in the corresponding societal preference order. \\
Therefore we know that if the voters changed their ranking of A from last to first one by one, there has to be one voter, $v_k, 1\leq k \leq n$, whose change in the individual preference order causes A to switch from last place to first place in the societal preference order. Thus, this voter is a potential dictator. \\
We show know $v_k$ controls the societal preference between any pair of candidates not including B.
Let B and C be any two candidates other than A and assume that $v_k$ prefers B over C.
If $v_k$ moved A between B and C on his individual preference order, this would change nothing in the societal preference between B and C. Neither would a movement of A to the top of their individual preference orders by $v_1, \cdots, v_{k-1}$ and a movement of A to the bottom of their individual preference orders by $v_k, \cdots, v_n$ would not either. \\
Assume that all of these three changes occur. Then B would be ranked lower than A by $v_1, \cdots, v_{k-1}$ and higher than A by $v_k, \cdots, v_n$. Since we already know that $v_k$ would have yet to change his ranking of A from bottom to top in order to yield a societal preference order in which A were ranked first instead of last, clearly B would be preferred over A in the societal preference order resulting after the three changes. With a similar argumentation, it becomes obvious that A would be preferred over C in that societal preference order. Due to transitivity, B would be preferred over C in the societal preference order. \\
Since we observed before that the three changes yield no change in the corresponding societal preference order, we now also know, that B would be preferred over C in the societal preference order corresponding to the individual rankings before the three changes. \\
 % S. 86, Q 5.14

% maybe add instant runoff (p 48-50) though it violates monotonicity and CWC
% TODO: majority criterion ergänzen

%https://en.wikipedia.org/wiki/Social_Choice_and_Individual_Values

%TODO: May's theorem

%%@Alex
%%
%% plz don't use German in this text (also comments).
%%It is harder to read for outsiders and also a problem when you want to to grammar correction.
%%
%% And I propose to do line breaks after sentences to make the diff be easier to read.
%% (At the very latest after the dot, possibly every 80 chars, even.)
%% If you do a line break without \\, it will be ignored in the formatted text anyway.

{\color{blue}{
\begin{verbatim}
##### Voting system criteria

https://wiki.electorama.com/wiki/Category:Voting_system_criteria
%%TODO:
%% move wikipedia links to references

###### Features for classifications of voting systems
* Plurality voting
* Instant-runoff voting

### Popular voting systems
##### First-past-the-post voting/Winner takes it all
- Voters indicate on a ballot the candidate of their choice, and the candidate who receives the most votes wins.
- If there are at least two positions two be filled, each voter casts (up to) the same number of votes as there are positions to be filled, and those elected are the highest-placed candidates corresponding to that number of positions.
- (huge downside: it very much encourages tactical voting)
- https://en.wikipedia.org/wiki/First-past-the-post_voting

##### Majority judgement
- Used to determine a single winner.
- Voters grade each candidate in one of several ranks, for instance named from "excellent" to "bad", and the candidate with the highest median grade is the winner.
- The system's inventors mathematically proved that the system was the most "strategy-resistant" and therefore somehow immune to tactical voting.
- The algorithm we propose is also based on the median grade.
https://en.wikipedia.org/wiki/Majority_judgment

##### Approval voting
- Usually used to determine a single winner.
- Each voter may select any number of candidates. The winner is the candidate who is selected ("approved") most often.
- Variation: each voter may only select a predetermined number of candidates, otherwise this person's cast votes are invalid.
- The algorithm we propose also allows each candidate to evaluate an arbitrary number of candidates, but it is far from being some sort of approval voting.
https://www.electology.org/approval-voting
https://de.wikipedia.org/wiki/Wahl_durch_Zustimmung

##### Closed list voting
- Used when positions are to be filled by members of the running parties.
- Closed list voting: The voters only can vote for the parties. The elected parties have full decision over who of their members get the positions.
In praxis, the order in which a party's list candidates get elected can also be predetermined by districts. Then the voting system is called a "local list" system.

- These systems aren't of any use for our considerations.
- https://en.wikipedia.org/wiki/Closed_list; https://en.wikipedia.org/wiki/Party-list_proportional_representation

#### Preferential voting/Preference voting:
May refer to different election systems or groups of election systems. Some authors consider preferentially to be one of the characteristics by which electoral systems can be evaluated and classified.
Preferential voting may, for example, refer to ranked voting methods/ordinal voting systems, i.e. all election methods that involve ranking candidates in order of preference in a hierarchy on the ordinal scale, the most important ones being instant-runoff voting, single transferable vote and the Borda count.
instant-runoff voting
range voting/score voting
open list
bucklin voting

##### Score voting/rate voting
- Used to determine a single winner.
- Voters rate candidates on a scale. The candidate with the highest rating wins.
- Variations of score voting can use a score-style ballot to elect multiple candidates simultaneously.

%%TODOTODOTODO:
%%comparison to majority judgement, approval voting and bucklin voting (similarities/differences)

##### Instant-runoff voting
Used in single-seat elections with more than two candidates
Voters rank all of the candidates in their personal order of preference
The candidate with the fewest first-choice-votes is eliminated. If there is more than one candidate with the fewest first-choice-votes, the second-choice-votes of these candidates are taken into consideration and so on in order to eliminate only one candidate per voting round.
In the last voting round there are only two candidates left. The one who gets a majority of first-choice-votes wins the election.
Variations: There are a few variations of Instant-runoff voting. For example, a candidate could be considered the winner as soon as he/she has a majority of first-choice-votes even though there are more than two candidates left.
Downside for our purpose: well known (old) dApps are far too hard to be taken over

#### Open list voting
Voters have at least some influence on the order in which a party's candidates are elected. (Example: The candidates are the party's members. Each party has a rank of their members. If a party's candidate reaches a certain quota of the votes, he gets the position even if he's not at the top of the party's list.)
Open list describes a certain family of voting systems for elections in which multiple candidates are elected through allocations to an electoral listing. What this family has in common is that voters have at least some influence on the order in which a party's candidates are elected.
In "relatively closed" list systems, a candidate must get a full quota of votes to win a seat. There are various quotas that could be considered for this purpose.
In "more open" list systems, that quota is so low that it's possible that more of a party's candidates achieve the quota than the total number of seats won by the party. Therefore it should be constituted in advance whether the party's list ranking or the total number of each candidates' votes takes precedence if this happens.
In the "most open" list system, the total number of votes each candidate has received utterly determines the election result.
In a "free list" system/panachage electors even have more power over which candidates are elected than in the systems above, because each elector is given as many votes as there are seats to be filled and is allowed to cast more than one vote to the very same candidate.
https://en.wikipedia.org/wiki/Open_list; https://en.wikipedia.org/wiki/Party-list_proportional_representation

##### Bucklin voting/The Grand Junction System:
- Usually used to determine a single winner.
- Each voter ranks the candidates in ascending order, the first one being the favourite and the last one being the worst candidate.
- To evaluate the voting's, at first the prime rank is considered. Each candidate gains a score as high as the number of voters that ranked him first. If a candidate's total votes reach a majority (i.e. more than half of the number of voters), this candidate is the winner of the election. If not, the second rank is taken into consideration.
- The number of votes each candidate received at the second rank is added to the number of votes from the first rank. If a candidates number of votes reaches the majority (i.e. more than half of the number of voters), this candidate wins the election. Otherwise the procedure continues until a candidate with a majority vote is found. The winner then is the candidate with the most votes accumulated.
https://en.wikipedia.org/wiki/Bucklin_voting
https://de.wikipedia.org/wiki/Bucklin-Wahl
https://www.youtube.com/watch?v=CkIYZsJAvNQ

#### Ranked voting/Ordinal voting systems
Ranked voting describes certain voting systems in which voters rank outcomes in a hierarchy on the ordinal scale (ordinal voting systems).

#### cardinal voting systems

\end{verbatim}
}}%% end color

{\color{green}{\begin{verbatim}
https://de.wikipedia.org/wiki/Majority_Judgment
https://www.electology.org/score-voting
https://en.wikipedia.org/wiki/Score_voting

https://en.wikipedia.org/wiki/Instant-runoff_voting (todo)
https://en.wikipedia.org/wiki/Open_list
https://en.wikipedia.org/wiki/Preferential_voting (todo)

https://en.wikipedia.org/wiki/Ranked_voting (todo)
%%TODO:
%% move wikipedia links to references
\end{verbatim}}}%% end color


\documentclass[12pt]{article}
\input{physics1}
\begin{document}

\section*{NYU Physics I---numerical integration}

The question here is: How long does it take for an object to fall
$10\,\m$ near the surface of the Earth in the absence of air
resistance?  You will need to perform numerical integrations
throughout this course, so we begin by solving the problem that way.

\paragraph{\theproblem}\refstepcounter{problem}%
Choose a partner, obtain a sheet of notebook paper and
put your names on it.  Start a table with 21 rows and four columns for
four variables $t$, $a$, $v$, and $x$.

\paragraph{\theproblem}\refstepcounter{problem}%
In the $t$ column, put in times $0.0\,\s$, $0.1\,\s$, $0.2\,\s$,
\ldots, $2.0\,\s$.  In the $a$ column, put $-9.8\,\mpss$ in all 21
rows.

\paragraph{\theproblem}\refstepcounter{problem}%
In the first entry of the $v$ column, put $0.0\,\mps$.  In each
subsequent row $i+1$ put in for the $v$ entry $v_{i+1}$:
\begin{equation}
v_{i+1}= v_i + a_i\,\Delta t = v_i + a_i\,\left[t_{i+1}-t_i\right] \quad .
\end{equation}
Do that for all 20 subsequent rows.  Keep ``sufficient'' accuracy as
you go. Use a phone or calculator; no need to do this calculating by hand!

\paragraph{\theproblem}\refstepcounter{problem}%
In the first entry of the $x$ column, put $10.0\,\m$.  In each
subsequent row $i+1$ put in for the $x$ entry $x_{i+1}$:
\begin{equation}
x_{i+1}= x_i + v_i\,\Delta t = x_i + v_i\,\left[t_{i+1}-t_i\right] \quad .
\end{equation}
Do that for all 20 subsequent rows.  Keep ``sufficient'' accuracy as
you go.

\paragraph{\theproblem}\refstepcounter{problem}%
(Answer this and the following parts on your sheet of paper, below the
table or on the other side.)  Does the object get to $x=0\,\m$ within
the time span in your table?  If it does, make an estimate of the time
$t$ at which the object gets to $x=0\,\m$.

\paragraph{\theproblem}\refstepcounter{problem}%
Do you expect your answer to be an overestimate or underestimate of
the true time obtained by an analytic calculation?  Give a written
explanation.

\paragraph{\theproblem}\refstepcounter{problem}%
Do you recall this equation?
\begin{equation}
x = x_0 + v_0\,t + \frac{1}{2}\,a\,t^2
\end{equation}
Use this to compute the true time it takes the object to fall
$10\,\m$.  Were you correct in your expectation?  How far off was your
numerical answer?

\paragraph{\theproblem}\refstepcounter{problem}%
Name two things you could have done to make your integration more
accurate.

\end{document}