galgebra.tex
1 \documentclass[12pt]{report} 2 % setup the page geometry for landscape and use maximum screen real estate 3 %\usepackage[dvips]{geometry,graphicx,color} 4 5 \usepackage{listings} 6 \usepackage{parskip} 7 \usepackage[pdftex]{geometry,graphicx,color} 8 %\usepackage{bm} 9 \usepackage{amsmath} 10 \usepackage{mathtools} 11 \usepackage{tensor} 12 \usepackage{bbding} 13 \usepackage{comment} 14 \usepackage{tensor} 15 \usepackage{amsfonts} 16 \usepackage{srcltx} 17 \usepackage{amssymb} 18 \usepackage{pdfpages} 19 \usepackage{rotating} 20 \usepackage{setspace} 21 \usepackage{sectsty} 22 \usepackage{eufrak} 23 \usepackage{makecell} 24 \usepackage{longtable} 25 \usepackage{scrextend} 26 \usepackage[makeroom]{cancel} 27 \usepackage[hyphens]{url} 28 \DeclareGraphicsExtensions{.pdf} 29 \definecolor{LinkColor} {rgb} {0, 0, .8} 30 \allowdisplaybreaks 31 \geometry{headsep=2.0em,hscale=0.80} 32 \newcommand{\galgebra}{\mbox{$\mathcal{G\!A}$\hspace{.01in}\bf{lgebra}}} 33 \newcommand{\bm}[1]{\boldsymbol{#1}} 34 \newcommand{\ubh}{\bm{\hat{u}}} 35 \newcommand{\ebh}{\bm{\hat{e}}} 36 \newcommand{\ebf}{\bm{e}} 37 \newcommand{\mat}[1]{\left [ {#1} \right ]} 38 \newcommand{\bra}[1]{{#1}_{\mathcal{G}}} 39 \newcommand{\ket}[1]{{#1}_{\mathcal{D}}} 40 \newcommand{\ds}{\displaystyle} 41 \definecolor{red}{rgb}{1,0,0} 42 \definecolor{gray}{rgb}{0.95,0.95,0.95} 43 \setlength{\parindent}{0in} 44 \usepackage{sectsty} 45 \usepackage[colorlinks=true, linkcolor=LinkColor, citecolor=black, urlcolor=blue]{hyperref} 46 \usepackage[utf8]{inputenc} 47 \usepackage{fancybox} 48 49 \makeatletter 50 \newenvironment{CenteredBox}{% 51 \begin{Sbox}}{% Save the content in a box 52 \end{Sbox}\centerline{\parbox{\wd\@Sbox}{\TheSbox}}}% And output it centered 53 \makeatother 54 55 \sectionfont{\large} 56 %\titlespacing*{\section}{0pt}{6pt}{3pt} 57 \title{\galgebra: \bf\Large a Geometric Algebra Module for \emph{Sympy}} 58 \author{\bf Alan Bromborsky\\ 59 \bf Army Research Lab (Retired)\\ 60 \bf abrombo@verizon.net} 61 62 \newcommand{\bfrac}[2]{\displaystyle\frac{#1}{#2}} 63 \newcommand{\lp}{\left (} 64 \newcommand{\rp}{\right )} 65 \newcommand{\half}{\frac{1}{2}} 66 \newcommand{\llt}{\left <} 67 \newcommand{\rgt}{\right >} 68 \newcommand{\abs}[1]{\left |{#1}\right |} 69 \newcommand{\pdiff}[2]{\bfrac{\partial {#1}}{\partial {#2}}} 70 \newcommand{\pdifftwo}[3]{\bfrac{\partial^{2} {#1}}{\partial {#2}\partial {#3}}} 71 \newcommand{\lbrc}{\left \{} 72 \newcommand{\rbrc}{\right \}} 73 \newcommand{\set}[1]{\lbrc {#1} \rbrc} 74 \newcommand{\W}{\wedge} 75 \newcommand{\R}{\dagger} 76 \newcommand{\lbrk}{\left [} 77 \newcommand{\rbrk}{\right ]} 78 \newcommand{\com}[1]{\lbrk {#1} \rbrk} 79 \newcommand{\proj}[2]{\llt {#1} \rgt_{#2}} 80 %\newcommand{\bm}{\boldsymbol} 81 \newcommand{\braces}[1]{\left \{ {#1} \right \}} 82 \newcommand{\grade}[1]{\left < {#1} \right >} 83 \newcommand{\f}[2]{{#1}\lp {#2} \rp} 84 \newcommand{\paren}[1]{\lp {#1} \rp} 85 \newcommand{\eval}[2]{\left . {#1} \right |_{#2}} 86 \newcommand{\prm}[1]{{#1}'} 87 \newcommand{\ddt}[1]{\bfrac{d{#1}}{dt}} 88 \newcommand{\deriv}[3]{\bfrac{d^{#3}#1}{d{#2}^{#3}}} 89 \newcommand{\be}{\begin{equation}} 90 \newcommand{\ee}{\end{equation}} 91 \newcommand{\eb}{\bm{e}} 92 \newcommand{\ehb}{\bm{\hat{e}}} 93 \newcommand{\Tn}[2]{\f{\mathcal{T}_{#2}}{#1}} 94 \newcommand{\tr}{\mbox{tr}} 95 \newcommand{\T}[1]{\texttt{#1}} 96 \newcommand{\grd}{\bm{\nabla}} 97 98 99 \lstset{ 100 language=Python, 101 showstringspaces=false, 102 formfeed=\newpage, 103 tabsize=4, 104 commentstyle=\itshape, 105 basicstyle=\ttfamily, 106 numbers=left, 107 numberstyle=\tiny, 108 numbersep=5pt, 109 morekeywords={models, lambda, forms} 110 } 111 112 \newcommand{\includecode}[1]{\lstinputlisting[language=Python, caption=#1, escapechar=none]{#1}} 113 \newcommand{\notebox}[1]{\begin{center}\fbox{\parbox{6in}{#1}}\end{center}} 114 \newcommand{\warningbox}[1]{\color{red}\begin{center}\fbox{\parbox{6in}{#1}}\end{center}\color{black}} 115 \begin{document} 116 117 \parskip 10pt 118 119 \maketitle 120 {\bf Introduction}\newline 121 122 \begin{center} 123 \includegraphics[scale=0.25]{images/dhestenes.jpg} \begin{tabular}{c} 124 \includegraphics[scale=0.25]{images/wkclifford.jpg} \\ 125 \emph{William Kindom Clifford} 126 \end{tabular} 127 \end{center} 128 129 This document describes the implementation, installation and use of a 130 geometric algebra module written in 131 python that utilizes the \emph{sympy} symbolic algebra library. The python 132 module ga has been developed for coordinate free calculations using 133 the operations (geometric, outer, and inner products etc.) of geometric algebra. 134 The operations can be defined using a completely arbitrary metric defined 135 by the inner products of a set of arbitrary vectors or the metric can be 136 restricted to enforce orthogonality and signature constraints on the set of 137 vectors. Additionally, a metric that is a function of a coordinate set can 138 be defined so that a geometric algebra over a manifold can be implemented. 139 Geometric algebras over submanifolds of the base manifold are also supported as 140 well as linear multivector differential operators and linear transformations. 141 In addition the module includes the geometric, outer (curl) and inner 142 (div) derivatives. The module requires the \emph{sympy} module and the numpy module for numerical linear 143 algebra calculations. For \LaTeX\ output a \LaTeX\ distribution and pdf viewer must be installed. If the 144 user is interested in using geometric algebra for strictly numerical purposes I would recommend using the 145 \emph{glucat} C++ templates which have a python wrapper for python users (\url{http://glucat.sourceforge.net/}). 146 147 148 \tableofcontents 149 150 \chapter{Installation on Linux, Windows, and Mac} 151 152 \section{Install python} 153 The \T{galgebra} python module, which is an implementation of geometric algebra in python has two 154 perquisites for a minimal installation, python and \T{sympy}. For the python language we have the 155 following situation\footnote{Currently \T{galgebra} supports python versions 2.7+, but not versions 3.0+ of python.}. 156 \begin{center} 157 \begin{tabular}{cl} 158 os & \multicolumn{1}{c}{python installation} \vspace{5pt} \\ \hline 159 linux & \parbox{4in}{\vspace{5pt} Comes with all versions of linux\vspace{5pt}} \\ \hline 160 windows & \parbox{4in}{\vspace{5pt}To install python on windows go to \url{https://www.python.org/downloads/windows/} and install version 161 appropriate for you version of windows. If you wish a more complete/advanced installation go to 162 \url{https://code.google.com/p/pythonxy/}\vspace{5pt}.}\\ \hline 163 mac & \parbox{4in}{\vspace{5pt}Basic version comes with OSX. For better installation go to 164 \url{http://docs.python-guide.org/en/latest/starting/install/osx/}\vspace{5pt}.} \\ \hline 165 \end{tabular} 166 \end{center} 167 \section{Install sympy} 168 For \T{sympy} there are two alternatives for installation. 169 \begin{center} 170 \begin{tabular}{cl} 171 mode & \multicolumn{1}{c}{method} \vspace{5pt} \\ \hline 172 latest release & \parbox{4in}{\vspace{5pt}Go to \url{https://github.com/sympy/sympy/releases} and select 173 option appropriate for your system. Note that if you have \emph{pip} 174 (see \url{https://pip.pypa.io/en/latest/installing.html}) installed you can install 175 the latest release by entering the command ``\T{pip sympy}.'' \vspace{5pt}} \\ \hline 176 development version & \parbox{4in}{\vspace{5pt}Go to \url{https://github.com/sympy/sympy} and download zipped archive. 177 Unzip archive. Open terminal/command line in top directory of unzipped 178 archive. For linux or osx run ``\T{sudo python setup.py install}.'' For windows run 179 ``\T{python setup.py install}'' from the command line.\vspace{5pt}} \\ \hline 180 \end{tabular} 181 \end{center} 182 The method for the development version is preferred since that method always builds \T{sympy} with the python system you have 183 installed on your system (32-bits verses 64-bits and particular python version you are running). 184 \section{Install galgebra} 185 Since you are reading this document you have already obtained a copy of \T{galgebra}. If you wish to obtain the very latest 186 version (assuming you have not already done this) go to \url{https://github.com/brombo/galgebra} and download and extract the 187 zipped archive. 188 189 Then with whatever version you are using open a terminal/command line in the \T{galgebra} directory that is in the top directory 190 of the archive. If you are in the correct the directory it should contain the python program \T{setgapth.py}. If you are in 191 linux or osx run the program with the command ``\T{sudo python setgapth.py},'' if in windows use ``\T{python setgapth.py}.'' 192 193 This program creates the file \T{Ga.pth} in the correct directory to simplify importing the \T{galgebra} modules into your python 194 programs. The modules you will use for programming with geometric algebra/calculus are \T{ga}, \T{mv}, \T{lt}, and 195 \T{printer}\footnote{All these modules are in the same directory as \T{setgapth.py}.}. To import any of these modules into your 196 program, say \T{mv}, you only have to enter in the program \T{import mv}. It does not matter where the program file is located. 197 198 \section{{\LaTeX} Options} 199 In order to use the latex output of the \T{galgebra} modules (excluding latex output from \emph{Ipython notebook}) you must install 200 a latex distribution. Directions follow if you do not already have {\LaTeX} installed.\footnote{In order for \T{galgebra} to output 201 latex formatted pdf files your distribution of latex must have \T{pdflatex} installed.} 202 \begin{center} 203 \begin{tabular}{cl} 204 os & \multicolumn{1}{c}{latex installation} \vspace{5pt} \\ \hline 205 linux & \parbox{4in}{\vspace{5pt} Open a terminal and run ``\T{sudo apt-get texlive-full install}''. It takes about half an hour 206 to install.\vspace{5pt}} \\ \hline 207 windows & \parbox{4in}{\vspace{5pt}Go to \url{http://miktex.org/download} (other downloads). Download a net installer. 208 Install a full version of \emph{MikTex}.\vspace{5pt}}\\ \hline 209 mac & \parbox{4in}{\vspace{5pt}Go to \url{http://www.tug.org/mactex/} and follow instructions to install 210 \emph{MacTeX}.\vspace{5pt}} \\ \hline 211 \end{tabular} 212 \end{center} 213 \section{``Ipython notebook'' Options} 214 To use \emph{ipython notebook} with \T{galgebra} it must be installed. To install \emph{ipython notebook} do the following. 215 216 Google ``get-pip.py'' and click on the first entry ``get-pip.py''. Then follow the instructions to download ``get-pip.py''. 217 Open a terminal/command line in the directory of the download and execute \T{python get-pip.py} for windows or \T{sudo python get-pip.py} 218 for linux. The reason for install \emph{pip} in this manner is that it insures the correct settings for the version of 219 python you are using. Then run in a terminal/command line 220 \T{pip install "ipython[notebook]"}. If you have already installed \emph{ipython notebook} you should enter 221 \T{pip install "ipython[notebook]" --upgrade} to make sure you have the latest version. Linux and OSX users will have to 222 use \T{sudo} with the commands. The version of \emph{ipython notebook} we are using is \textbf{jupyter} and that should be 223 shown when the notebook is started. 224 225 Note that to correctly print latex from \emph{ipython notebook} one must use the \T{Format()} function from the \emph{printer} 226 module. Go to the section on latex printing for more information. 227 228 \section{The ANSI Console} 229 230 The \T{printer} module of \T{galgebra} contains the class \T{Eprint} which is described in section~(\ref{stdprint}). This function uses 231 the capabilities of the ansi console (terminal) for enhanced multivector printing where multivector bases, sympy functions and derivatives 232 are printed in different colors. The ansi console is native to Linux and OSX (which is really Unix under the hood), but not windows. 233 The best available free substitute for 234 the ansi console on windows is \emph{ConEmu}. The web page for ConEmu is \url{http://conemu.github.io/}. In order to install \emph{ConEmu} 235 download the appropriate version of the \emph{ConEmu} installer (exe file) for your system (32 bit or 64 bit) from the website and and execute it. Instructions for using \emph{ConEmu} are given in section~(\ref{stdprint}). 236 237 \section{Geany Programmers Editor} 238 239 \emph{Geany} is a very nice \emph{free} programmers editor that work well with \emph{python}. From within \emph{geany} you can execute a 240 \emph{python} program. The \emph{galgebra} printing system is setup so that you can display the program output on an ansi terminal or if 241 you are using the \LaTeX options has the terminal launch a \emph{pdf} browser to view the \LaTeX output. To install \emph{geany} on 242 Linux use the command line ``\T{sudo apt-get install geany}'', on Windows go to \url{http://www.geany.org/Download/Releases} or to install 243 \emph{geany} in OSX go to \url{http://wiki.geany.org/howtos/osx/running}. 244 245 \chapter{What is Geometric Algebra?} 246 247 \section{Basics of Geometric Algebra} 248 249 Geometric algebra is the Clifford algebra of a real finite dimensional vector 250 space or the algebra that results when the vector space 251 is extended with a product of vectors (geometric product) that is associative, 252 left and right distributive, and yields a real number for the square (geometric 253 product) of any vector \cite{Hestenes}, \cite{Doran}. The elements of the geometric 254 algebra are called multivectors and consist of the linear combination of 255 scalars, vectors, and the geometric product of two or more vectors. The 256 additional axioms for the geometric algebra are that for any vectors $a$, 257 $b$, and $c$ in the base vector space (\cite{Doran},p85): 258 259 \begin{equation} 260 \begin{array}{c} 261 a\lp bc \rp = \lp ab \rp c \\ 262 a\lp b+c \rp = ab+ac \\ 263 \lp a + b \rp c = ac+bc \\ 264 aa = a^{2} \in \Re. 265 \end{array} 266 \end{equation} 267 268 If the dot (inner) product of two vectors is defined by (\cite{Doran},p86) 269 270 \begin{equation} 271 a\cdot b \equiv (ab+ba)/2, 272 \end{equation} 273 274 then we have 275 276 \begin{align} 277 c &= a+b \\ 278 c^{2} &= (a+b)^{2} \\ 279 c^{2} &= a^{2}+ab+ba+b^{2} \\ 280 a\cdot b &= (c^{2}-a^{2}-b^{2})/2 \in \Re 281 \end{align} 282 283 Thus $a\cdot b$ is real. The objects generated from linear combinations 284 of the geometric products of vectors are called multivectors. If a basis for 285 the underlying vector space are the vectors $\set{\eb_{1},\dots,\eb_{n}}$ (we use 286 boldface $\eb$'s to denote basis vectors) 287 a complete basis for the geometric algebra is given by the scalar $1$, the vectors $\eb_{1},\dots,\eb_{n}$ 288 and all geometric products of vectors 289 290 \begin{equation} 291 \eb_{i_{1}}\eb_{i_{2}}\dots \eb_{i_{r}} \mbox{ where } 0\le r \le n\mbox{, }0 \le i_{j} \le n \mbox{ and } i_{1}<i_{2}<\dots<i_{r} 292 \end{equation} 293 294 Each base of the complete basis is represented by a non-commutative symbol (except for the scalar 1) 295 with name $\eb_{i_{1}}\dots \eb_{i_{r}}$ so that the general multivector $\bm{A}$ is represented by 296 ($A$ is the scalar part of the multivector and the $A^{i_{1},\dots,i_{r}}$ are scalars) 297 298 \begin{equation} 299 \bm{A} = A + \sum_{r=1}^{n}\sum_{\substack{i_{1},\dots,i_{r}\\ 0\le i_{j}<i_{j+1} \le n}} 300 A^{i_{1},\dots,i_{r}}\eb_{i_{1}}\eb_{i_{2}}\dots \eb_{r} 301 \end{equation} 302 303 The critical operation in setting up the geometric algebra is reducing 304 the geometric product of any two bases to a linear combination of bases so that 305 we can calculate a multiplication table for the bases. Since the geometric 306 product is associative we can use the operation (by definition for two vectors 307 $a\cdot b \equiv (ab+ba)/2$ which is a scalar) 308 309 \begin{equation}\label{reduce} 310 \eb_{i_{j+1}}\eb_{i_{j}} = 2\eb_{i_{j+1}}\cdot \eb_{i_{j}} - \eb_{i_{j}}\eb_{i_{j+1}} 311 \end{equation} 312 313 These processes are repeated until every basis list in $\bm{A}$ is in normal 314 (ascending) order with no repeated elements. As an example consider the 315 following 316 317 \begin{align} 318 \eb_{3}\eb_{2}\eb_{1} &= (2(\eb_{2}\cdot \eb_{3}) - \eb_{2}\eb_{3})\eb_{1} \\ 319 &= 2\paren{\eb_{2}\cdot \eb_{3}}\eb_{1} - \eb_{2}\eb_{3}\eb_{1} \\ 320 &= 2\paren{\eb_{2}\cdot \eb_{3}}\eb_{1} - \eb_{2}\paren{2\paren{\eb_{1}\cdot \eb_{3}}-\eb_{1}\eb_{3}} \\ 321 &= 2\paren{\paren{\eb_{2}\cdot \eb_{3}}\eb_{1}-\paren{\eb_{1}\cdot \eb_{3}}\eb_{2}}+\eb_{2}\eb_{1}\eb_{3} \\ 322 &= 2\paren{\paren{\eb_{2}\cdot \eb_{3}}\eb_{1}-\paren{\eb_{1}\cdot \eb_{3}}\eb_{2}+ 323 \paren{\eb_{1}\cdot \eb_{2}}\eb_{3}}-\eb_{1}\eb_{2}\eb_{3} 324 \end{align} 325 326 which results from repeated application of eq.~(\ref{reduce}). If the product of basis vectors contains repeated factors 327 eq.~(\ref{reduce}) can be used to bring the repeated factors next to one another so that if $\eb_{i_{j}} = \eb_{i_{j+1}}$ 328 then $\eb_{i_{j}}\eb_{i_{j+1}} = \eb_{i_{j}}\cdot \eb_{i_{j+1}}$ which is a scalar that commutes with all the terms in the product 329 and can be brought to the front of the product. Since every repeated pair of vectors in a geometric product of $r$ factors 330 reduces the number of non-commutative factors in the product by $r-2$. The number of bases in the multivector algebra is $2^{n}$ 331 and the number containing $r$ factors is ${n\choose r}$ which is the number of combinations or $n$ things 332 taken $r$ at a time (binomial coefficient). 333 334 The other construction required for formulating the geometric algebra is the outer or wedge product (symbol $\W$) of $r$ 335 vectors denoted by $a_{1}\W\dots\W a_{r}$. The wedge product of $r$ vectors is called an $r$-blade and is defined 336 by (\cite{Doran},p86) 337 338 \begin{equation} 339 a_{1}\W\dots\W a_{r} \equiv \sum_{i_{j_{1}}\dots i_{j_{r}}} \epsilon^{i_{j_{1}}\dots i_{j_{r}}}a_{i_{j_{1}}}\dots a_{i_{j_{1}}} 340 \end{equation} 341 342 where $\epsilon^{i_{j_{1}}\dots i_{j_{r}}}$ is the contravariant permutation symbol which is $+1$ for an even permutation of the 343 superscripts, $0$ if any superscripts are repeated, and $-1$ for an odd permutation of the superscripts. From the definition 344 $a_{1}\W\dots\W a_{r}$ is antisymmetric in all its arguments and the following relation for the wedge product of a vector $a$ and an 345 $r$-blade $B_{r}$ can be derived 346 347 \begin{equation}\label{wedge} 348 a\W B_{r} = (aB_{r}+(-1)^{r}B_{r}a)/2 349 \end{equation} 350 351 Using eq.~(\ref{wedge}) one can represent the wedge product of all the basis vectors 352 in terms of the geometric product of all the basis vectors so that one can solve (the system 353 of equations is lower diagonal) for the geometric product of all the basis vectors in terms of 354 the wedge product of all the basis vectors. Thus a general multivector $\bm{B}$ can be 355 represented as a linear combination of a scalar and the basis blades. 356 357 \begin{equation} 358 \bm{B} = B + \sum_{r=1}^{n}\sum_{i_{1},\dots,i_{r},\;\forall\; 0\le i_{j} \le n} B^{i_{1},\dots,i_{r}}\eb_{i_{1}}\W \eb_{i_{2}}\W\dots\W \eb_{r} 359 \end{equation} 360 361 Using the blades $\eb_{i_{1}}\W \eb_{i_{2}}\W\dots\W \eb_{r}$ creates a graded 362 algebra where $r$ is the grade of the basis blades. The grade-$r$ 363 part of $\bm{B}$ is the linear combination of all terms with 364 grade $r$ basis blades. 365 366 \subsection{Grade Projection} 367 368 The scalar part of $\bm{B}$ is defined to 369 be grade-$0$. Now that the blade expansion of $\bm{B}$ is defined 370 we can also define the grade projection operator $\proj{\bm{B}}{r}$ by 371 372 \begin{equation} 373 \proj{\bm{B}}{r} = \sum_{i_{1},\dots,i_{r},\;\forall\; 0\le i_{j} \le n} B^{i_{1},\dots,i_{r}}\eb_{i_{1}}\W \eb_{i_{2}}\W\dots\W \eb_{r} 374 \end{equation} 375 376 and 377 378 \begin{equation} 379 \proj{\bm{B}}{} \equiv \proj{\bm{B}}{0} = B 380 \end{equation} 381 382 \subsection{Multivector Products} 383 384 Then if $\bm{A}_{r}$ is an $r$-grade multivector and $\bm{B}_{s}$ is an $s$-grade multivector we have 385 386 \begin{equation} 387 \bm{A}_{r}\bm{B}_{s} = \proj{\bm{A}_{r}\bm{B}_{s}}{\abs{r-s}}+\proj{\bm{A}_{r}\bm{B}_{s}}{\abs{r-s}+2}+\cdots 388 \proj{\bm{A}_{r}\bm{B}_{s}}{r+s} 389 \end{equation} 390 391 and define (\cite{Hestenes},p6) 392 393 \begin{align} 394 \bm{A}_{r}\W\bm{B}_{s} &\equiv \proj{\bm{A}_{r}\bm{B}_{s}}{r+s} \\ 395 \bm{A}_{r}\cdot\bm{B}_{s} &\equiv \braces{ \begin{array}{cc} 396 r\mbox{ and }s \ne 0: & \proj{\bm{A}_{r}\bm{B}_{s}}{\abs{r-s}} \\ 397 r\mbox{ or }s = 0: & 0 \end{array}} 398 \end{align} 399 400 where $\bm{A}_{r}\cdot\bm{B}_{s}$ is called the dot or inner product of 401 two pure grade multivectors. For the case of two non-pure grade multivectors 402 403 \begin{align} 404 \bm{A}\W\bm{B} &= \sum_{r,s}\proj{\bm{A}}{r}\W\proj{\bm{B}}{{s}} \\ 405 \bm{A}\cdot\bm{B} &= \sum_{r,s\ne 0}\proj{\bm{A}}{r}\cdot\proj{\bm{B}}{{s}} 406 \end{align} 407 408 Two other products, the left ($\rfloor$) and right ($\lfloor$) contractions, are defined by 409 410 \begin{align} 411 \bm{A}\lfloor\bm{B} &\equiv \sum_{r,s}\braces{\begin{array}{cc} \proj{\bm{A}_r\bm{B}_{s}}{r-s} & r \ge s \\ 412 0 & r < s \end{array}} \\ 413 \bm{A}\rfloor\bm{B} &\equiv \sum_{r,s}\braces{\begin{array}{cc} \proj{\bm{A}_{r}\bm{B}_{s}}{s-r} & s \ge r \\ 414 0 & s < r\end{array}} 415 \end{align} 416 417 \subsection{Reverse of Multivector} 418 419 A final operation for multivectors is the reverse. If a multivector $\bm{A}$ is the geometric product of $r$ vectors (versor) 420 so that $\bm{A} = a_{1}\dots a_{r}$ the reverse is defined by 421 422 \begin{align} 423 \bm{A}^{\R} \equiv a_{r}\dots a_{1} 424 \end{align} 425 426 where for a general multivector we have (the the sum of the reverse of versors) 427 428 \begin{equation} 429 \bm{A}^{\R} = A + \sum_{r=1}^{n}(-1)^{r(r-1)/2}\sum_{i_{1},\dots,i_{r},\;\forall\; 0\le i_{j} \le n} A^{i_{1},\dots,i_{r}}\eb_{i_{1}}\W \eb_{i_{2}}\W\dots\W \eb_{r} 430 \end{equation} 431 432 note that if $\bm{A}$ is a versor then $\bm{A}\bm{A}^{\R}\in\Re$ and ($AA^{\R} \ne 0$) 433 434 \begin{equation} 435 \bm{A}^{-1} = \bfrac{\bm{A}^{\R}}{\bm{AA}^{\R}} 436 \end{equation} 437 438 The reverse is important in the theory of rotations in $n$-dimensions. If 439 $R$ is the product of an even number of vectors and $RR^{\R} = 1$ 440 then $RaR^{\R}$ is a composition of rotations of the vector $a$. 441 If $R$ is the product of two vectors then the plane that $R$ defines 442 is the plane of the rotation. That is to say that $RaR^{\R}$ rotates the 443 component of $a$ that is projected into the plane defined by $a$ and 444 $b$ where $R=ab$. $R$ may be written 445 $R = e^{\frac{\theta}{2}U}$, where $\theta$ is the angle of rotation 446 and $U$ is a unit blade $\lp U^{2} = \pm 1\rp$ that defines the 447 plane of rotation. 448 449 \subsection{Reciprocal Frames} 450 451 If we have $M$ linearly independent vectors (a frame), 452 $a_{1},\dots,a_{M}$, then the reciprocal frame is 453 $a^{1},\dots,a^{M}$ where $a_{i}\cdot a^{j} = \delta_{i}^{j}$, 454 $\delta_{i}^{j}$ is the Kronecker delta (zero if $i \ne j$ and one 455 if $i = j$). The reciprocal frame is constructed as follows: 456 457 \begin{equation} 458 E_{M} = a_{1}\W\dots\W a_{M} 459 \end{equation} 460 461 \begin{equation} 462 E_{M}^{-1} = \bfrac{E_{M}}{E_{M}^{2}} 463 \end{equation} 464 465 Then 466 467 \begin{equation} 468 a^{i} = \lp -1\rp^{i-1}\lp a_{1}\W\dots\W \breve{a}_{i} \W\dots\W a_{M}\rp E_{M}^{-1} 469 \end{equation} 470 471 where $\breve{a}_{i}$ indicates that $a_{i}$ is to be deleted from 472 the product. In the standard notation if a vector is denoted with a subscript 473 the reciprocal vector is denoted with a superscript. The set of reciprocal vectors 474 will be calculated if a coordinate set is given when a geometric algebra is instantiated since 475 they are required for geometric differentiation when the \T{Ga} member function \T{Ga.mvr()} 476 is called to return the reciprocal basis in terms of the basis vectors. 477 478 \section{Manifolds and Submanifolds}\label{sect_manifold} 479 480 A $m$-dimensional vector manifold\footnote{By the manifold embedding theorem any $m$-dimensional 481 manifold is isomorphic to a $m$-dimensional vector manifold}, $\mathcal{M}$, is defined by a 482 coordinate tuple (tuples are indicated by the vector accent ``$\vec{\;\;\;}$'') 483 \be 484 \vec{x} = \paren{x^{1},\dots,x^{m}}, 485 \ee 486 and the differentiable mapping ($U^{m}$ is an $m$-dimensional subset of $\Re^{m}$) 487 \be 488 \f{\bm{e}^{\mathcal{M}}}{\vec{x}}\colon U^{m}\subseteq\Re^{m}\rightarrow \mathcal{V}, 489 \ee 490 where $\mathcal{V}$ is a vector space with an inner product\footnote{This product in not necessarily positive definite.} ($\cdot$) and is of $\f{\dim}{\mathcal{V}} \ge m$. 491 492 Then a set of basis vectors for the tangent space of $\mathcal{M}$ at $\vec{x}$, $\Tn{\mathcal{M}}{\vec{x}}$, are 493 \be 494 \bm{e}_{i}^{\mathcal{M}} = \pdiff{\bm{e}^{\mathcal{M}}}{x^{i}} 495 \ee 496 and 497 \be 498 \f{g_{ij}^{\mathcal{M}}}{\vec{x}} = \bm{e}_{i}^{\mathcal{M}}\cdot\bm{e}_{j}^{\mathcal{M}}. 499 \ee 500 A $n$-dimensional ($n\le m$) submanifold $\mathcal{N}$ of $\mathcal{M}$ is defined by a coordinate tuple 501 \be 502 \vec{u} = \paren{u^{1},\dots,u^{n}}, 503 \ee 504 and a differentiable mapping 505 \be\label{eq_79} 506 \f{\vec{x}}{\vec{u}}\colon U^{n}\subseteq\Re^{n}\rightarrow U^{m}\subseteq\Re^{m}, 507 \ee 508 which induces a mapping 509 \be 510 \f{\bm{e}^{\mathcal{M}}}{\f{\vec{x}}{\vec{u}}}\colon U^{n}\subseteq\Re^{n}\rightarrow \mathcal{V}. 511 \ee 512 Then the basis vectors for the tangent space $\Tn{\mathcal{N}}{\vec{u}}$ are 513 (using $\f{\eb^{\mathcal{N}}}{\vec{u}} = \f{\eb^{\mathcal{M}}}{\f{\vec{x}}{\vec{u}}}$ and the chain rule)\footnote{In 514 this section and all following sections we are using the Einstein summation convention unless otherwise stated.} 515 \be 516 \f{\bm{e}_{i}^{\mathcal{N}}}{\vec{u}} = \pdiff{\f{\bm{e}^{\mathcal{N}}}{\vec{u}}}{u^{i}} 517 = \pdiff{\f{\bm{e}^{\mathcal{M}}}{\vec{x}}}{x^{j}}\pdiff{x^{j}}{u^{i}} 518 = \f{\bm{e}_{j}^{\mathcal{M}}}{\f{\vec{x}}{\vec{u}}}\pdiff{x^{j}}{u^{i}}, 519 \ee 520 and 521 \be\label{eq_81} 522 \f{g_{ij}^{\mathcal{N}}}{\vec{u}} = \pdiff{x^{k}}{u^{i}}\pdiff{x^{l}}{u^{j}} 523 \f{g_{kl}^{\mathcal{M}}}{\f{\vec{x}}{\vec{u}}}. 524 \ee 525 Going back to the base manifold, $\mathcal{M}$, note that the mapping 526 $\f{\bm{e}^{\mathcal{M}}}{\vec{x}}\colon U^{n}\subseteq\Re^{n}\rightarrow \mathcal{V}$ allows us to calculate an unnormalized pseudo-scalar 527 for $\Tn{\mathcal{M}}{\vec{x}}$, 528 \be 529 \f{I^{\mathcal{M}}}{\vec{x}} = \f{\bm{e}_{1}^{\mathcal{M}}}{\vec{x}} 530 \W\dots\W\f{\bm{e}_{m}^{\mathcal{M}}}{\vec{x}}. 531 \ee 532 With the pseudo-scalar we can define a projection operator from $\mathcal{V}$ 533 to the tangent space of $\mathcal{M}$ by 534 \be 535 \f{P_{\vec{x}}}{\bm{v}} = (\bm{v}\cdot \f{I^{\mathcal{M}}}{\vec{x}}) 536 \paren{\f{I^{\mathcal{M}}}{\vec{x}}}^{-1} \;\forall\; \bm{v}\in\mathcal{V}. 537 \ee 538 In fact for each tangent space $\Tn{\mathcal{M}}{\vec{x}}$ we can define a geometric algebra 539 $\f{\mathcal{G}}{\Tn{\mathcal{M}}{\vec{x}}}$ with pseudo-scalar $I^{\mathcal{M}}$ so that if 540 $A \in \f{\mathcal{G}}{\mathcal{V}}$ then 541 \be 542 \f{P_{\vec{x}}}{A} = \paren{A\cdot \f{I^{\mathcal{M}}}{\vec{x}}} 543 \paren{\f{I^{\mathcal{M}}}{\vec{x}}}^{-1} 544 \in \f{\mathcal{G}}{\Tn{\mathcal{M}}{\vec{x}}}\;\forall\; 545 A \in \f{\mathcal{G}}{\mathcal{V}} 546 \ee 547 and similarly for the submanifold $\mathcal{N}$. 548 549 If the embedding $\f{\bm{e}^{\mathcal{M}}}{\vec{x}}\colon U^{n}\subseteq\Re^{n}\rightarrow \mathcal{V}$ is not given, 550 but the metric tensor $\f{g_{ij}^{\mathcal{M}}}{\vec{x}}$ is given the geometric algebra of the 551 tangent space can be constructed. Also the derivatives of the basis vectors of the tangent space can 552 be calculated from the metric tensor using the Christoffel symbols, $\f{\Gamma_{ij}^{k}}{\vec{u}}$, where the derivatives of the basis vectors are given by 553 \be 554 \pdiff{\bm{e}_{j}^{\mathcal{M}}}{x^{i}} =\f{\Gamma_{ij}^{k}}{\vec{u}}\bm{e}_{k}^{\mathcal{M}}. 555 \ee 556 If we have a submanifold, $\mathcal{N}$, defined by eq.~(\ref{eq_79}) we can calculate the metric of 557 $\mathcal{N}$ from eq.~(\ref{eq_81}) and hence construct the geometric algebra and calculus of the 558 tangent space, $\Tn{\mathcal{N}}{\vec{u}}\subseteq \Tn{\mathcal{M}}{\f{\vec{x}}{\vec{u}}}$. 559 560 \textbf{If the base manifold is normalized (use the hat symbol to denote normalized tangent vectors, 561 $\hat{\bm{e}}_{i}^{\mathcal{M}}$, and the resulting metric tensor, $\hat{g}_{ij}^{\mathcal{M}}$) we have 562 $\hat{\bm{e}}_{i}^{\mathcal{M}}\cdot\hat{\bm{e}}_{i}^{\mathcal{M}} = \pm 1$ and $\hat{g}_{ij}^{\mathcal{M}}$ does not posses enough 563 information to calculate $g_{ij}^{\mathcal{N}}$. In that case we need to know $g_{ij}^{\mathcal{M}}$, the 564 metric tensor of the base manifold before normalization. Likewise, for the case of a vector 565 manifold unless the mapping, $\f{\bm{e}^{\mathcal{M}}}{\vec{x}}\colon U^{m}\subseteq\Re^{m}\rightarrow \mathcal{V}$, is 566 constant the tangent vectors and metric tensor can only be normalized after the fact (one cannot have a 567 mapping that automatically normalizes all the tangent vectors).} 568 569 \section{Geometric Derivative} 570 571 The directional derivative of a multivector field $\f{F}{x}$ is defined by ($a$ is a vector and $h$ is a scalar) 572 \be\label{eq_50} 573 \paren{a\cdot\nabla_{x}}F \equiv \lim_{h\rightarrow 0}\bfrac{\f{F}{x+ah}-\f{F}{x}}{h}. 574 \ee 575 Note that $a\cdot\nabla_{x}$ is a scalar operator. It will give a result containing only those grades 576 that are already in $F$. $\paren{a\cdot\nabla_{x}}F$ is the best linear approximation of $\f{F}{x}$ 577 in the direction $a$. Equation~(\ref{eq_50}) also defines the operator $\nabla_{x}$ which for 578 the basis vectors, $\set{\bm{e}_{i}}$, has the representation (note that the $\set{\bm{e}^{j}}$ are reciprocal 579 basis vectors) 580 \begin{equation} 581 \nabla_{x} F = \bm{e}^{j}\bfrac{\partial F}{\partial x^{j}} 582 \end{equation} 583 If $F_{r}$ is a $r$-grade multivector (if the independent vector, $x$, is obvious we suppress it in the 584 notation and just write $\nabla$) and 585 $F_{r} = F_{r}^{i_{1}\dots i_{r}}\bm{e}_{i_{1}}\W\dots\W \bm{e}_{i_{r}}$ 586 then 587 \begin{equation} 588 \nabla F_{r} = \bfrac{\partial F_{r}^{i_{1}\dots i_{r}}}{\partial x^{j}}\bm{e}^{j}\lp\bm{e}_{i_{1}}\W 589 \dots\W \bm{e}_{i_{r}} \rp 590 \end{equation} 591 Note that 592 $\bm{e}^{j}\lp\bm{e}_{i_{1}}\W\dots\W \bm{e}_{i_{r}} \rp$ 593 can only contain grades $r-1$ and $r+1$ so that $\nabla F_{r}$ 594 also can only contain those grades. For a grade-$r$ multivector 595 $F_{r}$ the inner (div) and outer (curl) derivatives are 596 597 \begin{equation} 598 \nabla\cdot F_{r} = \left < \nabla F_{r}\right >_{r-1} = \bm{e}^{j}\cdot \pdiff{F_{r}}{x^{j}} 599 \end{equation} 600 601 and 602 603 \begin{equation} 604 \nabla\W F_{r} = \left < \nabla F_{r}\right >_{r+1} = \bm{e}^{j}\W \pdiff{F_{r}}{x^{j}} 605 \end{equation} 606 607 For a general multivector function $F$ the inner and outer derivatives are 608 just the sum of the inner and outer derivatives of each grade of the multivector 609 function. 610 611 \subsection{Geometric Derivative on a Manifold} 612 613 In the case of a manifold the derivatives of the $\bm{e}_{i}$'s are functions of the coordinates, 614 $\set{x^{i}}$, so that the geometric derivative of a $r$-grade multivector field is 615 \begin{align} 616 \nabla F_{r} &= \bm{e}^{i}\pdiff{F_{r}}{x^{i}} = \bm{e}^{i}\pdiff{}{x^{i}} 617 \paren{F_{r}^{i_{1}\dots i_{r}}\bm{e}_{i_{1}}\W\dots\W\bm{e}_{i_{r}}} \nonumber \\ 618 &= \pdiff{F_{r}^{i_{1}\dots i_{r}}}{x^{i}}\bm{e}^{i}\paren{\bm{e}_{i_{1}}\W\dots\W\bm{e}_{i_{r}}} 619 +F_{r}^{i_{1}\dots i_{r}}\bm{e}^{i}\pdiff{}{x^{i}}\paren{\bm{e}_{i_{1}}\W\dots\W\bm{e}_{i_{r}}} 620 \end{align} 621 where the multivector functions $\bm{e}^{i}\pdiff{}{x^{i}}\paren{\bm{e}_{i_{1}}\W\dots\W\bm{e}_{i_{r}}}$ are the 622 connection for the manifold.\footnote{We use the Christoffel symbols of the first kind 623 to calculate the derivatives of the basis vectors and the product rule to 624 calculate the derivatives of the basis blades where (\url{http://en.wikipedia.org/wiki/Christoffel_symbols}) 625 \begin{equation*} 626 \Gamma_{ijk} = \half \paren{\pdiff{g_{jk}}{x^{i}}+\pdiff{g_{ik}}{x^{j}}-\pdiff{g_{ij}}{x^{k}}}, 627 \end{equation*} 628 and 629 \begin{equation*} 630 \pdiff{\eb_{j}}{x^{i}} = \Gamma_{ijk}\eb^{k}. 631 \end{equation*} 632 The Christoffel symbols of the second kind, 633 \begin{equation*} 634 \Gamma_{ij}^{k} = \half g^{kl}\paren{\pdiff{g_{li}}{x^{j}}+\pdiff{g_{lj}}{x^{i}}-\pdiff{g_{ij}}{x^{l}}}, 635 \end{equation*} 636 could also be used to calculate the derivatives in term of the original basis vectors, but since we need to calculate the 637 reciprocal basis vectors for the geometric derivative 638 it is more efficient to use the symbols of the first kind.} 639 640 The directional (material/convective) derivative, $\paren{v\cdot\nabla}F_{r}$ is given by 641 \begin{align} 642 \paren{v\cdot\nabla} F_{r} &= v^{i}\pdiff{F_{r}}{x^{i}} = v^{i}\pdiff{}{x^{i}} 643 \paren{F_{r}^{i_{1}\dots i_{r}}\bm{e}_{i_{1}}\W\dots\W\bm{e}_{i_{r}}} \nonumber \\ 644 &= v^{i}\pdiff{F_{r}^{i_{1}\dots i_{r}}}{x^{i}}\paren{\bm{e}_{i_{1}}\W\dots\W\bm{e}_{i_{r}}} 645 +v^{i}F_{r}^{i_{1}\dots i_{r}}\pdiff{}{x^{i}}\paren{\bm{e}_{i_{1}}\W\dots\W\bm{e}_{i_{r}}}, 646 \end{align} 647 so that the multivector connection functions for the directional derivative are 648 $\pdiff{}{x^{i}}\paren{\bm{e}_{i_{1}}\W\dots\W\bm{e}_{i_{r}}}$. Be careful and note that 649 $\paren{v\cdot\nabla} F_{r} \ne v\cdot \paren{\nabla F_{r}}$ since the dot and geometric products are 650 not associative with respect to one another ($v\cdot\nabla$ is a scalar operator). 651 652 \subsection{Normalizing Basis for Derivatives} 653 654 The basis vector set, $\set{\bm{e}_{i}}$, is not in general normalized. We define a normalized set of basis 655 vectors, $\set{\bm{\hat{e}}_{i}}$, by 656 657 \begin{equation} 658 \bm{\hat{e}}_{i} = \bfrac{\bm{e}_{i}}{\sqrt{\abs{\bm{e}_{i}^{2}}}} = \bfrac{\bm{e}_{i}}{\abs{\bm{e}_{i}}}. 659 \end{equation} 660 661 This works for all $\bm{e}_{i}^{2} \neq 0$. Note that $\bm{\hat{e}}_{i}^{2} = \pm 1$. 662 663 Thus the geometric derivative for a set of normalized basis vectors is (where 664 $F_{r} = F_{r}^{i_{1}\dots i_{r}} \bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{r}}$ and [no summation] 665 $\hat{F}_{r}^{i_{1}\dots i_{r}} = F_{r}^{i_{1}\dots i_{r}} \abs{\bm{\hat{e}}_{i_{1}}}\dots\abs{\bm{\hat{e}}_{i_{r}}}$). 666 \be 667 \nabla F_{r} = \eb^{i}\pdiff{F_{r}}{x^{i}} = 668 \pdiff{F_{r}^{i_{1}\dots i_{r}}}{x^{i}}\bm{e}^{i} 669 \paren{\bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{r}}} 670 +F_{r}^{i_{1}\dots i_{r}}\bm{e}^{i}\pdiff{}{x^{i}} 671 \paren{\bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{r}}}. 672 \ee 673 To calculate $\bm{e}^{i}$ in terms of the $\bm{\hat{e}}_{i}$'s we have 674 \begin{align} 675 \bm{e}^{i} &= g^{ij}\bm{e}_{j} \nonumber \\ 676 \bm{e}^{i} &= g^{ij}\abs{\bm{e}_{j}}\bm{\hat{e}}_{j}. 677 \end{align} 678 This is the general (non-orthogonal) formula. If the basis vectors are orthogonal then (no summation over repeated indexes) 679 \begin{align} 680 \bm{e}^{i} &= g^{ii}\abs{\bm{e}_{i}}\bm{\hat{e}}_{i} \nonumber \\ 681 \bm{e}^{i} &= \bfrac{\abs{\bm{e}_{i}}}{g_{ii}}\bm{\hat{e}}_{i} = \bfrac{\abs{\bm{\hat{e}}_{i}}}{\bm{e}_{i}^{2}}\bm{\hat{e}}_{i}. 682 \end{align} 683 Additionally, one can calculate the connection of the normalized basis as follows 684 \begin{align} 685 \pdiff{\paren{\abs{\bm{e}_{i}}\bm{\hat{e}}_{i}}}{x^{j}} =& \pdiff{\bm{e}_{i}}{x^{j}}, \nonumber \\ 686 \pdiff{\abs{\bm{e}_{i}}}{x^{j}}\bm{\hat{e}}_{i} 687 +\abs{\bm{e}_{i}}\pdiff{\bm{\hat{e}}_{i}}{x^{j}} =& \pdiff{\bm{e}_{i}}{x^{j}}, \nonumber \\ 688 \pdiff{\bm{\hat{e}}_{i}}{x^{j}} =& \bfrac{1}{\abs{\bm{e}_{i}}}\paren{\pdiff{\bm{e}_{i}}{x^{j}} 689 -\pdiff{\abs{\bm{e}_{i}}}{x^{j}}\bm{\hat{e}}_{i}},\nonumber \\ 690 =& \bfrac{1}{\abs{\bm{e}_{i}}}\pdiff{\bm{e}_{i}}{x^{j}} 691 -\bfrac{1}{\abs{\bm{e}_{i}}}\pdiff{\abs{\bm{e}_{i}}}{x^{j}}\bm{\hat{e}}_{i},\nonumber \\ 692 =& \bfrac{1}{\abs{\bm{e}_{i}}}\pdiff{\bm{e}_{i}}{x^{j}} 693 -\bfrac{1}{2g_{ii}}\pdiff{g_{ii}}{x^{j}}\bm{\hat{e}}_{i}, 694 \end{align} 695 where $\pdiff{\bm{e}_{i}}{x^{j}}$ is expanded in terms of the $\bm{\hat{e}}_{i}$'s. 696 697 \subsection{Linear Differential Operators}\label{ldops} 698 699 First a note on partial derivative notation. We shall use the following notation for a partial derivative where 700 the manifold coordinates are $x_{1},\dots,x_{n}$: 701 \be\label{eq_66a} 702 \bfrac{\partial^{j_{1}+\cdots+j_{n}}}{\partial x_{1}^{j_{1}}\dots\partial x_{n}^{j_{n}}} = \partial_{j_{1}\dots j_{n}}. 703 \ee 704 If $j_{k}=0$ the partial derivative with respect to the $k^{th}$ coordinate is not taken. If $j_{k} = 0$ for all 705 $1 \le k \le n$ then the partial derivative operator is the scalar one. If we consider a partial derivative where the $x$'s are 706 not in normal order such as 707 \begin{equation*} 708 \bfrac{\partial^{j_{1}+\cdots+j_{n}}}{\partial x_{i_{1}}^{j_{1}}\dots\partial x_{i_{n}}^{j_{n}}}, 709 \end{equation*} 710 and the $i_{k}$'s are not in ascending order. The derivative can always be put in the form in eq~(\ref{eq_66a}) since the order 711 of differentiation does not change the value of the partial derivative (for the smooth functions we are considering). 712 Additionally, using our notation the product of two partial derivative operations is given by 713 \be 714 \partial_{i_{1}\dots i_{n}}\partial_{j_{1}\dots j_{n}} = \partial_{i_{1}+j_{1},\dots, i_{n}+j_{n}}. 715 \ee 716 717 A general general multivector linear differential operator is a linear combination of multivectors and partial derivative operators 718 denoted by 719 \be\label{eq_66b} 720 D \equiv D^{i_{1}\dots i_{n}}\partial_{i_{1}\dots i_{n}}. 721 \ee 722 Equation~(\ref{eq_66b}) is the normal form of the differential operator in that the partial derivative operators are written to the right 723 of the multivector coefficients and do not operate upon the multivector coefficients. 724 The operator of eq~(\ref{eq_66b}) can operate on mulitvector functions, returning a multivector function via the following definitions. 725 726 727 $F$ as 728 \be\label{eq_67a} 729 D\circ F = D^{j_{1}\dots j_{n}}\circ\partial_{j_{1}\dots j_{n}}F, 730 \ee 731 or 732 \be\label{eq_68a} 733 F\circ D = \partial_{j_{1}\dots j_{n}}F\circ D^{j_{1}\dots j_{n}}, 734 \ee 735 where the $D^{j_{1}\dots j_{n}}$ are multivector functions and $\circ$ is any of the multivector multiplicative operations. 736 737 Equations~(\ref{eq_67a}) and (\ref{eq_68a}) are not the most general multivector linear differential operators, the most general would be 738 \be 739 \f{D}{F} = \f{D^{j_{1}\dots j_{n}}}{\partial_{j_{1}\dots j_{n}}F}, 740 \ee 741 where $\f{D^{j_{1}\dots j_{n}}}{}$ are linear multivector functionals. 742 743 The definition of the sum of two differential operators is obvious since any multivector operator, $\circ$, is a bilinear operator 744 $\paren{\paren{D_{A}+D_{B}}\circ F = D_{A}\circ F+D_{B}\circ F}$, the product of two differential operators $D_{A}$ and $D_{B}$ operating on a multivector function $F$ is defined to be ($\circ_{1}$ and $\circ_{2}$ are any two multivector multiplicative operations) 745 \begin{align*} 746 \paren{D_{A}\circ_{1}D_{B}}\circ_{2}F &\equiv \paren{D_{A}^{i_{1}\dots i_{n}}\circ_{1} 747 \partial_{i_{1}\dots i_{n}}\paren{D_{B}^{j_{1}\dots j_{n}} 748 \partial_{j_{1}\dots j_{n}}}}\circ_{2}F \nonumber \\ 749 &= \paren{D_{A}^{i_{1}\dots i_{n}}\circ_{1} 750 \paren{\paren{\partial_{i_{1}\dots i_{n}}D_{B}^{j_{1}\dots j_{n}}} 751 \partial_{j_{1}\dots j_{n}}+ 752 D_{B}^{j_{1}\dots j_{n}}} 753 \partial_{i_{1}+j_{1},\dots, i_{n}+j_{n}}}\circ_{2}F \nonumber \\ 754 &= \paren{D_{A}^{i_{1}\dots i_{n}}\circ_{1}\paren{\partial_{i_{1}\dots i_{n}}D_{B}^{j_{1}\dots j_{n}}}} 755 \circ_{2}\partial_{j_{1}\dots j_{n}}F+ 756 \paren{D_{A}^{i_{1}\dots i_{n}}\circ_{1}D_{B}^{j_{1}\dots j_{n}}} 757 \circ_{2}\partial_{i_{1}+j_{1},\dots, i_{n}+j_{n}}F, 758 \end{align*} 759 where we have used the fact that the $\partial$ operator is a scalar operator and commutes with $\circ_{1}$ and $\circ_{2}$. 760 761 Thus for a pure operator product $D_{A}\circ D_{B}$ we have 762 \be\label{eq_71a} 763 D_{A}\circ D_{B} = \paren{D_{A}^{i_{1}\dots i_{n}}\circ\paren{\partial_{i_{1}\dots i_{n}}D_{B}^{j_{1}\dots j_{n}}}} 764 \partial_{j_{1}\dots j_{n}}+ 765 \paren{D_{A}^{i_{1}\dots i_{n}}\circ_{1}D_{B}^{j_{1}\dots j_{n}}} 766 \partial_{i_{1}+j_{1},\dots, i_{n}+j_{n}} 767 \ee 768 and the form of eq~(\ref{eq_71a}) is the same as eq~(\ref{eq_67a}). The basis of eq~(\ref{eq_71a}) is that the $\partial$ operator 769 operates on all object to the right of it as products so that the product rule must be used in all differentiations. Since eq~(\ref{eq_71a}) 770 puts the product of two differential operators in standard form we also evaluate $F\circ_{2}\paren{D_{A}\circ_{1}D_{B}}$. 771 772 We now must distinguish between the following cases. If $D$ is a differential operator and $F$ a multivector function should $D\circ F$ and 773 $F\circ D$ return a differential operator or a multivector. In order to be consistent with the standard vector analysis we have $D\circ F$ 774 return a multivector and $F\circ D$ return a differential operator. Then we define the complementary differential operator $\bar{D}$ which 775 is identical to $D$ except that $\bar{D}\circ F$ returns a differential operator according to eq~(\ref{eq_71a})\footnote{In this case 776 $D_{B}^{j_{1}\dots j_{n}} = F$ and $\partial_{j_{1}\dots j_{n}} = 1$.} and $F\circ\bar{D}$ returns a multivector according to eq~(\ref{eq_68a}). 777 778 A general differential operator is built from repeated applications of the basic operator building blocks $\paren{\bar{\nabla}\circ A}$, 779 $\paren{A\circ\bar{\nabla}}$, $\paren{\bar{\nabla}\circ\bar{\nabla}}$, and $\paren{A\pm \bar{\nabla}}$. Both $\nabla$ and $\bar{\nabla}$ 780 are represented by the operator 781 \be 782 \nabla = \bar{\nabla} = e^{i}\pdiff{}{x^{i}}, 783 \ee 784 but are flagged to produce the appropriate result. 785 786 In the our notation the directional derivative operator is $a\cdot\nabla$, the Laplacian 787 $\nabla\cdot\nabla$ and the expression for the Riemann tensor, $R^{i}_{jkl}$, is 788 \be 789 \paren{\nabla\W\nabla}\eb^{i} = \half R^{i}_{jkl}\paren{\eb^{j}\W\eb^{k}}\eb^{l}. 790 \ee 791 We would use the complement if we wish a quantum mechanical type commutator defining 792 \be 793 \com{x,\nabla} \equiv x\nabla - \bar{\nabla}x, 794 \ee 795 or if we wish to simulate the dot notation (Doran and Lasenby) 796 \be 797 \dot{F}\dot{\nabla} = F\bar{\nabla}. 798 \ee 799 800 \subsection{Split Differential Operator} 801 802 To implement the general ``dot'' notation for differential operators in python is not possible. Another type of symbolic notation is required. I 803 propose what one could call the ``split differential operator.'' For $\nabla$ denote the corresponding split operator by two operators 804 $\bra{\nabla}$ and 805 $\ket{\nabla}$ where in practice $\bra{\nabla}$ is a tuple of vectors and $\ket{\nabla}$ is a tuple of corresponding partial derivatives. Then the equivalent of 806 the ``dot'' notation would be 807 \begin{equation} 808 \dot{\nabla}\paren{A\dot{B}C} = \bra{\nabla}\paren{A\paren{\ket{\nabla}B}C}.\label{splitopV} 809 \end{equation} 810 We are using the $\mathcal{G}$ subscript to indicate the geometric algebra parts of the multivector differential operator and the $\mathcal{D}$ subscript 811 to indicate the scalar differential operator parts of the multivector differential operator. An example of this notation in 3D Euclidean space is 812 \begin{eqnarray} 813 \bra{\nabla} &= \paren{\eb_{x},\eb_{y},\eb_{z}}, \\ 814 \ket{\nabla} &= \paren{\pdiff{}{x},\pdiff{}{y},\pdiff{}{x}}, 815 \end{eqnarray} 816 To implement $\bra{\nabla}$ and $\ket{\nabla}$ we have in the example 817 \begin{eqnarray} 818 \ket{\nabla}B &= \paren{\pdiff{B}{x},\pdiff{B}{y},\pdiff{B}{z}} \\ 819 \paren{\ket{\nabla}B}C &= \paren{\pdiff{B}{x}C,\pdiff{B}{y}C,\pdiff{B}{z}C} \\ 820 A\paren{\ket{\nabla}B}C &= \paren{A\pdiff{B}{x}C,A\pdiff{B}{y}C,A\pdiff{B}{z}C}. 821 \end{eqnarray} 822 Then the final evaluation is 823 \begin{equation} 824 \bra{\nabla}\paren{A\paren{\ket{\nabla}B}C} = \eb_{x}A\pdiff{B}{x}C+\eb_{y}A\pdiff{B}{y}C+\eb_{z}A\pdiff{B}{z}C, 825 \end{equation} 826 which could be called the ``dot'' product of two tuples. Note that $\nabla = \bra{\nabla}\ket{\nabla}$ and 827 $\dot{F}\dot{\nabla} = F\bar{\nabla} = \paren{\ket{\nabla}F}\bra{\nabla}$. 828 829 For the general multivector differential operator, $D$, the split operator parts are $\bra{D}$, a tuple of basis blade multivectors and $\ket{D}$, a 830 tuple of scalar differential operators that correspond to the coefficients of the basis-blades in the total operator $D$ so that 831 \begin{equation} 832 \dot{D}\paren{A\dot{B}C} = \bra{D}\paren{A\paren{\ket{D}B}C}. \label{splitopM} 833 \end{equation} 834 If the index set for the basis blades of a geometric algebra is denoted by $\set{n}$ where $\set{n}$ contains $2^{n}$ indices for an $n$ dimensional 835 geometric algebra then the most general multivector differential operator can be written\footnote{For example in three dimensions 836 $\set{3} = (0,1,2,3,(1,2),(2,3),(1,3),(1,2,3))$ and as an example of how the superscript would work with each grade $\eb^{0}=1$, $\eb^{1}=\eb^{1}$, $\eb^{\paren{1,2}}=\eb^{1}\W\eb^{2}$, and $\eb^{\paren{1,2,3}}=\eb^{1}\W\eb^{2}\W\eb^{3}$.} 837 \begin{equation} 838 D = {\ds \sum_{l\in\set{n}}\eb^{l}D_{\set{l}}} 839 \end{equation} 840 \begin{equation} 841 \dot{D}\paren{A\dot{B}C} = \bra{D}\paren{A\paren{\ket{D}B}C} = {\ds \sum_{l\in\set{n}}\eb^{l}\paren{A\paren{D_{l}B}C}} 842 \end{equation} 843 or 844 \begin{equation} 845 \paren{A\dot{B}C}\dot{D} = \paren{A\paren{\ket{D}B}C}\bra{D} = {\ds \sum_{l\in\set{n}}\paren{A\paren{D_{l}B}C}\eb^{l}}. 846 \end{equation} 847 The implementation of equations~\ref{splitopV} and \ref{splitopM} is described in sections~\ref{makeMV} and \ref{makeMVD}. 848 849 850 \section{Linear Transformations/Outermorphisms}\label{Ltrans} 851 852 In the tangent space of a manifold, $\mathcal{M}$, (which is a vector space) a linear transformation is the mapping 853 $\underline{T}\colon\Tn{\mathcal{M}}{\vec{x}}\rightarrow\Tn{\mathcal{M}}{\vec{x}}$ (we use an underline to indicate 854 a linear transformation) where for all $x,y\in \Tn{\mathcal{M}}{\vec{x}}$ and $\alpha\in\Re$ we have 855 \begin{align} 856 \f{\underline{T}}{x+y} =& \f{\underline{T}}{x} + \f{\underline{T}}{y} \\ 857 \f{\underline{T}}{\alpha x} =& \alpha\f{\underline{T}}{x} 858 \end{align} 859 The outermorphism induced by $\underline{T}$ is defined for $x_{1},\dots,x_{r}\in\Tn{\mathcal{M}}{\vec{x}}$ where 860 $r\le\f{\dim}{\Tn{\mathcal{M}}{\vec{x}}}$ 861 \be 862 \f{\underline{T}}{x_{1}\W\dots\W x_{r}} \equiv \f{\underline{T}}{x_{1}}\W\dots\W\f{\underline{T}}{x_{r}} 863 \ee 864 If $I$ is the pseudo scalar for $\Tn{\mathcal{M}}{\vec{x}}$ we also have the following definitions for determinate, trace, 865 and adjoint ($\overline{T}$) of $\underline{T}$ 866 \begin{align} 867 \f{\underline{T}}{I} \equiv&\; \f{\det}{\underline{T}}I\text{,\footnotemark} \label{eq_82}\\ 868 \f{\tr}{\underline{T}} \equiv&\; \nabla_{y}\cdot\f{\underline{T}}{y}\text{,\footnotemark} \label{eq_83}\\ \addtocounter{footnote}{-1} 869 x\cdot \f{\overline{T}}{y} \equiv&\; y\cdot \f{\underline{T}}{x}.\text{\footnotemark} \label{eq_84}\\ \addtocounter{footnote}{-1} 870 \end{align} 871 \footnotetext{Since $\underline{T}$ is linear we do not require $I^{2} = \pm 1$.}\addtocounter{footnote}{1} 872 \footnotetext{In this case $y$ is a vector in the tangent space and not a coordinate vector so that the 873 basis vectors are {\em not} a function of $y$.}\addtocounter{footnote}{1} 874 \footnotetext{Both $x$ and $y$ are vectors in the tangent space.} 875 If $\set{\eb_{i}}$ is a basis for $\Tn{\mathcal{M}}{\vec{x}}$ then we can represent $\underline{T}$ with the matrix $\underline{T}_{i}^{j}$ used 876 as follows (Einstein summation convention as usual) - 877 \be\label{eq_85} 878 \f{\underline{T}}{\eb_{i}} = \underline{T}_{i}^{j}\eb_{j}, 879 \ee 880 where 881 \be\label{eq_85a} 882 \underline{T}_{i}^{j} = \eb^{j}\cdot\f{\underline{T}}{\eb_{i}}. 883 \ee 884 The let $\paren{\underline{T}^{-1}}_{m}^{n}$ be the inverse matrix of $\underline{T}_{i}^{j}$ so that 885 $\paren{\underline{T}^{-1}}_{m}^{k}\underline{T}_{k}^{j} = \delta^{j}_{m}$ and 886 \begin{equation} 887 \underline{T}^{-1}\paren{a^{i}\eb_{i}} = a^{i}\paren{\underline{T}^{-1}}_{i}^{j}\eb_{j} 888 \end{equation} 889 and calculate 890 \begin{align} 891 \underline{T}^{-1}\paren{\underline{T}\paren{a}} &= \underline{T}^{-1}\paren{\underline{T}\paren{a^{i}\eb_{i}}} \nonumber \\ 892 &= \underline{T}^{-1}\paren{a^{i}\underline{T}_{i}^{j}\eb_{j}} \nonumber \\ 893 &= a^{i}\paren{\underline{T}^{-1}}_{i}^{j} \underline{T}_{j}^{k}\eb_{k} \nonumber \\ 894 &= a^{i}\delta_{i}^{j}\eb_{j} = a^{i}\eb_{i} = a. 895 \end{align} 896 Thus if eq~\ref{eq_85a} is used to define the $\underline{T}_{i}^{j}$ then the linear transformation defined by the matrix $\paren{\underline{T}^{-1}}_{m}^{n}$ is the inverse of $\underline{T}$. 897 898 In eq.~(\ref{eq_85}) the matrix, $\underline{T}_{i}^{j}$, only has it's usual meaning if the $\set{\eb_{i}}$ form an orthonormal Euclidean 899 basis (Minkowski spaces not allowed). Equations~(\ref{eq_82}) through (\ref{eq_84}) become 900 \begin{align} 901 \f{\det}{\underline{T}} =&\; \f{\underline{T}}{\eb_{1}\W\dots\W\eb_{n}}\paren{\eb_{1}\W\dots\W\eb_{n}}^{-1},\\ 902 \f{\tr}{\underline{T}} =&\; \underline{T}_{i}^{i},\\ 903 \overline{T}_{j}^{i} =&\; g^{il}g_{jp}\underline{T}_{l}^{p}. 904 \end{align} 905 906 A important form of linear transformation with a simple representation is the spinor transformation. If $S$ is an even multivector we have 907 $SS^{\R} = \rho^{2}$, where $\rho^{2}$ is a scalar. Then $S$ is a spinor transformation is given by ($v$ is a vector) 908 \begin{equation} 909 \f{S}{v} = SvS^{\R} 910 \end{equation} 911 if $\f{S}{v}$ is a vector and 912 \begin{equation} 913 \f{S^{-1}}{v} = \frac{S^{\R}vS}{\rho^{4}}. 914 \end{equation} 915 Thus 916 \begin{align} 917 \f{S^{-1}}{\f{S}{v}} &= \frac{S^{\R}SvS^{\R}S}{\rho^{4}} \nonumber \\ 918 &= \frac{\rho^{2}v\rho^{2}}{\rho^{4}} \nonumber \\ 919 &= v. 920 \end{align} 921 922 One more topic to consider is whether or not $T^{i}_{j}$ should be called the matrix representation of $T$? The reason that 923 this is a question is that for a general metric $g_{ij}$ is that because of the dependence of the dot product on the metric 924 $T^{i}_{j}$ does not necessarily show the symmetries of the underlying transformation $T$. Consider the expression 925 \begin{align} 926 a\cdot\f{T}{b} &= a^{i}\eb_{i}\cdot\f{T}{b^{j}\eb_{j}} \nonumber \\ 927 &= a^{i}\eb_{i}\cdot \f{T}{\eb_{j}}b^{j} \nonumber \\ 928 &= a^{i}\eb_{i}\cdot\eb_{k} T_{j}^{k}b^{j} \nonumber \\ 929 &= a^{i}g_{ik}T_{j}^{k}b^{j}. 930 \end{align} 931 It is 932 \begin{equation} 933 T_{ij} = g_{ik}T_{j}^{k} 934 \end{equation} 935 that has the proper symmetry for self adjoint transformations $(a\cdot\f{T}{b} = b\cdot\f{T}{a})$ in the sense that if 936 $T = \overline{T}$ then $T_{ij} = T_{ji}$. Of course if we are dealing with a manifold where the $g_{ij}$'s are functions 937 of the coordinates then the matrix representation of a linear transformation will also be a function of the coordinates. 938 Assuming we use $T_{ij}$ for the matrix representation of the linear transformation, $T$, then if we given the matrix 939 representation, $T_{ij}$, we can construct the linear transformation given by $T^{i}_{j}$ as follows 940 \begin{align} 941 T_{ij} &= g_{ik}T_{j}^{k} \nonumber \\ 942 g^{li}T_{ij} &= g^{li}g_{ik}T_{j}^{k} \nonumber \\ 943 g^{li}T_{ij} &= \delta_{k}^{l}T_{j}^{k} \nonumber \\ 944 g^{li}T_{ij} &= T_{j}^{l}. 945 \end{align} 946 Any program/code that represents $T$ should allow one to define $T$ in terms of $T_{ij}$ or $T_{j}^{l}$ and likewise 947 given a linear transformation $T$ obtain both $T_{ij}$ and $T_{j}^{l}$ from it. Please note that these considerations 948 come into play for any non-Euclidean metric with respect to the trace and adjoint of a linear transformation since 949 calculating either requires a dot product. 950 951 \section{Multilinear Functions}\label{MLTrans} 952 A multivector multilinear function\footnote{We are following the treatment of Tensors in section 3--10 of \cite{Hestenes}.} is a 953 multivector function $\f{T}{A_{1},\dots,A_{r}}$ that is linear in each of it arguments\footnote{We assume that the arguments 954 are elements of a vector space or more generally a geometric algebra so that the concept of linearity is meaningful.} 955 (it could be implicitly non-linearly dependent 956 on a set of additional arguments such as the position coordinates, but we only consider the linear arguments). $T$ is a \emph{tensor} 957 of degree $r$ if each variable $A_{j}$ is restricted to the vector space $\mathcal{V}_{n}$. More generally if each 958 $A_{j}\in\f{\mathcal{G}}{\mathcal{V}_{n}}$ (the geometric algebra of $\mathcal{V}_{n}$), we call $T$ an \emph{extensor} of 959 degree-$r$ on $\f{\mathcal{G}}{\mathcal{V}_{n}}$. 960 961 If the values of $\f{T}{a_{1},\dots,a_{r}}$ $\lp a_{j}\in\mathcal{V}_{n}\;\forall\; 1\le j \le r \rp$ are $s$-vectors 962 (pure grade $s$ multivectors in 963 $\f{\mathcal{G}}{\mathcal{V}_{n}}$) we say that $T$ has grade $s$ and rank $r+s$. A tensor of grade zero is called a 964 \emph{multilinear form}. 965 966 In the normal definition of tensors as multilinear functions the tensor is defined as a mapping 967 $$T:\bigtimes_{i=1}^{r}\mathcal{V}_{i}\rightarrow\Re,$$ so that the standard tensor definition is an example of a grade zero 968 degree/rank $r$ tensor in our definition. 969 970 \subsection{Algebraic Operations} 971 The properties of tensors are ($\alpha\in\Re$, $a_{j},b\in\mathcal{V}_{n}$, $T$ and $S$ are tensors of rank $r$, 972 and $\circ$ is any multivector multiplicative operation) 973 \begin{align} 974 \f{T}{a_{1},\dots,\alpha a_{j},\dots,a_{r}} =& \alpha\f{T}{a_{1},\dots,a_{j},\dots,a_{r}}, \\ 975 \f{T}{a_{1},\dots,a_{j}+b,\dots,a_{r}} =& \f{T}{a_{1},\dots,a_{j},\dots,a_{r}}+ \f{T}{a_{1},\dots,a_{j-1},b,a_{j+1},\dots,a_{r}}, \\ 976 \f{\lp T\pm S\rp}{a_{1},\dots,a_{r}} \equiv& \f{T}{a_{1},\dots,a_{r}}\pm\f{S}{a_{1},\dots,a_{r}}. 977 \end{align} 978 Now let $T$ be of rank $r$ and $S$ of rank $s$ then the product of the two tensors is 979 \be 980 \f{\lp T\circ S\rp}{a_{1},\dots,a_{r+s}} \equiv \f{T}{a_{1},\dots,a_{r}}\circ\f{S}{a_{r+1},\dots,a_{r+s}}, 981 \ee 982 where ``$\circ$'' is any multivector multiplicative operation. 983 984 \subsection{Covariant, Contravariant, and Mixed Representations} 985 986 The arguments (vectors) of the multilinear function can be represented in terms of the basis vectors or the reciprocal basis vectors 987 \begin{align} 988 a_{j} =& a^{i_{j}}\eb_{i_{j}}, \label{vrep}\\ 989 =& a_{i_{j}}\eb^{i_{j}}. \label{rvrep} 990 \end{align} 991 Equation~(\ref{vrep}) gives $a_{j}$ in terms of the basis vectors and eq~(\ref{rvrep}) in terms of the reciprocal basis vectors. The index 992 $j$ refers to the argument slot and the indices $i_{j}$ the components of the vector in terms of the basis. The 993 covariant representation of the tensor is defined by 994 \begin{align} 995 T\indices{_{i_{1}\dots i_{r}}} \equiv& \f{T}{\eb_{i_{1}},\dots,\eb_{i_{r}}} \\ 996 \f{T}{a_{1},\dots,a_{r}} =& \f{T}{a^{i_{1}}\eb_{i_{1}},\dots,a^{i_{r}}\eb_{i_{r}}} \nonumber \\ 997 =& \f{T}{\eb_{i_{1}},\dots,\eb_{i_{r}}}a^{i_{1}}\dots a^{i_{r}} \nonumber \\ 998 =& T\indices{_{i_{1}\dots i_{r}}}a^{i_{1}}\dots a^{i_{r}}. 999 \end{align} 1000 Likewise for the contravariant representation 1001 \begin{align} 1002 T\indices{^{i_{1}\dots i_{r}}} \equiv& \f{T}{\eb^{i_{1}},\dots,\eb^{i_{r}}} \\ 1003 \f{T}{a_{1},\dots,a_{r}} =& \f{T}{a_{i_{1}}\eb^{i_{1}},\dots,a_{i_{r}}\eb^{i_{r}}} \nonumber \\ 1004 =& \f{T}{\eb^{i_{1}},\dots,\eb^{i_{r}}}a_{i_{1}}\dots a_{i_{r}} \nonumber \\ 1005 =& T\indices{^{i_{1}\dots i_{r}}}a_{i_{1}}\dots a_{i_{r}}. 1006 \end{align} 1007 One could also have a mixed representation 1008 \begin{align} 1009 T\indices{_{i_{1}\dots i_{s}}^{i_{s+1}\dots i_{r}}} \equiv& \f{T}{\eb_{i_{1}},\dots,\eb_{i_{s}},\eb^{i_{s+1}}\dots\eb^{i_{r}}} \\ 1010 \f{T}{a_{1},\dots,a_{r}} =& \f{T}{a^{i_{1}}\eb_{i_{1}},\dots,a^{i_{s}}\eb_{i_{s}}, 1011 a_{i_{s+1}}\eb^{i_{s}}\dots,a_{i_{r}}\eb^{i_{r}}} \nonumber \\ 1012 =& \f{T}{\eb_{i_{1}},\dots,\eb_{i_{s}},\eb^{i_{s+1}},\dots,\eb^{i_{r}}} 1013 a^{i_{1}}\dots a^{i_{s}}a_{i_{s+1}},\dots a^{i_{r}} \nonumber \\ 1014 =& T\indices{_{i_{1}\dots i_{s}}^{i_{s+1}\dots i_{r}}}a^{i_{1}}\dots a^{i_{s}}a_{i_{s+1}}\dots a^{i_{r}}. 1015 \end{align} 1016 In the representation of $T$ one could have any combination of covariant (lower) and contravariant (upper) indexes. 1017 1018 To convert a covariant index to a contravariant index simply consider 1019 \begin{align} 1020 \f{T}{\eb_{i_{1}},\dots,\eb^{i_{j}},\dots,\eb_{i_{r}}} =& \f{T}{\eb_{i_{1}},\dots,g^{i_{j}k_{j}}\eb_{k_{j}},\dots,\eb_{i_{r}}} \nonumber \\ 1021 =& g^{i_{j}k_{j}}\f{T}{\eb_{i_{1}},\dots,\eb_{k_{j}},\dots,\eb_{i_{r}}} \nonumber \\ 1022 T\indices{_{i_{1}\dots}^{i_{j}}_{\dots i_{r}}} =& g^{i_{j}k_{j}}T\indices{_{i_{1}\dots i_{j}\dots i_{r}}}. 1023 \end{align} 1024 Similarly one could lower an upper index with $g_{i_{j}k_{j}}$. 1025 1026 \subsection{Contraction and Differentiation} 1027 The contraction of a tensor between the $j^{th}$ and $k^{th}$ variables (slots) is 1028 \be 1029 \f{T}{a_{i},\dots,a_{j-1},\nabla_{a_{k}},a_{j+1},\dots,a_{r}} = \nabla_{a_{j}}\cdot\lp\nabla_{a_{k}}\f{T}{a_{1},\dots,a_{r}}\rp. 1030 \ee 1031 This operation reduces the rank of the tensor by two. This definition gives the standard results for \emph{metric contraction} which is 1032 proved as follows for a rank $r$ grade zero tensor (the circumflex ``$\breve{\:\:}$'' indicates that a term is to be deleted from the product). 1033 \begin{align} 1034 \f{T}{a_{1},\dots,a_{r}} =& a^{i_{1}}\dots a^{i_{r}}T_{i_{1}\dots i_{r}} \\ 1035 \nabla_{a_{j}}T =& \eb^{l_{j}} a^{i_{1}}\dots\lp\partial_{a^{l_j}}a^{i_{j}}\rp\dots a_{i_{r}}T_{i_{1}\dots i_{r}} \nonumber \\ 1036 =& \eb^{l_{j}}\delta_{l_{j}}^{i_{j}} a^{i_{1}}\dots \breve{a}^{i_{j}}\dots a^{i_{r}}T_{i_{1}\dots i_{r}} \\ 1037 \nabla_{a_{m}}\cdot\lp\nabla_{a_{j}}T\rp =& \eb^{k_{m}}\cdot\eb^{l_{j}}\delta_{l_{j}}^{i_{j}} 1038 a^{i_{1}}\dots \breve{a}^{i_{j}}\dots\lp\partial_{a^{k_m}}a^{i_{m}}\rp 1039 \dots a^{i_{r}}T_{i_{1}\dots i_{r}} \nonumber \\ 1040 =& g^{k_{m}l_{j}}\delta_{l_{j}}^{i_{j}}\delta_{k_{m}}^{i_{m}} 1041 a^{i_{1}}\dots \breve{a}^{i_{j}}\dots\breve{a}^{i_{m}} 1042 \dots a^{i_{r}}T_{i_{1}\dots i_{r}} \nonumber \\ 1043 =& g^{i_{m}i_{j}}a^{i_{1}}\dots \breve{a}^{i_{j}}\dots\breve{a}^{i_{m}} 1044 \dots a^{i_{r}}T_{i_{1}\dots i_{j}\dots i_{m}\dots i_{r}} \nonumber \\ 1045 =& g^{i_{j}i_{m}}a^{i_{1}}\dots \breve{a}^{i_{j}}\dots\breve{a}^{i_{m}} 1046 \dots a^{i_{r}}T_{i_{1}\dots i_{j}\dots i_{m}\dots i_{r}} \nonumber \\ 1047 =& \lp g^{i_{j}i_{m}}T_{i_{1}\dots i_{j}\dots i_{m}\dots i_{r}}\rp a^{i_{1}}\dots 1048 \breve{a}^{i_{j}}\dots\breve{a}^{i_{m}}\dots a^{i_{r}} \label{eq108} 1049 \end{align} 1050 Equation~(\ref{eq108}) is the correct formula for the metric contraction of a tensor. 1051 1052 If we have a mixed representation of a tensor, $T\indices{_{i_{1}\dots}^{i_{j}}_{\dots i_{k}\dots i_{r}}}$, 1053 and wish to contract between an upper and lower index ($i_{j}$ and $i_{k}$) first lower the upper index and then use eq~(\ref{eq108}) 1054 to contract the result. Remember lowering the index does \emph{not} change the tensor, only the \emph{representation} of the tensor, 1055 while contraction results in a \emph{new} tensor. First lower index 1056 \be 1057 T\indices{_{i_{1}\dots}^{i_{j}}_{\dots i_{k}\dots i_{r}}} \xRightarrow{\mbox{\tiny Lower Index}} g_{i_{j}k_{j}}T\indices{_{i_{1}\dots}^{k_{j}}_{\dots i_{k}\dots i_{r}}} 1058 \ee 1059 Now contract between $i_{j}$ and $i_{k}$ and use the properties of the metric tensor. 1060 \begin{align} 1061 g_{i_{j}k_{j}}T\indices{_{i_{1}\dots}^{k_{j}}_{\dots i_{k}\dots i_{r}}} \xRightarrow{\mbox{\tiny Contract}}& 1062 g^{i_{j}i_{k}}g_{i_{j}k_{j}}T\indices{_{i_{1}\dots}^{k_{j}}_{\dots i_{k}\dots i_{r}}} \nonumber \\ 1063 =& \delta_{k_{j}}^{i_{k}}T\indices{_{i_{1}\dots}^{k_{j}}_{\dots i_{k}\dots i_{r}}}. \label{114a} 1064 \end{align} 1065 Equation~(\ref{114a}) is the standard formula for contraction between upper and lower indexes of a mixed tensor. 1066 1067 Finally if $\f{T}{a_{1},\dots,a_{r}}$ is a tensor field (implicitly a function of position) the tensor derivative is defined as 1068 \begin{align} 1069 \f{T}{a_{1},\dots,a_{r};a_{r+1}} \equiv \lp a_{r+1}\cdot\nabla\rp\f{T}{a_{1},\dots,a_{r}}, 1070 \end{align} 1071 assuming the $a^{i_{j}}$ coefficients are not a function of the coordinates. 1072 1073 This gives for a grade zero rank $r$ tensor 1074 \begin{align} 1075 \lp a_{r+1}\cdot\nabla\rp\f{T}{a_{1},\dots,a_{r}} =& a^{i_{r+1}}\partial_{x^{i_{r+1}}}a^{i_{1}}\dots a^{i_{r}} 1076 T_{i_{1}\dots i_{r}}, \nonumber \\ 1077 =& a^{i_{1}}\dots a^{i_{r}}a^{i_{r+1}} 1078 \partial_{x^{i_{r+1}}}T_{i_{1}\dots i_{r}}. 1079 \end{align} 1080 1081 \subsection{From Vector to Tensor} 1082 1083 A rank one tensor is a vector since it satisfies all the axioms for a vector space, but a vector in not necessarily a tensor since not all vectors 1084 are multilinear (actually in the case of vectors a linear function) functions. However, there is a simple isomorphism between vectors and 1085 rank one tensors defined by the mapping $\f{v}{a}:\mathcal{V}\rightarrow\Re$ such that if $v,a \in\mathcal{V}$ 1086 \be 1087 \f{v}{a} \equiv v\cdot a. 1088 \ee 1089 So that if $v = v^{i}\eb_{i} = v_{i}\eb^{i}$ the covariant and contravariant representations of $v$ are 1090 (using $\eb^{i}\cdot\eb_{j} = \delta^{i}_{j}$) 1091 \be 1092 \f{v}{a} = v_{i}a^{i} = v^{i}a_{i}. 1093 \ee 1094 1095 \subsection{Parallel Transport and Covariant Derivatives} 1096 The covariant derivative of a tensor field $\f{T}{a_{1},\dots,a_{r};x}$ ($x$ is the coordinate vector of which $T$ can be a non-linear function) in 1097 the direction $a_{r+1}$ is (remember $a_{j} = a_{j}^{k}\eb_{k}$ and the $\eb_{k}$ can be functions of $x$) the directional derivative of 1098 $\f{T}{a_{1},\dots,a_{r};x}$ where all the arguments of $T$ are parallel transported. The definition of parallel transport is if $a$ and $b$ are 1099 tangent vectors in the tangent spaced of the manifold then 1100 \be 1101 \paren{a\cdot\nabla_{x}}b = 0 \label{eq108a} 1102 \ee 1103 if $b$ is parallel transported. Since $b = b^{i}\eb_{i}$ and the derivatives of $\eb_{i}$ are functions of the $x^{i}$'s then the $b^{i}$'s are 1104 also functions of the $x^{i}$'s so that in order for eq~(\ref{eq108a}) to be satisfied we have 1105 \begin{align} 1106 \paren{a\cdot\nabla_{x}}b =& a^{i}\partial_{x^{i}}\paren{b^{j}\eb_{j}} \nonumber \\ 1107 =& a^{i}\paren{\paren{\partial_{x^{i}}b^{j}}\eb_{j} + b^{j}\partial_{x^{i}}\eb_{j}} \nonumber \\ 1108 =& a^{i}\paren{\paren{\partial_{x^{i}}b^{j}}\eb_{j} + b^{j}\Gamma_{ij}^{k}\eb_{k}} \nonumber \\ 1109 =& a^{i}\paren{\paren{\partial_{x^{i}}b^{j}}\eb_{j} + b^{k}\Gamma_{ik}^{j}\eb_{j}}\nonumber \\ 1110 =& a^{i}\paren{\paren{\partial_{x^{i}}b^{j}} + b^{k}\Gamma_{ik}^{j}}\eb_{j} = 0. 1111 \end{align} 1112 Thus for $b$ to be parallel transported we must have 1113 \be 1114 \partial_{x^{i}}b^{j} = -b^{k}\Gamma_{ik}^{j}. \label{eq121a} 1115 \ee 1116 The geometric meaning of parallel transport is that for an infinitesimal rotation and dilation of the basis vectors (cause by infinitesimal changes in the $x^{i}$'s) the direction and magnitude of the vector $b$ does not change. 1117 1118 If we apply eq~(\ref{eq121a}) along a parametric curve defined by $\f{x^{j}}{s}$ we have 1119 \begin{align} 1120 \deriv{b^{j}}{s}{} =& \deriv{x^{i}}{s}{}\pdiff{b^{j}}{x^{i}} \nonumber \\ 1121 =& -b^{k}\deriv{x^{i}}{s}{}\Gamma_{ik}^{j}, \label{eq122a} 1122 \end{align} 1123 and if we define the initial conditions $\f{b^{j}}{0}\eb_{j}$. Then eq~(\ref{eq122a}) is a system of first order 1124 linear differential equations with initial conditions and the solution, $\f{b^{j}}{s}\eb_{j}$, is the parallel transport of the 1125 vector $\f{b^{j}}{0}\eb_{j}$. 1126 1127 An equivalent formulation for the parallel transport equation is to let $\f{\gamma}{s}$ be a parametric curve in the manifold 1128 defined by the tuple $\f{\gamma}{s} = \paren{\f{x^{1}}{s},\dots,\f{x^{n}}{s}}$. Then the tangent to $\f{\gamma}{s}$ is given by 1129 \be 1130 \deriv{\gamma}{s}{} \equiv \deriv{x^{i}}{s}{}\eb_{i} 1131 \ee 1132 and if $\f{v}{x}$ is a vector field on the manifold then 1133 \begin{align} 1134 \paren{\deriv{\gamma}{s}{}\cdot\nabla_{x}}v =& \deriv{x^{i}}{s}{}\pdiff{}{x^{i}}\paren{v^{j}\eb_{j}} \nonumber \\ 1135 =&\deriv{x^{i}}{s}{}\paren{\pdiff{v^{j}}{x^{i}}\eb_{j}+v^{j}\pdiff{\eb_{j}}{x^{i}}} \nonumber \\ 1136 =&\deriv{x^{i}}{s}{}\paren{\pdiff{v^{j}}{x^{i}}\eb_{j}+v^{j}\Gamma^{k}_{ij}\eb_{k}} \nonumber \\ 1137 =&\deriv{x^{i}}{s}{}\pdiff{v^{j}}{x^{i}}\eb_{j}+\deriv{x^{i}}{s}{}v^{k}\Gamma^{j}_{ik}\eb_{j} \nonumber \\ 1138 =&\paren{\deriv{v^{j}}{s}{}+\deriv{x^{i}}{s}{}v^{k}\Gamma^{j}_{ik}}\eb_{j} \nonumber \\ 1139 =& 0. \label{eq124a} 1140 \end{align} 1141 Thus eq~(\ref{eq124a}) is equivalent to eq~(\ref{eq122a}) and parallel transport of a vector field along a curve is 1142 equivalent to the directional derivative of the vector field in the direction of the tangent to the curve being zero. 1143 1144 If the tensor component representation is contra-variant (superscripts instead of subscripts) we must use the covariant component representation of 1145 the vector arguments of the tensor, $a = a_{i}\eb^{i}$. Then the definition of parallel transport gives 1146 \begin{align} 1147 \paren{a\cdot\nabla_{x}}b =& a^{i}\partial_{x^{i}}\paren{b_{j}\eb^{j}} \nonumber \\ 1148 =& a^{i}\paren{\paren{\partial_{x^{i}}b_{j}}\eb^{j} + b_{j}\partial_{x^{i}}\eb^{j}}, 1149 \end{align} 1150 and we need 1151 \be 1152 \paren{\partial_{x^{i}}b_{j}}\eb^{j} + b_{j}\partial_{x^{i}}\eb^{j} = 0. \label{eq111a} 1153 \ee 1154 To satisfy equation~(\ref{eq111a}) consider the following 1155 \begin{align} 1156 \partial_{x^{i}}\paren{\eb^{j}\cdot\eb_{k}} =& 0 \nonumber \\ 1157 \paren{\partial_{x^{i}}\eb^{j}}\cdot\eb_{k} + \eb^{j}\cdot\paren{\partial_{x^{i}}\eb_{k}} =& 0 \nonumber \\ 1158 \paren{\partial_{x^{i}}\eb^{j}}\cdot\eb_{k} + \eb^{j}\cdot\eb_{l}\Gamma_{ik}^{l} =& 0 \nonumber \\ 1159 \paren{\partial_{x^{i}}\eb^{j}}\cdot\eb_{k} + \delta_{l}^{j}\Gamma_{ik}^{l} =& 0 \nonumber \\ 1160 \paren{\partial_{x^{i}}\eb^{j}}\cdot\eb_{k} + \Gamma_{ik}^{j} =& 0 \nonumber \\ 1161 \paren{\partial_{x^{i}}\eb^{j}}\cdot\eb_{k} =& -\Gamma_{ik}^{j} 1162 \end{align} 1163 Now dot eq~(\ref{eq111a}) into $\eb_{k}$ giving 1164 \begin{align} 1165 \paren{\partial_{x^{i}}b_{j}}\eb^{j}\cdot\eb_{k} + b_{j}\paren{\partial_{x^{i}}\eb^{j}}\cdot\eb_{k} =& 0 \nonumber \\ 1166 \paren{\partial_{x^{i}}b_{j}}\delta_{j}^{k} - b_{j}\Gamma_{ik}^{j} =& 0 \nonumber \\ 1167 \paren{\partial_{x^{i}}b_{k}} = b_{j}\Gamma_{ik}^{j}. 1168 \end{align} 1169 Thus if we have a mixed representation of a tensor 1170 \be 1171 \f{T}{a_{1},\dots,a_{r};x} = 1172 \f{T\indices{_{i_{1}\dots i_{s}}^{i_{s+1}\dots i_{r}}}}{x}a^{i_{1}}\dots a^{i_{s}}a_{i_{s+1}}\dots a_{i_{r}}, 1173 \ee 1174 the covariant derivative of the tensor is 1175 \begin{align} 1176 \paren{a_{r+1}\cdot D} \f{T}{a_{1},\dots,a_{r};x} =& 1177 \pdiff{T\indices{_{i_{1}\dots i_{s}}^{i_{s+1}\dots i_{r}}}}{x^{r+1}}a^{i_{1}}\dots a^{i_{s}}a_{i_{s+1}}\dots a^{r}_{i_{r}} 1178 a^{i_{r+1}} \nonumber \\ 1179 &\hspace{-0.5in}+ \sum_{p=1}^{s}\pdiff{a^{i_{p}}}{x^{i_{r+1}}}T\indices{_{i_{1}\dots i_{s}}^{i_{s+1}\dots i_{r}}}a^{i_{1}}\dots 1180 \breve{a}^{i_{p}}\dots a^{i_{s}}a_{i_{s+1}}\dots a_{i_{r}}a^{i_{r+1}} \nonumber \\ 1181 &\hspace{-0.5in}+ \sum_{q=s+1}^{r}\pdiff{a_{i_{p}}}{x^{i_{r+1}}}T\indices{_{i_{1}\dots i_{s}}^{i_{s+1}\dots i_{r}}}a^{i_{1}}\dots 1182 a^{i_{s}}a_{i_{s+1}}\dots\breve{a}_{i_{q}}\dots a_{i_{r}}a^{i_{r+1}} \nonumber \\ 1183 =& \pdiff{T\indices{_{i_{1}\dots i_{s}}^{i_{s+1}\dots i_{r}}}}{x^{r+1}}a^{i_{1}}\dots a^{i_{s}}a_{i_{s+1}}\dots a^{r}_{i_{r}} 1184 a^{i_{r+1}} \nonumber \\ 1185 &\hspace{-0.5in}- \sum_{p=1}^{s}\Gamma_{i_{r+1}l_{p}}^{i_{p}}T\indices{_{i_{1}\dots i_{p}\dots i_{s}}^{i_{s+1} 1186 \dots i_{r}}}a^{i_{1}}\dots 1187 a^{l_{p}}\dots a^{i_{s}}a_{i_{s+1}}\dots a_{i_{r}}a^{i_{r+1}} \nonumber \\ 1188 &\hspace{-0.5in}+ \sum_{q=s+1}^{r}\Gamma_{i_{r+1}i_{q}}^{l_{q}}T\indices{_{i_{1}\dots i_{s}}^{i_{s+1}\dots i_{q} 1189 \dots i_{r}}}a^{i_{1}}\dots 1190 a^{i_{s}}a_{i_{s+1}}\dots a_{l_{q}}\dots a_{i_{r}}a^{i_{r+1}} . \label{eq126a} 1191 \end{align} 1192 From eq~(\ref{eq126a}) we obtain the components of the covariant derivative to be 1193 \begin{align} 1194 \pdiff{T\indices{_{i_{1}\dots i_{s}}^{i_{s+1}\dots i_{r}}}}{x^{r+1}} 1195 - \sum_{p=1}^{s}\Gamma_{i_{r+1}l_{p}}^{i_{p}}T\indices{_{i_{1}\dots i_{p}\dots i_{s}}^{i_{s+1}\dots i_{r}}} 1196 + \sum_{q=s+1}^{r}\Gamma_{i_{r+1}i_{q}}^{l_{q}}T\indices{_{i_{1}\dots i_{s}}^{i_{s+1}\dots i_{q}\dots i_{r}}}. 1197 \end{align} 1198 The component free form of the covariant derivative (the one used to calculate it in the code) is 1199 \begin{equation} 1200 \mathcal{D}_{a_{r+1}} \f{T}{a_{1},\dots,a_{r};x} \equiv \nabla T 1201 - \sum_{k=1}^{r}\f{T}{a_{1},\dots,\paren{a_{r+1}\cdot\nabla} a_{k},\dots,a_{r};x}. 1202 \end{equation} 1203 1204 \section{Representation of Multivectors in \emph{sympy}} 1205 1206 The \emph{sympy} python module offers a simple way of representing multivectors using linear 1207 combinations of commutative expressions (expressions consisting only of commuting \emph{sympy} objects) 1208 and non-commutative symbols. We start by defining $n$ non-commutative \emph{sympy} symbols as a basis for 1209 the vector space 1210 \begin{center} 1211 \T{(e\_1,...,e\_n) = symbols('e\_1,...,e\_n',commutative=False,real=True)} 1212 \end{center} 1213 1214 1215 Several software packages for numerical geometric algebra calculations are 1216 available from Doran-Lasenby group and the Dorst group. Symbolic packages for 1217 Clifford algebra using orthogonal bases such as 1218 $\eb_{i}\eb_{j}+\eb_{j}\eb_{i} = 2\eta_{ij}$, where $\eta_{ij}$ is a numeric 1219 array are available in Maple and Mathematica. The symbolic algebra module, 1220 {\em ga}, developed for python does not depend on an orthogonal basis 1221 representation, but rather is generated from a set of $n$ arbitrary 1222 symbolic vectors $\eb_{1},\eb_{2},\dots,\eb_{n}$ and a symbolic metric 1223 tensor $g_{ij} = \eb_{i}\cdot \eb_{j}$ (the symbolic metric can be symbolic constants 1224 or symbolic function in the case of a manifold). 1225 1226 In order not to reinvent the wheel all scalar symbolic algebra is handled by the 1227 python module \emph{sympy} and the abstract basis vectors are encoded as 1228 non-commuting \emph{sympy} symbols. 1229 1230 The basic geometric algebra operations will be implemented in python by defining 1231 a geometric algebra class, {\em Ga}, that performs all required geometric algebra an 1232 calculus operations on \emph{sympy} expressions of the form (Einstein summation convention) 1233 \be 1234 F +\sum_{r=1}^{n}F^{i_{1}\dots i_{r}}\eb_{i_{1}}\dots\eb_{i_{r}} 1235 \ee 1236 where the $F$'s are \emph{sympy} symbolic constants or functions of the 1237 coordinates and a multivector class, {\em Mv}, that wraps {\em Ga} and overloads the python operators to provide 1238 all the needed multivector operations as shown in Table~\ref{ops} 1239 where $A$ and $B$ are any two multivectors (In the case of 1240 $+$, $-$, $*$, $\W$, $|$, $<$, and $>$ the operation is also defined if $A$ or 1241 $B$ is a \emph{sympy} symbol or a \emph{sympy} real number). 1242 1243 \begin{table} 1244 \begin{center} 1245 \begin{tabular}{cc} 1246 $A+B$ & sum of multivectors \\ 1247 $A-B$ & difference of multivectors \\ 1248 $A*B$ & geometric product of multivectors \\ 1249 $A\W B$ & outer product of multivectors \\ 1250 $A|B$ & inner product of multivectors \\ 1251 $A<B$ & left contraction of multivectors \\ 1252 $A>B$ & right contraction of multivectors \\ 1253 $A/B$ & division of multivectors\footnotemark 1254 \end{tabular} 1255 \end{center} 1256 \caption{Multivector operations for GA}\label{ops} 1257 \end{table} 1258 \footnotetext{Division uses right multiplication by 1259 the inverse function, $A/B = AB^{-1}$, for those cases where $B^{-1}$ can 1260 be calculated ($B$, or $B^{2}$, or $BB^{\R}$ is a scalar).} 1261 Since \T{<} and \T{>} have no r-forms (in python for the \T{<} and \T{>} operators there are no \lstinline$__rlt__()$ and 1262 \lstinline$__rgt__()$ member functions to overload) 1263 we can only have mixed modes (sympy scalars and multivectors) if the first operand is a multivector. 1264 1265 1266 Except for \T{<} and \T{>} all the multivector operators have r-forms so that as long as one of the 1267 operands, left or right, is a multivector the other can be a multivector or a scalar (\emph{sympy} symbol or number). 1268 1269 \subsection{Operator Precedence}\label{OpPrec} 1270 \textbf{\textit{Note that the operator order precedence is determined by python and is not 1271 necessarily that used by geometric algebra. It is \emph{absolutely essential} to 1272 use parenthesis in multivector 1273 expressions containing \T{\^}, \T{|}, \T{<}, and/or \T{>}. As an example let 1274 \T{A} and \T{B} be any two multivectors. Then \T{A + A*B = A +(A*B)}, but 1275 \lstinline!A+A^B = (2*A)^B! since in python the \T{\^} operator has a lower precedence 1276 than the \T{+} operator. In geometric algebra the outer and inner products and 1277 the left and right contractions have a higher precedence than the geometric 1278 product and the geometric product has a higher precedence than addition and 1279 subtraction. In python the \T{\^}, \T{|}, \T{>}, and \T{<} all have a lower 1280 precedence than \T{+} and \T{-} while \T{*} has a higher precedence than 1281 \T{+} and \T{-}.}} 1282 1283 \textbf{Additional care has to be used when using the operators \T{!=} and \T{==} with 1284 the operators \T{<} and \T{>}. All these operators have the same precedence and are 1285 evaluated chained from left to right. To be completely safe for expressions such as 1286 \T{A == B} or \T{A != B} always user \T{(A) == (B)} and \T{(A) != (B)} if \T{A} or \T{B} 1287 contains a left, \T{<}, or right, \T{>}, contraction.} 1288 1289 For those users who wish to define a default operator precedence the functions 1290 \T{def\_prec()} and \T{GAeval()} are available in the module printer. 1291 1292 \lstinline$def_prec(gd,op_ord='<>|,^,*')$ 1293 \begin{quote} 1294 Define the precedence of the multivector operations. The function 1295 \T{def\_prec()} must be called from the main program and the 1296 first argument \T{gd} must be set to \T{globals()}. The second argument 1297 \T{op\_ord} determines the operator precedence for expressions input to 1298 the function \T{GAeval()}. The default value of \T{op\_ord} is \lstinline$'<>|,^,*'$. 1299 For the default value the \T{<}, \T{>}, and \T{|} operations have equal 1300 precedence followed by \T{\^}, and \T{\^} is followed by \T{*}. 1301 \end{quote} 1302 1303 \T{GAeval(s,pstr=False)} 1304 \begin{quote} 1305 The function \T{GAeval()} returns a multivector expression defined by the 1306 string \T{s} where the operations in the string are parsed according to 1307 the precedences defined by \T{def\_prec()}. \T{pstr} is a flag 1308 to print the input and output of \T{GAeval()} for debugging purposes. 1309 \T{GAeval()} works by adding parenthesis to the input string \T{s} with the 1310 precedence defined by \T{op\_ord='<>|,\^,*'}. Then the parsed string is 1311 converted to a \emph{sympy} expression using the python \T{eval()} function. 1312 For example consider where \T{X}, \T{Y}, \T{Z}, and \T{W} are multivectors 1313 1314 \begin{lstlisting}[numbers=none] 1315 def_prec(globals()) 1316 V = GAeval('X|Y^Z*W') 1317 \end{lstlisting} 1318 1319 The \emph{sympy} variable \T{V} would evaluate to \lstinline!((X|Y)^Z)*W!. 1320 \end{quote} 1321 1322 \section{Vector Basis and Metric}\label{BasisMetric} 1323 1324 The two structures that define the \T{metric} class (inherited by the 1325 geometric algebra class) are the 1326 symbolic basis vectors and the symbolic metric. The symbolic basis 1327 vectors are input as a string with the symbol name separated by spaces. For 1328 example if we are calculating the geometric algebra of a system with three 1329 vectors that we wish to denote as \T{a0}, \T{a1}, and \T{a2} we would define the 1330 string variable: 1331 1332 \begin{lstlisting}[numbers=none] 1333 basis = 'a0 a1 a2' 1334 \end{lstlisting} 1335 1336 that would be input into the geometric algebra class instantiation function, \T{Ga()}. The next step would be 1337 to define the symbolic metric for the geometric algebra of the basis we 1338 have defined. The default metric is the most general and is the matrix of 1339 the following symbols 1340 1341 \begin{equation}\label{metric} 1342 g = \lbrk 1343 \begin{array}{ccc} 1344 (a0.a0) & (a0.a1) & (a0.a2) \\ 1345 (a0.a1) & (a1.a1) & (a1.a2) \\ 1346 (a0.a2) & (a1.a2) & (a2.a2) \\ 1347 \end{array} 1348 \rbrk 1349 \end{equation} 1350 1351 1352 where each of the $g_{ij}$ is a symbol representing all of the dot 1353 products of the basis vectors. Note that the symbols are named so that 1354 $g_{ij} = g_{ji}$ since for the symbol function 1355 $(a0.a1) \ne (a1.a0)$. 1356 1357 Note that the strings shown in eq.~(\ref{metric}) are only used when the values 1358 of $g_{ij}$ are output (printed). In the ga module (library) 1359 the $g_{ij}$ symbols are stored in a member of the geometric algebra 1360 instance so that if \T{o3d} is a geometric algebra then \T{o3d.g} is 1361 the metric tensor ($g_{ij} = $\T{o3d.g[i,j]}) for that algebra. 1362 1363 The default definition of $g$ can be overwritten by specifying a string 1364 that will define $g$. As an example consider a symbolic representation 1365 for conformal geometry. Define for a basis 1366 1367 \begin{lstlisting}[numbers=none] 1368 basis = 'a0 a1 a2 n nbar' 1369 \end{lstlisting} 1370 1371 and for a metric 1372 1373 \begin{lstlisting}[numbers=none] 1374 g = '# # # 0 0, # # # 0 0, # # # 0 0, 0 0 0 0 2, 0 0 0 2 0' 1375 \end{lstlisting} 1376 1377 then calling \T{cf3d = Ga(basis,g=g)} would initialize the metric tensor 1378 1379 \begin{equation} 1380 g = \lbrk 1381 \begin{array}{ccccc} 1382 (a0.a0) & (a0.a1) & (a0.a2) & 0 & 0\\ 1383 (a0.a1) & (a1.a1) & (a1.a2) & 0 & 0\\ 1384 (a0.a2) & (a1.a2) & (a2.a2) & 0 & 0 \\ 1385 0 & 0 & 0 & 0 & 2 \\ 1386 0 & 0 & 0 & 2 & 0 1387 \end{array} 1388 \rbrk 1389 \end{equation} 1390 1391 for the \T{cf3d} (conformal 3-d) geometric algebra. 1392 1393 Here we have specified that \T{n} and \T{nbar} are orthogonal to all the 1394 \T{a}'s, \T{(n.n) = (nbar.nbar) = 0}, and \T{(n.nbar) = 2}. Using 1395 \T{\#} in the metric definition string just tells the program to use the 1396 default symbol for that value. 1397 1398 When \T{Ga} is called multivector representations of the basis local to 1399 the program are instantiated. For the case of an orthogonal 3-d vector 1400 space that means the 1401 symbolic vectors named \T{a0}, \T{a1}, and \T{a2} are created. We can 1402 instantiate the geometric algebra and obtain the basis vectors with - 1403 1404 \begin{lstlisting}[numbers=none] 1405 o3d = Ga('a_1 a_2 a_3',g=[1,1,1]) 1406 (a_1,a_2,a_3) = o3d.mv() 1407 \end{lstlisting} 1408 1409 or use the \T{Ga.build()} function - 1410 1411 \begin{lstlisting}[numbers=none] 1412 (o3d,a_1,a_2,a_3) = Ga.build('a_1 a_2 a_3',g=[1,1,1]) 1413 \end{lstlisting} 1414 1415 Note that the python variable name for a basis vector does not have to 1416 correspond to the name give in \T{Ga()} or \T{Ga.build()}, one may wish to use a 1417 shortened python variable name to reduce programming (typing) errors, for 1418 example one could use - 1419 1420 \begin{lstlisting}[numbers=none] 1421 (o3d,a1,a2,a3) = Ga.build('a_1 a_2 a_3',g=[1,1,1]) 1422 \end{lstlisting} 1423 1424 or 1425 1426 \begin{lstlisting}[numbers=none] 1427 (st4d,g0,g1,g2,g3) = Ga.build('gamma_0 gamma_1 gamma_2 gamma_3',\ 1428 g=[1,-1,-1,-1]) 1429 \end{lstlisting} 1430 1431 for Minkowski space time. 1432 1433 If the latex printer is used \T{e1} would print as $\bm{e_{1}}$ 1434 and \T{g1} as $\bm{\gamma_{1}}$. 1435 1436 \notebox{ 1437 Additionally \T{Ga()} and \T{Ga.build()} has simplified options for naming a set of basis vectors and for 1438 inputing an orthogonal basis. 1439 \vspace{4pt} 1440 If one wishes to name the basis vectors $\bm{e}_{x}$, $\bm{e}_{y}$, and 1441 $\bm{e}_{z}$ then set \T{basis='e*x|y|z'} or to name $\bm{\gamma}_{t}$, 1442 $\bm{\gamma}_{x}$, $\bm{\gamma}_{y}$, and $\bm{\gamma}_{z}$ then set 1443 \T{basis='gamma*t|x|y|z'}. 1444 For the case of an orthogonal basis if the signature of the 1445 vector space is $(1,1,1)$ (Euclidean 3-space) set \T{g=[1,1,1]} or if it 1446 is $(1,-1,-1,-1)$ (Minkowski 4-space) set \T{g=[1,-1,-1,-1]}. If \T{g} is a 1447 function of position then \T{g} can be entered as a \emph{sympy} matrix with \emph{sympy} 1448 functions as the entries of the matrix or as a list of functions for the 1449 case of a orthogonal metric. In the case of spherical coordinates we have 1450 \T{g=[1,r**2,r**2*sin(th)**2]}. 1451 } 1452 1453 \section{Representation and Reduction of Multivector Bases} 1454 1455 In our symbolic geometric algebra all multivectors 1456 can be obtained from the symbolic basis vectors we have input, via the 1457 different operations available to geometric algebra. The first problem we have 1458 is representing the general multivector in terms terms of the basis vectors. To 1459 do this we form the ordered geometric products of the basis vectors and develop 1460 an internal representation of these products in terms of python classes. The 1461 ordered geometric products are all multivectors of the form 1462 $a_{i_{1}}a_{i_{2}}\dots a_{i_{r}}$ where $i_{1}<i_{2}<\dots <i_{r}$ 1463 and $r \le n$. We call these multivectors bases and represent them 1464 internally with non-commutative symbols so for example $a_{1}a_{2}a_{3}$ 1465 is represented by 1466 1467 \begin{lstlisting}[numbers=none] 1468 Symbol('a_1*a_2*a_3',commutative=False) 1469 \end{lstlisting} 1470 1471 In the simplest case of two basis vectors \T{a\_1} and \T{a\_2} we have a list of 1472 bases 1473 1474 \begin{lstlisting}[numbers=none] 1475 self.bases = [[Symbol('a_1',commutative=False,real=True),\ 1476 Symbol('a_2',commutative=False,real=True)],\ 1477 [Symbol('a_1*a_2',commutative=False,real=True)]] 1478 \end{lstlisting} 1479 1480 For the case of the basis blades we have 1481 1482 \begin{lstlisting}[numbers=none] 1483 self.blades = [[Symbol('a_1',commutative=False,real=True),\ 1484 Symbol('a_2',commutative=False,real=True)],\ 1485 [Symbol('a_1^a_2',commutative=False,real=True)]] 1486 \end{lstlisting} 1487 1488 \notebox{ 1489 For all grades/pseudo-grades greater than one (vectors) the \T{*} in the name of the base symbol is 1490 replaced with a \T{\^} in the name of the blade symbol so that for all basis bases and 1491 blades of grade/pseudo-grade greater than one there are different symbols for the corresponding 1492 bases and blades.} 1493 1494 The index tuples for the bases of each pseudo grade and each grade for the case of dimension 3 is 1495 1496 \begin{lstlisting}[numbers=none] 1497 self.indexes = (((0,),(1,),(2,)),((0,1),(0,2),(1,2)),((0,1,2))) 1498 \end{lstlisting} 1499 1500 Then the non-commutative symbol representing each base is constructed from each index tuple. 1501 For example for \verb|self.indexes[1][1]| the symbol is \verb|Symbol('a_1*a_3',commutative=False)|. 1502 1503 \notebox{In the case that the metric tensor is diagonal (orthogonal basis vectors) both base and blade 1504 bases are identical and fewer arrays and dictionaries need to be constructed.} 1505 1506 1507 \section{Base Representation of Multivectors} 1508 1509 In terms of the bases defined as non-commutative \emph{sympy} symbols the general multivector 1510 is a linear combination (scalar \emph{sympy} coefficients) of bases so that for the case 1511 of two bases the most general multivector is given by - 1512 1513 \begin{lstlisting}[numbers=none] 1514 A = A_0+A__1*self.bases[1][0]+A__2*self.bases[1][1]+\ 1515 A__12*self.bases[2][0] 1516 \end{lstlisting} 1517 1518 If we have another multivector \T{B} to multiply with \T{A} we can calculate the product in 1519 terms of a linear combination of bases if we have a multiplication table for the bases. 1520 1521 \section{Blade Representation of Multivectors} 1522 1523 Since we can now calculate the symbolic geometric product of any two 1524 multivectors we can also calculate the blades corresponding to the product of 1525 the symbolic basis vectors using the formula 1526 1527 \begin{equation} 1528 A_{r}\W b = \half\lp A_{r}b+\lp -1 \rp^{r}bA_{r} \rp, 1529 \end{equation} 1530 1531 where $A_{r}$ is a multivector of grade $r$ and $b$ is a 1532 vector. For our example basis the result is shown in Table~\ref{bladexpand}. 1533 1534 \begin{table}[h] 1535 \begin{lstlisting}[numbers=none] 1536 1 = 1 1537 a0 = a0 1538 a1 = a1 1539 a2 = a2 1540 a0^a1 = {-(a0.a1)}1+a0a1 1541 a0^a2 = {-(a0.a2)}1+a0a2 1542 a1^a2 = {-(a1.a2)}1+a1a2 1543 a0^a1^a2 = {-(a1.a2)}a0+{(a0.a2)}a1+{-(a0.a1)}a2+a0a1a2 1544 \end{lstlisting} 1545 \caption{Bases blades in terms of bases.}\label{bladexpand} 1546 \end{table} 1547 1548 The important thing to notice about Table~\ref{bladexpand} is that it is a 1549 triagonal (lower triangular) system of equations so that using a simple back 1550 substitution algorithm we can solve for the pseudo bases in terms of the blades 1551 giving Table~\ref{baseexpand}. 1552 1553 \begin{table} 1554 \begin{lstlisting}[numbers=none] 1555 1 = 1 1556 a0 = a0 1557 a1 = a1 1558 a2 = a2 1559 a0a1 = {(a0.a1)}1+a0^a1 1560 a0a2 = {(a0.a2)}1+a0^a2 1561 a1a2 = {(a1.a2)}1+a1^a2 1562 a0a1a2 = {(a1.a2)}a0+{-(a0.a2)}a1+{(a0.a1)}a2+a0^a1^a2 1563 \end{lstlisting} 1564 \caption{Bases in terms of basis blades.}\label{baseexpand} 1565 \end{table} 1566 1567 Using Table~\ref{baseexpand} and simple substitution we can convert from a base 1568 multivector representation to a blade representation. Likewise, using Table~\ref{bladexpand} 1569 we can convert from blades to bases. 1570 1571 Using the blade representation it becomes simple to program functions that will 1572 calculate the grade projection, reverse, even, and odd multivector functions. 1573 1574 Note that in the multivector class \T{Mv} there is a class variable for each 1575 instantiation, \T{self.is\_blade\_rep}, that is set to \T{False} for a base representation 1576 and \T{True} for a blade representation. One needs to keep track of which 1577 representation is in use since various multivector operations require conversion 1578 from one representation to the other. 1579 1580 \notebox{ 1581 When the geometric product of two multivectors is calculated the module looks to 1582 see if either multivector is in blade representation. If either is the result of 1583 the geometric product is converted to a blade representation. One result of this 1584 is that if either of the multivectors is a simple vector (which is automatically a 1585 blade) the result will be in a blade representation. If \T{a} and \T{b} are vectors 1586 then the result \T{a*b} will be \lstinline$(a.b)+a^b$ or simply \lstinline$a^b$ if \T{(a.b) = 0}.} 1587 1588 1589 1590 1591 1592 \chapter{Module Components} 1593 1594 The geometric algebra module consists of the following files and classes 1595 \begin{center} 1596 \begin{longtable}{ccl} 1597 \bf{File} & \bf{Classes} & {\bf Usage} \\ \Xhline{2\arrayrulewidth} 1598 \T{metric.py} & \T{Metric} & \parbox[t]{4in}{Instantiates metric tensor and derivatives of basis vectors. Normalized basis if required.} \\ \hline 1599 \T{ga.py} & \T{Ga} & \parbox[t]{4in}{Instantiates geometric algebra (inherits \T{Metric}), generates bases, blades, multiplication 1600 tables, reciprocal basis, and left and right geometric derivative operators.} \\ \cline{2-3} 1601 & \T{Sm} & \parbox[t]{4in}{Instantiates geometric algebra for submainfold (inherits \T{Ga}).} \\ \hline 1602 \T{mv.py} & \T{Mv} & \parbox[t]{4in}{Instantiates multivector.}\\ \cline{2-3} 1603 & \T{Dop} & \parbox[t]{4in}{Instantiates linear multivector differential operator.}\\ \hline 1604 \T{lt.py} & \T{Lt} & \parbox[t]{4in}{Instantiates multivector linear transformation.}\\ \hline 1605 \T{printer.py} & \T{Eprint} & \parbox[t]{4in}{Starts enhanced text printing on ANSI terminal (requires \T{ConEmu} on Windows).}\\ \cline{2-3} 1606 & \T{GaPrinter} & \parbox[t]{4in}{Text printer for all geometric algebra classes (inherits from \T{sympy} 1607 \T{StringPrinter}).}\\ \cline{2-3} 1608 & \T{GaLatexPrinter} & \parbox[t]{4in}{\LaTeX printer for all geometric algebra classes (inherits from \T{sympy} 1609 \T{LatexPrinter}).}\\ \hline 1610 \end{longtable} 1611 \end{center} 1612 1613 \section{Instantiating a Geometric Algebra} 1614 1615 The geometric algebra class is instantiated with 1616 1617 \T{Ga(basis,g=None,coords=None,X=None,norm=False,sig='e',Isq='-',wedge=True,debug=False)} 1618 \begin{quote} 1619 The \T{basis} and \T{g} parameters were described in section~\ref{BasisMetric}. 1620 If the metric is a function of position, if we have multivector fields, or we 1621 wish to calculate geometric derivatives a coordinate set, \T{coords}, is required. 1622 \T{coords} is a list of \emph{sympy} symbols. For the case of instantiating a 3-d geometric 1623 algebra in spherical coordinates we have 1624 \begin{lstlisting}[numbers=none] 1625 (r, th, phi) = coords = symbols('r,theta,phi', real=True) 1626 basis = 'e_r e_theta e_phi' 1627 g = [1, r**2, r**2*sin(th)**2] 1628 sp3d = Ga(basis,g=g,coords=coords,norm=True) 1629 \end{lstlisting} 1630 The input \T{X} allows the metric to be input as a vector manifold. 1631 \T{X} is a list of functions of \T{coords} of dimension, $m$, equal to or greater 1632 than the number of coordinates. If \T{g=None} it is assumed that \T{X} is a 1633 vector in an $m$-dimensional orthonormal Euclidean vector space. If it is wished 1634 the embedding vector space to be non-Euclidean that condition is specified with 1635 \T{g}. For example if we wish the embedding space to be a 5-dimensional Minkowski 1636 space then \T{g=[-1,1,1,1,1]}. Then the Ga class uses \T{X} to calculate the 1637 manifold basis vectors as a function of the coordinates and from them the metric 1638 tensor.\footnote{Since \T{X} or the metric tensor can be functions of coordinates 1639 the vector space that the geometric algebra is constructed from is not necessarily 1640 flat so that the geometric algebra is actually constructed on the tangent space of 1641 the manifold which is a vector space.} 1642 1643 If \T{norm=True} the basis vectors of the manifold are normalized so that the 1644 absolute values of the squares of the basis vectors are one. \emph{Currently you 1645 should only use this option for diagonal metric tensors, and even there due so 1646 with caution, due to the possible 1647 problems with taking the square root of a general \emph{sympy} expression (one that has an 1648 unknown sign).} 1649 1650 \textbf{When a geometric algebra is created the unnormalized metric tensor is always saved 1651 so that submanifolds created from the normalized manifold can be calculated correctly.} 1652 1653 \T{sig} indicates the signature of the vector space in the following ways.\footnote{The 1654 signature of the vector space, $(p,q)$, is required to determine whether the square of 1655 the normalized pseudoscalar, $I$, is $+1$ or $-1$. In the future the metric tensor would 1656 be required to create a generalized spinor \cite[p.~106]{Hestenes}.} 1657 \begin{enumerate} 1658 \item If the metric tensor is purely numerical (the components are not symbolic or 1659 functions of the coordinates) and is diagonal (orthogonal basis vectors) the 1660 signature is computed from the metric tensor. 1661 \item If the metric tensor is not purely numerical and orthogonal the following hints 1662 are used (dimension of vector space is $n$) 1663 \begin{enumerate} 1664 \item \T{sig='e'} the default hint assumes the signature is for a Euclidean space 1665 with signature $(n,0)$. 1666 \item \T{sig='m+'} assumes the signature if for the Minkowski space $(n-1,1)$. 1667 \item \T{sig='m-'} assumes the signature if for the Minkowski space $(1,n-1)$. 1668 \item \T{sig=p} where \T{p} is an integer $p\le n$ and the signature it $(p,n-p)$. 1669 \end{enumerate} 1670 \end{enumerate} 1671 If the metric tensor contains no symbolic constants, but is a function of the coordinates, it is 1672 possible to determine the signature of the metric numerically by specifying a allowed numerical 1673 coordinate tuple due to the invariance of the signature. This will be implemented in the future. 1674 1675 Currently one need not be concerned about inputting \T{sig} unless one in using the \emph{Ga} member 1676 function \T{Ga.I()} or the functions \T{Mv.dual()} or \T{cross()} which also use \T{Ga.I()}. 1677 1678 If $I^{2}$ is numeric it is calculated if it is not numeric then \T{Isq='-'} is the sign of the square of the pseudo-scalar. This is needed 1679 for some operations. The default is chosen for the case of a general 3D Euclidean metric. 1680 1681 If \T{wedge=True} the basis blades of a multivector are printed using the ``\T{\^}'' symbol between basis vectors. If \T{wedge=False} the 1682 subscripts of each individual basis vector (assuming that the basis vector symbols are of the form root symbol with a subscript\footnote{Using 1683 {\LaTeX} output if a basis vector is denoted by $\eb_{x}$ then $\eb$ is the root symbol and $x$ is the subscript}). For example in three 1684 dimensions if the basis vectors are $\eb_{x}$, $\eb_{y}$, and $\eb_{z}$ the grade 3 basis blade would be printed as $\eb_{xyz}$. 1685 1686 If \T{debug=True} the data structures required to initialize the Ga class 1687 are printed out. 1688 1689 To get the basis vectors for \T{sp3d} we would have to use the member function 1690 \T{Ga.mv()} in the form 1691 \begin{lstlisting}[numbers=none] 1692 (er,eth,ephi) = sp3d.mv() 1693 \end{lstlisting} 1694 \end{quote} 1695 1696 To access the reciprocal basis vectors of the geometric algebra use the member function \T{mvr()} 1697 1698 \T{Ga.mvr(norm='True')} 1699 \begin{quote} 1700 \T{Ga.mvr(norm)} returns the reciprocal basis vectors as a tuple. This allows the programmer to 1701 attach any python variable names to the reciprocal basis vectors that is convenient. For example 1702 (demonstrating the use of both \T{mv()} and \T{mvr()}) 1703 \begin{lstlisting} 1704 (e_x,e_y,e_z) = o3d.mv() 1705 (e__x,e__y,e__z) = o3d.mvr() 1706 \end{lstlisting} 1707 If \T{norm='True'} or the basis vectors are orthogonal 1708 the dot product of the basis vector and the corresponding reciprocal basis vector is one 1709 $\paren{e_{i}\cdot e^{j}=\delta_{i}^{j}}$. If \T{norm='False'} and the basis is non-orthogonal 1710 The dot product of the basis vector and the corresponding reciprocal basis vector is the square of the 1711 pseudo scalar, $I^{2}$, of the geometric algebra $\paren{e_{i}\cdot e^{j}=E^{2}\delta_{i}^{j}}$. 1712 \end{quote} 1713 1714 In addition to the basis vectors, if coordinates are defined for the geometric algebra, the 1715 left and right geometric derivative operators are calculated and accessed with the \T{Ga} 1716 member function \T{grads()}. 1717 1718 \T{Ga.grads()} 1719 \begin{quote} 1720 \T{Ga.grads()} returns a tuple with the left and right geometric derivative operators. A 1721 typical usage would be 1722 \begin{lstlisting}[numbers=none] 1723 (grad,rgrad) = sp3d.grads() 1724 \end{lstlisting} 1725 for the spherical 3-d geometric algebra. The left derivative $\paren{\T{grad} =\bm{\nabla}}$ and the 1726 right derivative $\paren{\T{rgrad} = \bm{\bar{\nabla}}}$ have been explained in section~\ref{ldops}. Again 1727 the names \T{grad} and \T{rgrad} used in a program are whatever the user chooses them to be. In the previous 1728 example \T{grad} and \T{rgrad} are used. 1729 \end{quote} 1730 1731 an alternative instantiation method is 1732 1733 \T{Ga.build(basis, g=None, coords=None, X=None, norm=False, debug=False)} 1734 \begin{quote} 1735 The input parameters for \T{Ga.build()} are the same as for \T{Ga()}. The difference is 1736 that in addition to returning the geometric algebra \T{Ga.build()} returns the basis vectors 1737 at the same time. Using \T{Ga.build()} in the previous example gives 1738 \begin{lstlisting} 1739 (r, th, phi) = coords = symbols('r,theta,phi', real=True) 1740 basis = 'e_r e_theta e_phi' 1741 g = [1, r**2, r**2*sin(th)**2] 1742 (sp3d,er,eth,ephi) = Ga.build(basis,g=g,coord=coords,norm=True) 1743 \end{lstlisting} 1744 1745 \end{quote} 1746 1747 To access the pseudo scalar of the geometric algebra us the member function \T{I()}. 1748 1749 \T{Ga.I()} 1750 \begin{quote} 1751 \T{Ga.I()} returns the normalized pseudo scalar $\paren{\abs{I^{2}}=1}$ for the 1752 geometric algebra. For example $I = \mbox{\T{o3d.I()}}$ for the \T{o3d} geometric 1753 algebra. This function requires the signature of the vector space (see instantiating 1754 a geometric algebra). 1755 \end{quote} 1756 1757 \T{Ga.E()} 1758 \begin{quote} 1759 \T{Ga.E()} returns the unnormalized pseudo scalar $E_{n} = \bm{e}_{1}\W\dots\W\bm{e}_{n}$ 1760 for the geometric algebra. 1761 \end{quote} 1762 1763 In general we have defined member functions of the \T{Ga} class that will instantiate objects 1764 of other classes since the objects of the other classes are all associated with a particular 1765 geometric algebra object. Thus we have 1766 \begin{center} 1767 \begin{tabular}{ccc} 1768 Object & Class & \T{Ga} method \\ 1769 multivector & \T{Mv} & \T{mv} \\ 1770 submanifold & \T{Sm} & \T{sm} \\ 1771 linear transformation & \T{Lt} & \T{lt} \\ 1772 differential operator & \T{Dop} & \T{dop} 1773 \end{tabular} 1774 \end{center} 1775 for the instantiation of various objects from the \T{Ga} class. This means that in order to 1776 instantiate any of these objects we need only to import \T{Ga} into our program. 1777 1778 \section{Instantiating a Multivector}\label{makeMV} 1779 1780 Since we need to associate each multivector with the geometric algebra that contains it 1781 we use a member function of Ga to instantiate every multivector\footnote{There is a 1782 multivector class, \T{Mv}, but in order the insure that every multivector is associated 1783 with the correct geometric algebra we always use the member function \T{Ga.mv} to instantiate 1784 the multivector.} The multivector is instantiated with: 1785 1786 \T{Ga.mv(name, mode, f=False)} 1787 \begin{quote} 1788 As an example of both instantiating a geometric algebra and multivectors consider the 1789 following code fragment for a 3-d Euclidean geometric algebra. 1790 \begin{lstlisting} 1791 from sympy import symbols 1792 from ga import Ga 1793 (x, y, z) = coords = symbols('x,y,z',real=True) 1794 o3d = Ga('e_x e_y e_z', g=[1,1,1], coords=coords) 1795 (ex, ey, ez) = o3d.mv() 1796 V = o3d.mv('V','vector',f=True) 1797 f = o3d.mv(x*y*z) 1798 B = o3d.mv('B',2) 1799 \end{lstlisting} 1800 First consider the multivector instantiation in line 6,\newline 1801 \centerline{\T{V = o3d.mv('V','vector',f=True)}}.\newline 1802 Here 1803 a 3-dimensional multivector field that is a function of \T{x}, \T{y}, and \T{z} (\T{f=True}) is 1804 being instantiated. If latex output were used (to be discussed later) the multivector 1805 \T{V} would be displayed as 1806 \be 1807 V^{x}\eb_{x} + V^{y}\eb_{y} + V^{z}\eb_{z} 1808 \ee 1809 Where the coefficients of the basis vectors are generalized \emph{sympy} functions of the 1810 coordinates. If \T{f=(x,y)} then the coefficients would be functions of \T{x} and \T{y}. 1811 In general is \T{f} is a tuple of symbols then the coefficients of the basis would be functions of those 1812 symbols. The superscripts\footnote{Denoted in text output by \T{A\_\_x}, etc. so 1813 that for text output \T{A} would be printed as \T{A\_\_x*e\_x+A\_\_y*e\_y+A\_\_z*e\_z}.} are formed 1814 from the coordinate symbols or if there are no coordinates from the subscripts of 1815 the basis vectors. The types of name and modes available for multivector instantiation are 1816 \begin{center} 1817 \begin{tabular}{ccc} 1818 \T{name} & \T{mode} & result \\ 1819 string s & \T{`scalar'} & symbolic scalar of value Symbol(s) \\ 1820 string s &\T{`vector'} & symbolic vector \\ 1821 string s & \T{`grade2'} or \T{`bivector'} & symbolic bivector \\ 1822 string s & \T{r} (integer) & symbolic r-grade multivector \\ 1823 string s & \T{`pseudo'} & symbolic pseudoscalar \\ 1824 string s & \T{`spinor'} & symbolic even multivector \\ 1825 string s & \T{`mv'} & symbolic general multivector \\ 1826 scalar c & None & zero grade multivector with coefficient value c 1827 \end{tabular} 1828 \end{center} 1829 Line 5 of the previous listing illustrates the case of using the \T{mv} member function with 1830 no arguments. The code does not return a multivector, but rather a tuple or the basis vectors of the geometric algebra \T{o3d}. 1831 The elements of the tuple then can 1832 be used to construct multivectors, or multivector fields through the operations 1833 of addition, subtraction, multiplication (geometric, inner, and outer products and left and right contraction). 1834 As an example we could construct the vector function 1835 \begin{lstlisting}[numbers=none] 1836 F = x**2*ex + z*ey + x*y*ez 1837 \end{lstlisting} 1838 \vspace{-12pt}or the bivector function 1839 \begin{lstlisting}[numbers=none] 1840 B = z*(ex^ey) + y*(ey^ez) + y*(ex^ez). 1841 \end{lstlisting} 1842 \vspace{-7pt}Line 7 is an example of instantiating a multivector scalar function (a multivector with only a scalar part). If 1843 we print \T{f} the result is \T{x*y*z}. Line 8 is an example of instantiating a grade $r$ (in the example a grade 2) multivector 1844 where 1845 \begin{equation} 1846 B = B^{xy}\bm{e}_{x}\W\bm{e}_{y}+B^{yz}\bm{e}_{y}\W\bm{e}_{z}+B^{xz}\bm{e}_{x}\W\bm{e}_{z}. 1847 \end{equation} 1848 \end{quote} 1849 If one wished to calculate the left and right geometric derivatives of \T{F} and \T{B} the required code would be 1850 \begin{lstlisting} 1851 (grad,rgrad) = o3d.grads() 1852 dF = grad*F 1853 dB = grad*B 1854 dFr = F*rgrad 1855 dBr = B*rgrad. 1856 \end{lstlisting} 1857 \T{dF}, \T{dB}, \T{dFr}, and \T{dBr} are all multivector functions. For the code where the order of the operations are 1858 reversed 1859 \begin{lstlisting} 1860 (grad,rgrad) = o3d.grads() 1861 dFop = F*grad 1862 dBop = B*grad 1863 dFrop = rgrad*F 1864 dBrop = rgrad*B. 1865 \end{lstlisting} 1866 \T{dFop}, \T{dBop}, \T{dFrop}, and \T{dBrop} are all multivector differential operators (again see section~\ref{ldops}). 1867 1868 \section{Backward Compatibility Class MV} 1869 1870 In order to be backward compatible with older versions of \emph{galgebra} we introduce the class MV which is inherits it's functions from 1871 then class Mv. To instantiate a geometric algebra using MV use the static function 1872 1873 \begin{CenteredBox} 1874 \vspace{12pt}\begin{lstlisting} 1875 MV.setup(basis, metric=None, coords=None, rframe=False,\ 1876 debug=False,curv=(None,None))} 1877 \end{lstlisting}\vspace{12pt} 1878 \end{CenteredBox} 1879 1880 1881 \vspace{-6pt} 1882 \begin{quote} 1883 This function allows a single geometric algebra to be created. If the function is called more than once the old geometric algebra 1884 is overwritten by the new geometric algebra. The named input \T{metric} is the same as the named input \T{g} in the current 1885 version of \emph{galgebra}. Likewise, \T{basis}, \T{coords}, and \T{debug} are the same in the old and current versions of 1886 \emph{galgebra}\footnote{If the metric is input as a list or list or lists the object is no longer quoted (input as a string). 1887 For example the old \T{metric='[1,1,1]'} becomes \T{metric=[1,1,1]}.}. Due to improvements in \emph{sympy} the inputs 1888 \T{rframe} and \T{curv[1]} are no longer required. \T{curv[0]} is 1889 the vector function (list or tuple of scalar functions) of the coordinates required to define a vector manifold. For 1890 compatibility with the old version of \emph{galgebra} if \T{curv} is used \T{metric} should be a orthonormal Euclidean 1891 metric of the same dimension as \T{curv[0]}. It is strongly suggested that one use the new methods of defining a geometric algebra 1892 on a manifold. 1893 \end{quote} 1894 1895 \T{MV(base, mvtype, fct=False, blade\_rep=True)} 1896 1897 \begin{quote} 1898 For the instantiation of multivector using \T{MV} the \T{base} and \T{mvtype} arguments are the same as for new methods of 1899 multivector instantiation. The \T{fct} input is the same and the \T{g} input in the new methods. \T{blade\_rep} is not used 1900 in the new methods so setting \T{blade\_rep=False} will do nothing. Effectively \T{blade\_rep=False} was not used in the old 1901 examples. 1902 \end{quote} 1903 1904 \T{Fmt(self, fmt=1, title=None)} 1905 1906 \begin{quote} 1907 \T{Fmt} in \T{MV} has inputs identical to \T{Fmt} in \T{Mv} except that if \T{A} is a multivector then \T{A.Fmt(2,'A')} 1908 executes a print statement from \T{MV} and returns \T{None}, while from \T{Mv}, \T{A.Fmt(2,'A')} returns a string so that 1909 the function is compatible with use in \emph{ipython notebook}. 1910 \end{quote} 1911 1912 1913 \section{Basic Multivector Class Functions} 1914 1915 If we can instantiate multivectors we can use all the multivector class functions as described as follows. 1916 1917 \T{blade\_coefs(self,basis\_lst)} 1918 \begin{quote} 1919 Find coefficients (sympy expressions) of multivector basis blade expansion corresponding to basis 1920 blades in \T{basis\_lst}. For example if $V = V^{x}\eb_{x}+V^{y}\eb_{x}+V^{z}\eb_{x}$ Then 1921 $V.blade\_coefs([\eb_{z},\eb_{x}]) = [V^{z},V^{x}]$ or if $B = B^{xy}\eb_{x}\W\eb_{y}+V^{yz}\eb_{y}\W\eb_{z}$ 1922 then $B.blade\_coefs([\eb_{x}\W\eb_{y}]) = [B^{xy}]$. 1923 \end{quote} 1924 1925 \T{convert\_to\_blades(self)} 1926 \begin{quote} 1927 Convert multivector from the base representation to the blade representation. 1928 If multivector is already in blade representation nothing is done. 1929 \end{quote} 1930 1931 \T{convert\_from\_blades(self)} 1932 \begin{quote} 1933 Convert multivector from the blade representation to the base representation. 1934 If multivector is already in base representation nothing is done. 1935 \end{quote} 1936 1937 \T{diff(self,var)} 1938 \begin{quote} 1939 Calculate derivative of each multivector coefficient with respect to 1940 variable \T{var} and form new multivector from coefficients. 1941 \end{quote} 1942 1943 \T{dual(self)} 1944 \begin{quote} 1945 The mode of the \T{dual()} function is set by the \T{Ga} class static member function, \T{GA.dual\_mode(mode='I+')} of the \T{GA} geometric 1946 galgebra which sets the following return values ($I$ is the pseudo-scalar for the geometric algebra \T{GA}) 1947 \begin{center} 1948 \begin{tabular}{cc} 1949 \T{mode} & Return Value \\ 1950 \T{'+I'} & $IA$ \\ 1951 \T{'I+'} & $AI$ \\ 1952 \T{'-I'} & $-IA$ \\ 1953 \T{'I-'} & $-AI$ \\ 1954 \T{'+Iinv'} & $I^{-1}A$ \\ 1955 \T{'Iinv+'} & $AI^{-1}$ \\ 1956 \T{'-Iinv'} & $-I^{-1}A$ \\ 1957 \T{'Iinv-'} & $-AI^{-1}$ 1958 \end{tabular} 1959 \end{center} 1960 1961 For example if the geometric algebra is \T{o3d}, \T{A} is a multivector in \T{o3d}, and we wish to use \T{mode='I-'}. We set 1962 the mode with the function 1963 \T{o3d.dual('I-')} and get the dual of \T{A} with the function \T{A.dual()} which returns $-AI$. 1964 1965 If \T{o3d.dual(mode)} is not called the default for the dual mode is \T{mode='I+'} and \T{A*I} is returned. 1966 1967 Note that \T{Ga.dual(mode)} used the function \T{Ga.I()} to calculate the normalized pseudoscalar. Thus if the metric tensor is 1968 not numerical and orthogonal the correct hint for then\T{sig} input of the \emph{Ga} constructor is required. 1969 \end{quote} 1970 1971 \T{even(self)} 1972 \begin{quote} 1973 Return the even grade components of the multivector. 1974 \end{quote} 1975 1976 \T{exp(self,hint='-')} 1977 \begin{quote} 1978 If $A$ is a multivector then $e^{A}$ is defined for any $A$ via the series expansion for $e$. However as 1979 a practical matter we only have a simple closed form formula for $e^{A}$ if $A^{2}$ is a scalar.\footnote{In the 1980 future it should be possible to generate closed form expressions for $e^{A}$ if $A^{r}$ is a scalar for some 1981 interger $r$.} If $A^{2}$ is a scalar and we know the sign of $A^{2}$ we have the following formulas for $e^{A}$. 1982 \begin{center} 1983 \begin{tabular}{lll} 1984 $A^{2} > 0$: & & \\ 1985 & $A = \sqrt{A^{2}} \bfrac{A}{\sqrt{A^{2}}}$, & $e^{A} = \f{\cosh}{\sqrt{A^{2}}}+\f{\sinh}{\sqrt{A^{2}}}\bfrac{A}{\sqrt{A^{2}}}$ \\ 1986 $A^{2} < 0$: & & \\ 1987 & $A = \sqrt{-A^{2}} \bfrac{A}{\sqrt{-A^{2}}}$, & $e^{A} = \f{\cos}{\sqrt{-A^{2}}}+\f{\sin}{\sqrt{-A^{2}}}\bfrac{A}{\sqrt{-A^{2}}}$ \\ 1988 $A^{2} = 0$: & & \\ 1989 & & $e^{A} = 1 + A$ 1990 \end{tabular} 1991 \end{center} 1992 The hint is required for symbolic multivectors $A$ since in general \emph{sympy} cannot determine if 1993 $A^{2}$ is positive or negative. If $A$ is purely numeric the hint is ignored since the sign can be calculated. 1994 \end{quote} 1995 1996 \T{expand(self)} 1997 \begin{quote} 1998 Return multivector in which each coefficient has been expanded using 1999 \emph{sympy} \T{expand()} function. 2000 \end{quote} 2001 2002 \T{factor(self)} 2003 \begin{quote} 2004 Apply the \T{sympy} \T{factor} function to each coefficient of the multivector. 2005 \end{quote} 2006 2007 \T{Fmt(self, fmt=1,title=None)} 2008 \begin{quote} 2009 Fuction to print multivectors in different formats where 2010 \begin{center} 2011 \begin{tabular}{cl} 2012 \T{fmt} & \multicolumn{1}{c}{Formatting} \\ 2013 1 & Print entire multivector on one line. \\ 2014 2 & Print each grade of multivector on one line.\\ 2015 3 & Print each base of multivector on one line. 2016 \end{tabular} 2017 \end{center} 2018 \T{title} appends a title string to the beginning of the output. An equal sign in 2019 the title string is not required, but is added as a default. 2020 Note that \T{Fmt} only overrides the the global multivector printing format for the 2021 particular instance being printed. To reset the global multivector printing format 2022 use the function \T{Fmt()} in the printer module. 2023 \end{quote} 2024 2025 \T{func(self,fct)} 2026 \begin{quote} 2027 Apply the \T{sympy} scalar function \T{fct} to each coefficient of the multivector. 2028 \end{quote} 2029 2030 \T{grade(self,igrade=0)} 2031 \begin{quote} 2032 Return a multivector that consists of the part of the multivector of 2033 grade equal to \T{igrade}. If the multivector has no \T{igrade} part 2034 return a zero multivector. 2035 \end{quote} 2036 2037 \T{inv(self)} 2038 \begin{quote} 2039 Return the inverse of the multivector $M$ (\T{M.inv()}). If $M$ is a non-zero scalar return $1/M$. If $M^{2}$ is a non-zero 2040 scalar return $M/\paren{M^{2}}$, If $MM^{\R}$ is a non-zero scalar return $M^{\R}/\paren{MM^{\R}}$. Otherwise exit the program with 2041 an error message. 2042 2043 All division operators (\T{/}, \T{/=}) use right multiplication by the inverse. 2044 \end{quote} 2045 2046 \T{norm(self,hint='+')} 2047 \begin{quote} 2048 Return the norm of the multivector $M$ (\T{M.norm()}) defined by $\sqrt{\abs{MM^{\R}}}$. If $MM^{\R}$ is a scalar (a \emph{sympy} scalar 2049 is returned). If $MM^{\R}$ is not a scalar the program exits with an error message. If $MM^{\R}$ is a number \emph{sympy} can determine 2050 if it is positive or negative and calculate the absolute value. If $MM^{\R}$ is a \emph{sympy} expression (function) \emph{sympy} cannot 2051 determine the sign of the expression so that \T{hint='+'} or \T{hint='-'} is needed to determine if the program should calculate 2052 $\sqrt{MM^{\R}}$ or $\sqrt{-MM^{\R}}$. For example if we are in a Euclidean space and \T{M} is a vector then \T{hint='+'}, if 2053 \T{M} is a bivector then let \T{hint='-'}. If \T{hint='0'} and $MM^{\R}$ is a symbolic scalar \T{sqrt(Abs(M*M.rev()))} is returned 2054 where \T{Abs()} is the \emph{sympy} symbolic absolute value function. 2055 \end{quote} 2056 2057 \T{norm2(self)} 2058 \begin{quote} 2059 Return the the scalar defined by $MM^{\R}$ if $MM^{\R}$ is a scalar. If 2060 $MM^{\R}$ is not a scalar the program exits with an error message. 2061 \end{quote} 2062 2063 \begin{comment} 2064 \T{proj(self,bases\_lst)} 2065 \begin{quote} 2066 Return the projection of the multivector $M$ (\T{M.proj(bases\_lst)}) onto the subspace defined by the list of bases 2067 (\T{bases\_lst}). 2068 \end{quote} 2069 \end{comment} 2070 2071 \T{proj(self,lst)} 2072 \begin{quote} 2073 Return the projection of the mutivector $A$ onto the list, $lst$, of basis blades. For example if 2074 $A = A^{x}\eb_{x}+A^{y}\eb_{y}+A^{z}\eb_{z}$ then $A.proj\paren{[\eb_{x},\eb_{y}]} = A^{x}\eb_{x}+A^{y}\eb_{y}$. 2075 Similarly if $A = A^{xy}\eb_{x}\W\eb_{y}+A^{yz}\eb_{y}\W\eb_{z}$ then 2076 $A.proj\paren{[\eb_{x}\W\eb_{y}]} = A^{xy}\eb_{x}\W\eb_{y}$. 2077 \end{quote} 2078 2079 2080 2081 \T{project\_in\_blade(self,blade)} 2082 \begin{quote} 2083 Return the projection of the mutivector $A$ in subspace defined by the blade, $B$, using the formula 2084 $\paren{A\rfloor B}B^{-1} $ in \cite{Macdonald 1}, page 121. 2085 \end{quote} 2086 2087 \T{pure\_grade(self)} 2088 \begin{quote} 2089 If the multivector $A$ is pure (only contains one grade) return, $A.pure\_grade()$, the index ('0' for a scalar, 2090 '1' for vector, '2' for a bi-vector, etc.) of the non-zero grade. If $A$ is not pure return the negative of the 2091 highest non-zero grade index. 2092 \end{quote} 2093 2094 \T{odd(self)} 2095 \begin{quote} 2096 Return odd part of multivector. 2097 \end{quote} 2098 2099 \T{reflect\_in\_blade(self,blade)} 2100 \begin{quote} 2101 Return the reflection of the mutivector $A$ in the subspace defined by the $r$-grade blade, $B_{r}$, using the formula 2102 (extended to multivectors) $\sum_{i} \paren{-1}^{r\paren{i+1}}{B}_{r}\grade{A}_{i}B_{r}^{-1}$ in 2103 \cite{Macdonald 1}, page 129. 2104 \end{quote} 2105 2106 \T{rev(self)} 2107 \begin{quote} 2108 Return the reverse of the multivector. See eq.~(\ref{reverse}). 2109 \end{quote} 2110 2111 \T{rotate\_multivector(self,itheta,hint='-')} 2112 \begin{quote} 2113 Rotate the multivector $A$ via the operation $e^{-\theta i/2}Ae^{\theta i/2}$ 2114 where itheta = $\theta i$, $\theta$ is a scalar, and $i$ is a unit, $i^{2} = \pm 1$, 2-blade. 2115 If $\paren{\theta i}^{2}$ is not a number \T{hint} is required to determine the sign of the 2116 square of \T{itheta}. The default chosen, \T{hint='-'}, is correct for any Euclidean space. 2117 \end{quote} 2118 2119 \T{scalar(self)} 2120 \begin{quote} 2121 Return the coefficient (\emph{sympy} scalar) of the scalar part of a 2122 multivector. 2123 \end{quote} 2124 2125 \T{simplify(self,mode=simplify)} 2126 \begin{quote} 2127 \T{mode} is a \emph{sympy} simplification function of a list/tuple of \emph{sympy} 2128 simplification functions that are applied in sequence (if more than 2129 one function) each coefficient of the multivector. For example if 2130 we wished to applied \T{trigsimp} and \T{ratsimp} \emph{sympy} functions to the 2131 multivector \T{F} the code would be 2132 \begin{lstlisting}[numbers=none] 2133 Fsimp = F.simplify(mode=[trigsimp,ratsimp]). 2134 \end{lstlisting} 2135 \vspace{-10pt} 2136 Actually \T{simplify} could be used to apply any scalar \emph{sympy} function to 2137 the coefficients of the multivector. 2138 \end{quote} 2139 2140 \T{set\_coef(self,grade,base,value)} 2141 \begin{quote} 2142 Set the multivector coefficient of index \T{(grade,base)} to \T{value}. 2143 \end{quote} 2144 2145 \T{subs(self,x)} 2146 \begin{quote} 2147 Return multivector where \emph{sympy} subs function has been applied to each 2148 coefficient of multivector for argument dictionary/list \T{x}. 2149 \end{quote} 2150 2151 \T{trigsimp(self,**kwargs)} 2152 \begin{quote} 2153 Apply the \T{sympy} trigonometric simplification function \T{trigsimp} to 2154 each coefficient of the multivector. \T{**kwargs} are the arguments of 2155 trigsimp. See \T{sympy} documentation on \T{trigsimp} for more information. 2156 \end{quote} 2157 2158 \section{Basic Multivector Functions} 2159 2160 \T{com(A,B)} 2161 \begin{quote} 2162 Calculate commutator of multivectors $A$ and $B$. Returns $(AB-BA)/2$. 2163 2164 Additionally, commutator and anti-commutator operators are 2165 defined by 2166 \begin{align*} 2167 \mbox{\tt{A >> B}} \equiv & \bfrac{AB - BA}{2} \\ 2168 \mbox{\tt{A << B}} \equiv & \bfrac{AB + BA}{2}. 2169 \end{align*} 2170 2171 \end{quote} 2172 2173 \T{cross(v1,v2)} 2174 \begin{quote} 2175 If \T{v1} and \T{v2} are 3-dimensional Euclidean vectors the vector cross product is 2176 returned, $v_{1}\times v_{2} = -I\paren{v_{1}\W v_{2}}$. 2177 \end{quote} 2178 2179 \lstinline$def_prec(gd,op_ord='<>|,^,*')$\footnote{See footnote~\ref{fn_6}.} 2180 \begin{quote} 2181 This is used with the \T{GAeval()} function to evaluate a string representing a multivector 2182 expression with a revised operator precedence. \T{def\_prec()} redefines the operator 2183 precedence for multivectors. \T{def\_prec()} must be called in the main program an the 2184 argument \T{gd} must be \T{globals()}. The argument \T{op\_ord} defines the order of operator 2185 precedence from high to low with groups of equal precedence separated by commas. the default 2186 precedence \lstinline$op_ord='<>|,^,\*'$ is that used by Hestenes (\cite{Hestenes},p7,\cite{Doran},p38). 2187 \end{quote} 2188 2189 \T{dual(A,mode='I+')} 2190 \begin{quote} 2191 Return the dual of the multivector \T{A}. The default operation is $AI$. For other modes see member 2192 function\T{Mv.dual(mode)} 2193 \end{quote} 2194 2195 \T{even(A)} 2196 \begin{quote} 2197 Return even part of $A$. 2198 \end{quote} 2199 2200 \T{exp(A,hint='-')} 2201 \begin{quote} 2202 If $A$ is a multivector then \T{A.exp(hint)} is returned. If $A$ is a \emph{sympy} 2203 expression the \emph{sympy} expression $e^{A}$ is returned (see \T{sympy.exp(A)} member function). 2204 \end{quote} 2205 2206 \T{GAeval(s,pstr=False)}\footnote{\T{GAeval} is in the \T{printer} module.\label{fn_6}} 2207 \begin{quote} 2208 Returns multivector expression for string \T{s} with operator precedence for 2209 string \T{s} defined by inputs to function \T{def\_prec()}. if \T{pstr=True} 2210 \T{s} and \T{s} with parenthesis added to enforce operator precedence are printed. 2211 \end{quote} 2212 2213 \T{grade(A,r=0)} 2214 \begin{quote} 2215 If $A$ is a multivector $\grade{A}_{r}$ is returned. 2216 \end{quote} 2217 2218 \T{inv(A)} 2219 \begin{quote} 2220 If $A$ is a multivector and $AA^{\R}$ is a non-zero scalar then $A^{-1} = A^{\R}/(AA^{\R})$ is returned 2221 otherwise an exception is returned. 2222 \end{quote} 2223 2224 \T{Nga(x,prec=5)} 2225 \begin{quote} 2226 If \T{x} is a multivector with coefficients that contain floating point numbers, \T{Nga()} 2227 rounds all these numbers to a precision of \T{prec} and returns the rounded multivector. 2228 \end{quote} 2229 2230 \T{norm(A,hint='-')} 2231 \begin{quote} 2232 If $A$ is a multivector and $AA^{\R}$ is a number (not a scalar function) then $\sqrt{\abs{AA^{\R}}}$ is returned. 2233 If $AA^{\R}$ is a scalar \emph{sympy} expression, but not a number, and \T{hint='-'} then return $\sqrt{-AA^{\R}}$ otherwise return 2234 $\sqrt{AA^{\R}}$. 2235 \end{quote} 2236 2237 \T{norm2(A)} 2238 \begin{quote} 2239 If $A$ is a multivector and $AA^{\R}$ is a scalar return $\abs{AA^{\R}}$. 2240 \end{quote} 2241 2242 \T{odd(A)} 2243 \begin{quote} 2244 Return odd part of $A$. 2245 \end{quote} 2246 2247 \T{proj(B,A)} 2248 \begin{quote} 2249 Project blade \T{A} on blade \T{B} returning $\paren{A\rfloor B}B^{-1}$. 2250 \end{quote} 2251 2252 \T{ReciprocalFrame(basis,mode='norm')} 2253 \begin{quote} 2254 If \T{basis} is a list/tuple of vectors, \T{ReciprocalFrame()} returns a tuple of reciprocal 2255 vectors. If \T{mode=norm} the vectors are normalized. If \T{mode} is anything other than 2256 \T{norm} the vectors are unnormalized and the normalization coefficient is added to the 2257 end of the tuple. One must divide by this coefficient to normalize the vectors. 2258 \end{quote} 2259 2260 \T{refl(B,A)} 2261 \begin{quote} 2262 Reflect multivector $A$ in blade $B$. If $s$ is grade of $B$ 2263 returns $\sum_{r}(-1)^{s(r+1)}B\grade{A}_{r}B^{-1}$. 2264 \end{quote} 2265 2266 \T{rev(A)} 2267 \begin{quote} 2268 If $A$ is a multivector return $A^{\R}$. 2269 \end{quote} 2270 2271 \T{rot(itheta,A,hint='-')} 2272 \begin{quote} 2273 If \T{A} is a multivector return \T{A.rotate\_multivector(itheta,hint)} where \T{itheta} is the bi-vector blade defining the rotation. 2274 For the use of \T{hint} see the member function \T{Mv.rotate\_multivector(self,itheta,hint)}. 2275 2276 \end{quote} 2277 2278 \section{Multivector Derivatives}\label{makeMVD} 2279 2280 The various derivatives of a multivector function is accomplished by 2281 multiplying the gradient operator vector with the function. The gradient 2282 operation vector is returned by the \T{Ga.grads()} function if coordinates 2283 are defined. For example if we have for a 3-D vector space 2284 2285 \begin{lstlisting} 2286 X = (x,y,z) = symbols('x y z') 2287 o3d = Ga('e*x|y|z',metric='[1,1,1]',coords=X) 2288 (ex,ey,ez) = o3d.mv() 2289 (grad,rgrad) = o3d.grads() 2290 \end{lstlisting} 2291 2292 Then the gradient operator vector is \T{grad} (actually the user can give 2293 it any name he wants to). The derivatives of the multivector 2294 function \T{F = o3d.mv('F','mv',f=True)} are given by multiplying by the 2295 left geometric derivative operator and the right geometric derivative operator 2296 $\paren{\mbox{\T{grad}} = \nabla\mbox{ and } \mbox{\T{rgrad}} = \bar{\nabla}}$. Another option 2297 is to use the radiant operator members of the geometric algebra directly where we have 2298 $\nabla = \T{o3d.grad}$ and $\bar{\nabla} = \T{o3d.rgrad}$. 2299 2300 \begin{align*} 2301 \nabla F &= \mbox{\lstinline!grad*F!} \\ 2302 F \bar{\nabla} &= \mbox{\lstinline!F*rgrad!} \\ 2303 \nabla \W F &= \mbox{\lstinline!grad^F!} \\ 2304 F \W \bar{\nabla} &= \mbox{\lstinline!F^rgrad!} \\ 2305 \nabla \cdot F &= \mbox{\lstinline!grad|F!} \\ 2306 F \cdot \bar{\nabla} &= \mbox{\lstinline!F|rgrad!} \\ 2307 \nabla \rfloor F &= \mbox{\lstinline!grad<F!} \\ 2308 F \rfloor \bar{\nabla} &= \mbox{\lstinline!F<rgrad!} \\ 2309 \nabla \lfloor F &= \mbox{\lstinline!grad>F!} \\ 2310 F \lfloor \bar{\nabla} &= \mbox{\lstinline!F>rgrad!} 2311 \end{align*} 2312 2313 The preceding list gives examples of all possible multivector 2314 derivatives of the multivector function \T{F} where the operation returns 2315 a multivector function. The complementary operations 2316 2317 \begin{align*} 2318 F \nabla &= \mbox{\lstinline!F*grad!} \\ 2319 \bar{\nabla} F &= \mbox{\lstinline!rgrad*F!} \\ 2320 F \W \nabla &= \mbox{\lstinline!F^grad!} \\ 2321 \bar{\nabla} \W F &= \mbox{\lstinline!rgrad^F!} \\ 2322 F \cdot \nabla &= \mbox{\lstinline!F|grad!} \\ 2323 \bar{\nabla}\cdot F &= \mbox{\lstinline!rgrad|F!} \\ 2324 F \rfloor \nabla &= \mbox{\lstinline!F<grad!} \\ 2325 \bar{\nabla} \rfloor F &= \mbox{\lstinline!rgrad<F!} \\ 2326 F \lfloor \nabla &= \mbox{\lstinline!F>grad!} \\ 2327 \bar{\nabla} \lfloor F &= \mbox{\lstinline!rgrad>F!} 2328 \end{align*} 2329 2330 all return multivector linear differential operators. 2331 2332 \section{Submanifolds} 2333 2334 In general the geometric algebra that the user defines exists on the tangent space of 2335 a manifold (see section~\ref{sect_manifold}). The submanifold class, \T{Sm}, is derived from 2336 the \T{Ga} class and allows one 2337 to define a submanifold of a manifold by defining a coordinate mapping between the submanifold 2338 coordinates and the manifold coordinates. What is returned as the submanifold is the geometric 2339 algebra of the tangent space of the submanifold. The submanifold for a geometric algebra is 2340 instantiated with 2341 2342 \T{Ga.sm(map,coords,root='e',norm=False)} 2343 \begin{quote} 2344 To define the submanifold we must def a coordinate map from the coordinates of the submanifold to 2345 each of the coordinates of the base manifold. Thus the arguments \T{map} and \T{coords} are 2346 respectively lists of functions and symbols. The list of symbols, \T{coords}, are the coordinates of the 2347 submanifold and are of length equal to the dimension of the submanifold. The list of functions, \T{map}, 2348 define the mapping from the coordinate space of the submanifold to the coordinate space of the 2349 base manifold. The length of \T{map} is equal to the dimension of the base manifold and each function in 2350 \T{map} is a function of the coordinates of the submanifold. \T{root} is the root of the string that is 2351 used to name the basis vectors of the submanifold. The default value of \T{root} is \T{e}. The result of 2352 this is that if the \emph{sympy} symbols for the coordinates are \T{u} and \T{v} (two dimensional manifold) the 2353 text symbols for the basis vectors are \T{e\_u} and \T{e\_v} or in \LaTeX\, $e_{u}$ and $e_{v}$. As a 2354 concrete example consider the following code. 2355 \includecode{python/submanifold.py} 2356 The output of this program (using \LaTeX) is 2357 \begin{center} 2358 \includegraphics[scale=0.9]{python/submanifold.pdf} 2359 \end{center} 2360 2361 The base manifold, \T{sp3d}, is a 3-d Euclidean space using standard spherical coordinates. The submanifold 2362 \T{sph2d} of \T{sp3d} is a spherical surface of radius $1$. To take the sumanifold operation one step further 2363 the submanifold \T{cir1d} of \T{sph2d} is a circle in \T{sph2d} where the latitude of the circle is $\pi/8$. 2364 2365 In each case, for demonstration purposes, a scalar and vector function on each manifold is defined (\T{f} and \T{F} 2366 for the 2-d manifold and \T{h} and \T{H} for the 1-d manifold) and the geometric derivative of each function is taken. The 2367 manifold mapping and the metric tensor for \T{cir1d} of \T{sph2d} are also shown. Note that if the submanifold basis vectors 2368 are not normalized\footnote{Remember that normalization is currently supported only for orthogonal systems (diagonal 2369 metric tensors).} the program output is. 2370 \begin{center} 2371 \includegraphics[scale=1]{python/submanifold1.pdf} 2372 \end{center} 2373 \end{quote} 2374 2375 \section{Linear Transformations} 2376 2377 The mathematical background for linear transformations is in section~\ref{Ltrans}. Linear transformations on the tangent space of 2378 the manifold are instantiated with the \T{Ga} member function \T{lt} (the actual class being instantiated is \T{Lt}) as shown in 2379 lines 12, 20, 26, and 44 of the 2380 code listing~\T{Ltrans.py}. In all of the examples in \T{Ltrans.py} the default instantiation is used which produces a general (all the 2381 coefficients of the linear transformation are symbolic constants) linear transformation. \emph{Note that to instantiate linear transformations 2382 coordinates, $\set{\bm{e}_{i}}$, must be defined when the geometric algebra associated with the linear transformation is instantiated. 2383 This is due to the naming conventions of the general linear transformation (coordinate names are used) and for the calculation 2384 of the trace of the linear transformation which requires taking a divergence.} To instantiate a specific linear transformation 2385 the usage of \T{lt()} is 2386 \T{Ga.lt(M,f=False,mode='g')} 2387 \newpage 2388 \begin{quote} 2389 \T{M} is an expression that can define the coefficients of the linear transformation in various ways defined as follows. 2390 \begin{center} 2391 \begin{longtable}{cl} 2392 \T{M} & \multicolumn{1}{c}{Result} \\ \hline 2393 string \T{M} & \parbox[t]{4in}{Coefficients are symbolic constants with names $\T{M}^{x_{i}x_{j}}$ where $x_{i}$ 2394 and $x_{j}$ are the names 2395 of the $i^{th}$ and $j^{th}$ coordinates (see output of \T{Ltrans.py}). } \\ \hline 2396 char \T{mode} & \parbox[t]{4in}{If \T{M} is a string then \T{mode} determines whether the linear transformation is 2397 general, \T{mode='g'}, symmetric, \T{mode='s'}, or antisymmetric, \T{mode='a'}. The default is 2398 \T{mode='g'}.}\\ \hline 2399 list \T{M} & \parbox[t]{4in}{If \T{M} is a list of vectors equal in length to the dimension of the vector space then 2400 the linear transformation is $\f{L}{\ebf_{i}} = \T{M}\mat{i}$. If \T{M} is a list of lists of scalars where all 2401 lists are equal in length to the dimension of the vector space then the linear transformation is 2402 $\f{L}{\ebf_{i}} = \T{M}\mat{i}\mat{j}\ebf_{j}$.} \\ \hline 2403 dict \T{M} & \parbox[t]{4in}{If \T{M} is a dictionary the linear transformation is defined by 2404 $\f{L}{\ebf_{i}} = \T{M}\mat{\ebf_{i}}$. If $\ebf_{i}$ is not in the dictionary then $\f{L}{\ebf_{i}} =0$.} \\ \hline 2405 rotor \T{M} & \parbox[t]{4in}{If \T{M} is a rotor, $\T{M}\T{M}^{\R}=1$, the linear transformation is defined by 2406 $\f{L}{\ebf_{i}} = \T{M}\ebf_{i}\T{M}^{\R}$.} \\ \hline 2407 multivector function \T{M} & \parbox[t]{4in}{If \T{M} is a general multivector function, the function is tested for linearity, and if 2408 linear the coefficients of the linear transformation are calculated from 2409 $\f{L}{\ebf_{i}} = \f{\T{M}}{\ebf_{i}}$.} \\ \hline 2410 \end{longtable} 2411 \end{center} 2412 \vspace{-0.5in}\T{f} is \T{True} or \T{False}. If \T{True} the symbolic coefficients of the general linear transformation are instantiated as functions of the coordinates. 2413 \end{quote} 2414 The different methods of instantiation are demonstrated in the code \T{LtransInst.py} 2415 \includecode{python/LtransInst.py} 2416 with output 2417 \begin{center} 2418 \includegraphics[scale=1]{python/LtransInst.pdf} 2419 \end{center} 2420 The member function of the \T{Lt} class are 2421 2422 \T{Lt(A)} 2423 \begin{quote} 2424 Returns the image of the multivector $A$ under the linear transformation $L$ where $\f{L}{A}$ is defined by the 2425 linearity of $L$, the vector values $\f{L}{\ebf_{i}}$, and the definition 2426 $\f{L}{\ebf_{i_{1}}\W\dots\W\ebf_{i_{r}}} = \f{L}{\ebf_{i_{1}}}\W\dots\W\f{L}{\ebf_{i_{r}}}$. 2427 \end{quote} 2428 \T{Lt.det()} 2429 \begin{quote} 2430 Returns the determinant (a scalar) of the linear transformation, $L$, defined by $\f{\det}{L}I = \f{L}{I}$. 2431 \end{quote} 2432 \T{Lt.adj()} 2433 \begin{quote} 2434 Returns the adjoint (a linear transformation) of the linear transformation, $L$, defined by $a\cdot\f{L}{b} = b\cdot\f{\bar{L}}{a}$ where 2435 $a$ and $b$ are any two vectors in the tangent space and $\bar{L}$ is the adjoint of $L$. 2436 \end{quote} 2437 \T{Lt.tr()} 2438 \begin{quote} 2439 Returns the trace (a scalar) of the linear transformation, $L$, defined by 2440 $\f{\operatorname{tr}}{L}=\nabla_{a}\cdot\f{L}{a}$ where $a$ is a vector in the tangent space. 2441 \end{quote} 2442 \T{Lt.matrix()} 2443 \begin{quote} 2444 Returns the matrix representation (\emph{sympy} \T{Matrix}) of the linear transformation, $L$, defined by 2445 $\f{L}{\ebf_{i}} = L_{ij}\ebf_{j}$ where $L_{ij}$ is the matrix representation. 2446 \end{quote} 2447 The \T{Ltrans.py} demonstrate the use of the various \T{Lt} member functions and operators. The operators that can be used with 2448 linear transformations are \T{+}, \T{-}, and \T{*}. If $A$ and $B$ are linear transformations, $V$ a multivector, and $\alpha$ a 2449 scalar then $\f{\paren{A\pm B}}{V} = \f{A}{V}\pm\f{B}{V}$, $\f{\paren{AB}}{V} = \f{A}{\f{B}{V}}$, and 2450 $\f{\paren{\alpha A}}{V} = \alpha\f{A}{V}$. 2451 2452 The \T{matrix()} member function returns a \emph{sympy} \T{Matrix} object which can be printed in IPython notebook. To directly print 2453 an linear transformation in \emph{ipython notebook} one must implement (yet to be done) a printing method similar to \T{mv.Fmt()}. 2454 2455 Note that in \T{Ltrans.py} lines 30 and 49 are commented out since the latex output of those statements would run off the page. The 2456 use can uncomment those statements and run the code in the ``LaTeX docs'' directory to see the output. 2457 \includecode{python/Ltrans.py} 2458 \newpage The output of this code is. 2459 \begin{center} 2460 \includegraphics[scale=0.60]{python/Ltrans.pdf} 2461 \end{center} 2462 2463 \section{Differential Operators} 2464 2465 For the mathematical treatment of linear multivector differential operators see section~\ref{ldops}. The is a differential operator 2466 class \T{Dop}. However, one never needs to use it directly. The operators are constructed from linear combinations of multivector 2467 products of the operators \T{Ga.grad} and \T{Ga.rgrad} as shown in the following code for both orthogonal rectangular and spherical 2468 3-d coordinate systems. 2469 \includecode{python/Dop.py} 2470 The output of this code is. 2471 \begin{center} 2472 \includegraphics[scale=1]{python/Dop.pdf} 2473 \end{center} 2474 2475 Note that for print an operator in the IPython notebook one must implement (yet to be done) a printing method similar to \T{mv.Fmt()}. 2476 2477 \section{Instantiating a Multi-linear Functions (Tensors)} 2478 2479 The mathematical background for multi-linear functions is in section~\ref{MLtrans}. To instantiate a multi-linear function use 2480 2481 \T{Mlt(self, f, Ga, nargs=None, fct=False)} 2482 \begin{quote} 2483 Where the arguments are 2484 2485 \begin{tabular}{cl} 2486 \T{f} & \parbox[t]{5in}{Either a string for a general tensor (this option is included mainly for debugging of the \T{Mlt} class) 2487 or a multi-linear 2488 function of manifold tangent vectors (multi-vectors of grade one) to scalar. For example one could generate a custom 2489 python function such as shown in \T{TensorDef.py}.}\\ 2490 \T{Ga} & Geometric algebra that tensor is associated with. \\ 2491 \T{nargs} & \parbox[t]{5in}{If \T{f} is a string then \T{nargs} is the number of vector arguments of the tensor. If \T{f} is 2492 anything other than a string \T{nargs} is not required since \T{Mlt} determines the number of vector arguments from \T{f}.} \\ 2493 \T{fct} & \parbox[t]{5in}{if \T{f} is a string then \T{fct=True} forces the tensor to be a tensor field (function of the 2494 coordinates. If \T{f} anything other than a string \T{fct} is not required since \T{Mlt} determines whether the tensor is 2495 a tensor field from \T{f}.} 2496 \end{tabular} 2497 \end{quote} 2498 2499 \includecode{python/TensorDef.py} 2500 2501 \section{Basic Multilinear Function Class Functions} 2502 2503 If we can instantiate multilinear functions we can use all the multilinear function class functions as described as follows. 2504 See section~\ref{MLtrans} for the mathematical description of each operation. 2505 2506 \T{self(kargs)} 2507 \begin{quote} 2508 Calling function to evaluates multilinear function for \T{kargs} list of vector arguments and returns a value. Note that a 2509 sympy scalar is returned, \emph{not} a multilinear function. 2510 \end{quote} 2511 2512 \T{self.contract(slot1,slot2)} 2513 \begin{quote} 2514 Returns contraction of tensor between \T{slot1} and \T{slot2} where \T{slot1} is the index of the first vector argument and 2515 \T{slot2} is the index of the second vector argument of the tensor. For example if we have a rank two tensor, \T{T(a1,a2)}, 2516 then \T{T.contract(1,2)} is the contraction of \T{T}. For this case since there are only two slots there can only be one 2517 contraction. 2518 \end{quote} 2519 2520 \T{self.pdiff(slot)} 2521 \begin{quote} 2522 Returns gradient of tensor, \T{T}, with respect to slot vector. For example if the tensor is $\f{T}{a_{1},a_{2}}$ then 2523 \T{T.pdiff(2)} is $\nabla_{a_{2}}T$. Since \T{T} is a scalar function, \T{T.pdiff(2)} is a vector function. 2524 \end{quote} 2525 2526 \T{self.cderiv()} 2527 \begin{quote} 2528 Returns covariant derivative of tensor field. If \T{T} is a tensor of rank $k$ then \T{T.cderiv()} is a tensor of rank $k+1$. 2529 The operation performed is defined in section~\ref{MLtrans}. 2530 \end{quote} 2531 2532 \section{Standard Printing}\label{stdprint} 2533 2534 Printing of multivectors is handled by the module \T{printer} which contains 2535 a string printer class derived from the \emph{sympy} string printer class and a latex 2536 printer class derived from the \emph{sympy} latex printer class. Additionally, there 2537 is an \T{Eprint} class that enhances the console output of \emph{sympy} to make 2538 the printed output multivectors, functions, and derivatives more readable. 2539 \T{Eprint} requires an ansi console such as is supplied in linux or the 2540 program \emph{ConEmu} replaces \T{cmd.exe}. 2541 2542 For a windows user the simplest way to implement \emph{ConEmu} is to use the \emph{geany} 2543 editor and in the Edit$\rightarrow$Preferences$\rightarrow$Tools menu replace \T{cmd.exe} with\footnote{The 180 2544 in the \emph{ConEmu} command line is the width of the console you wish to display in characters. Change the number to suit you.} 2545 \begin{center} 2546 \T{"C:\texttt{\char`\\}Program Files\texttt{\char`\\}ConEmu\texttt{\char`\\}ConEmu64.exe" /WndW 180 /cmd \%c} 2547 \end{center} 2548 and then run an example \emph{galgeba} program that used \T{Eprint}. The default background and foreground colors make the output 2549 unreadable. To change these parameters to reasonable values:\footnote{I am not exactly sure what the different parameter setting 2550 do. I achieved the result I wished for by trial and error. I encourage the users to experiment and share their results.} 2551 \begin{enumerate} 2552 \item Right click on title bar of console. 2553 \item Open \emph{setting} window. 2554 \item Open \emph{colors} window. 2555 \item Set the following parameters to the indicated values: 2556 \begin{description} 2557 \item[Text:] \#0 2558 \item[Back:] \#7 2559 \item[Popup:] \#0 2560 \item[Back:] \#7 2561 \item[$\text{\rlap{$\checkmark$}}\square$ Extend foreground colors with background] \#13 2562 \end{description} 2563 \end{enumerate} 2564 2565 If \T{Eprint} is called in a program (linux) when multivectors are printed 2566 the basis blades or bases are printed in bold text, functions are printed in red, 2567 and derivative operators in green. 2568 2569 For formatting the multivector output there is the member function \T{Fmt(self,fmt=1,title=None)} 2570 which is documented in the multivector member functions. This member function works in the same 2571 way for {\LaTeX} printing. 2572 2573 There are two functions for returning string representations of multivectors. If \T{A} is a multivector then \T{str(A)} returns a string in which the 2574 scalar coefficients of the multivector bases have been simplified (grouped, factored, etc.). The member function \T{A.raw\_str()} returns a string in 2575 which the scalar coefficients of the multivector bases have not been simplified. 2576 2577 \section{Latex Printing}\label{LatexPrinting} 2578 2579 For latex printing one uses one functions from the \T{ga} module and one 2580 function from the \T{printer} module. The 2581 functions are 2582 2583 \T{Format(Fmode=True,Dmode=True)} 2584 \begin{quote} 2585 This function from the \T{ga} module turns on latex printing with the 2586 following options 2587 2588 \begin{tabular}{ccc} 2589 Argument & Value & Result \\ 2590 \T{Fmode} & \T{True} & Print functions without argument list, $f$ \\ 2591 & \T{False} & Print functions with standard \emph{sympy} latex formatting, $\f{f}{x,y,z}$ \\ 2592 \T{Dmode} & \T{True} & Print partial derivatives with condensed notation, $\partial_{x}f$ \\ 2593 & \T{False} & Print partial derivatives with standard \emph{sympy} latex formatting $\frac{\partial f}{\partial x}$ \\ 2594 \end{tabular} 2595 2596 \T{Format()} is also required for printing from \emph{ipython notebook} (note that \T{xpdf()} is not needed to print from \emph{ipython notebook}). 2597 \end{quote} 2598 2599 \T{Fmt(obj,fmt=1)} 2600 \begin{quote} 2601 \T{Fmt()} can be used to set the global multivector printing format or to print a tuple, list, of dictionary.\footnote{In 2602 \emph{Ipython notebook} tuples, or lists, or dictionarys of multivectors do print correctly. One mode of \T{Fmt()} corrects 2603 this deficiency.} The modes and operation of \T{Fmt()} are as follows: 2604 \begin{center} 2605 \begin{tabular}{cl} 2606 \T{obj} & Effect \\ \rule{0pt}{5ex} 2607 \T{obj=1,2,3} & \parbox[c]{4in}{Global multivector format is set to 1, 2, or 3 depending on \T{obj}. 2608 See multivector member function \T{Fmt()} for effect of \T{obj} value.} \\ \rule{0pt}{7ex} 2609 \begin{tabular}{rl} 2610 \T{obj=} & \vspace{-2pt}\hspace{-11pt}\parbox[l]{1in}{\T{tuple}\\ \T{list}\\ \T{dict}} 2611 \end{tabular} 2612 & \parbox[c]{4in}{The printing format of an object that is a tuple, list, or dict is controlled by the \T{fmt} argument in \T{Fmt}: 2613 \begin{center} 2614 \begin{tabular}{cl} 2615 \T{fmt=1} & Print complete \T{obj} on one line. \\ 2616 \T{fmt=2} & Print one element of \T{obj} on each line. 2617 \end{tabular}\end{center}} 2618 \end{tabular} 2619 \end{center} 2620 2621 \end{quote} 2622 2623 2624 \T{xpdf(filename=None,debug=False,paper=(14,11),crop=False)} 2625 \begin{quote} 2626 This function from the \T{printer} module post-processes the output captured from 2627 print statements, writes the resulting latex strings to the file \T{filename}, 2628 processes the file with pdflatex, and displays the resulting pdf file. All latex files except 2629 the pdf file are deleted. If \T{debug = True} the file \T{filename} is printed to 2630 standard output for debugging purposes and \T{filename} (the tex file) is saved. If \T{filename} is not entered the default 2631 filename is the root name of the python program being executed with \T{.tex} appended. 2632 The \T{paper} option defines the size of the paper sheet for latex. The format for the \T{paper} is 2633 2634 \begin{center} 2635 \begin{tabular}{ll} 2636 \T{paper=(w,h)} & \T{w} is paper width in inches and \\ 2637 & \T{h} is paper height in inches \\ 2638 \T{paper='letter'} & paper is standard letter size $8.5\mbox{ in}\times 11\mbox{ in}$ \\ 2639 \T{paper='landscape'} & paper is standard letter size but $11\mbox{ in}\times 8.5\mbox{ in}$ 2640 \end{tabular} 2641 \end{center} 2642 2643 The default of \T{paper=(14,11)} was chosen so that long multivector expressions would not be truncated on the display. 2644 2645 If the \T{crop} input is \T{True} the linux \T{pdfcrop} program is used to crop the pdf output (if output is one page). This only works 2646 for linux installations (where \T{pdfcrop} is installed). 2647 2648 The \T{xpdf} function requires that latex and a pdf viewer be installed on 2649 the computer. 2650 2651 \T{xpdf} \emph{is not required when printing latex in IPython notebook.} 2652 \end{quote} 2653 2654 As an example of using the latex printing options when the following code is 2655 executed 2656 2657 \begin{lstlisting} 2658 from printer import Format, xpdf 2659 from ga import Ga 2660 Format() 2661 g3d = Ga('e*x|y|z') 2662 A = g3d.mv('A','mv') 2663 print r'\bm{A} =',A 2664 print A.Fmt(2,r'\bm{A}') 2665 print A.Fmt(3,r'\bm{A}') 2666 xpdf() 2667 \end{lstlisting} 2668 2669 The following is displayed 2670 \begin{align*} 2671 \bm{A} = & A+A^{x}\bm{e_{x}}+A^{y}\bm{e_{y}}+A^{z}\bm{e_{z}}+A^{xy}\bm{e_{x}\W e_{y}}+A^{xz}\bm{e_{x}\W e_{z}}+A^{yz}\bm{e_{y}\W e_{z}}+A^{xyz}\bm{e_{x}\W e_{y}\W e_{z}} \\ 2672 \bm{A} = & A \\ & +A^{x}\bm{e_{x}}+A^{y}\bm{e_{y}}+A^{z}\bm{e_{z}} \\ & +A^{xy}\bm{e_{x}\W e_{y}}+A^{xz}\bm{e_{x}\W e_{z}}+A^{yz}\bm{e_{y}\W e_{z}} \\ & +A^{xyz}\bm{e_{x}\W e_{y}\W e_{z}} \\ 2673 \bm{A} = & A \\ & +A^{x}\bm{e_{x}} \\ & +A^{y}\bm{e_{y}} \\ & +A^{z}\bm{e_{z}} \\ & +A^{xy}\bm{e_{x}\W e_{y}} \\ & +A^{xz}\bm{e_{x}\W e_{z}} \\ & +A^{yz}\bm{e_{y}\W e_{z}} \\ & +A^{xyz}\bm{e_{x}\W e_{y}\W e_{z}} 2674 \end{align*} 2675 2676 For the cases of derivatives the code is 2677 2678 \begin{lstlisting} 2679 from printer import Format, xpdf 2680 from ga import Ga 2681 2682 Format() 2683 X = (x,y,z) = symbols('x y z') 2684 o3d = Ga('e_x e_y e_z',g=[1,1,1],coords=X) 2685 2686 f = o3d.mv('f','scalar',f=True) 2687 A = o3d.mv('A','vector',f=True) 2688 B = o3d.mv('B','grade2',f=True) 2689 2690 print r'\bm{A} =',A 2691 print r'\bm{B} =',B 2692 2693 print 'grad*f =',o3d.grad*f 2694 print r'grad|\bm{A} =',o3d.grad|A 2695 (o3d.grad*A).Fmt(2,r'grad*\bm{A}') 2696 2697 print r'-I*(grad^\bm{A}) =',-o3g.mv_I*(o3d.grad^A) 2698 print (o3d.grad*B).Fmt(2,r'grad*\bm{B}') 2699 print r'grad^\bm{B} =',o3d.grad^B 2700 print r'grad|\bm{B} =',o3d.grad|B 2701 2702 xpdf() 2703 \end{lstlisting} 2704 2705 and the latex displayed output is ($f$ is a scalar function) 2706 2707 \begin{equation*} \bm{A} = A^{x}\bm{e_{x}}+A^{y}\bm{e_{y}}+A^{z}\bm{e_{z}} \end{equation*} 2708 \begin{equation*} \bm{B} = B^{xy}\bm{e_{x}\W e_{y}}+B^{xz}\bm{e_{x}\W e_{z}}+B^{yz}\bm{e_{y}\W e_{z}} \end{equation*} 2709 \begin{equation*} \bm{\nabla} f = \partial_{x} f\bm{e_{x}}+\partial_{y} f\bm{e_{y}}+\partial_{z} f\bm{e_{z}} \end{equation*} 2710 \begin{equation*} \bm{\nabla} \cdot \bm{A} = \partial_{x} A^{x} + \partial_{y} A^{y} + \partial_{z} A^{z} \end{equation*} 2711 \begin{align*} \bm{\nabla} \bm{A} = & \partial_{x} A^{x} + \partial_{y} A^{y} + \partial_{z} A^{z} \\ & +\left ( - \partial_{y} A^{x} + \partial_{x} A^{y}\right ) \bm{e_{x}\W e_{y}}+\left ( - \partial_{z} A^{x} + \partial_{x} A^{z}\right ) \bm{e_{x}\W e_{z}}+\left ( - \partial_{z} A^{y} + \partial_{y} A^{z}\right ) \bm{e_{y}\W e_{z}} \\ \end{align*} 2712 \begin{equation*} -I (\bm{\nabla} \W \bm{A}) = \left ( - \partial_{z} A^{y} + \partial_{y} A^{z}\right ) \bm{e_{x}}+\left ( \partial_{z} A^{x} - \partial_{x} A^{z}\right ) \bm{e_{y}}+\left ( - \partial_{y} A^{x} + \partial_{x} A^{y}\right ) \bm{e_{z}} \end{equation*} 2713 \begin{align*} \bm{\nabla} \bm{B} = & \left ( - \partial_{y} B^{xy} - \partial_{z} B^{xz}\right ) \bm{e_{x}}+\left ( \partial_{x} B^{xy} - \partial_{z} B^{yz}\right ) \bm{e_{y}}+\left ( \partial_{x} B^{xz} + \partial_{y} B^{yz}\right ) \bm{e_{z}} \\ & +\left ( \partial_{z} B^{xy} - \partial_{y} B^{xz} + \partial_{x} B^{yz}\right ) \bm{e_{x}\W e_{y}\W e_{z}} \\ \end{align*} 2714 \begin{equation*} \bm{\nabla} \W \bm{B} = \left ( \partial_{z} B^{xy} - \partial_{y} B^{xz} + \partial_{x} B^{yz}\right ) \bm{e_{x}\W e_{y}\W e_{z}} \end{equation*} 2715 \begin{equation*} \bm{\nabla} \cdot \bm{B} = \left ( - \partial_{y} B^{xy} - \partial_{z} B^{xz}\right ) \bm{e_{x}}+\left ( \partial_{x} B^{xy} - \partial_{z} B^{yz}\right ) \bm{e_{y}}+\left ( \partial_{x} B^{xz} + \partial_{y} B^{yz}\right ) \bm{e_{z}} \end{equation*} 2716 2717 This example also demonstrates several other features of the latex printer. In the 2718 case that strings are input into the latex printer such as \lstinline!r'grad*\bm{A}'!, 2719 \lstinline!r'grad^\bm{A}'!, or \lstinline!r'grad*\bm{A}'!. The text symbols \T{grad}, \T{\^}, \T{|}, and 2720 \T{*} are mapped by the \T{xpdf()} post-processor as follows if the string contains 2721 an \T{=}. 2722 \begin{center} 2723 \begin{tabular}{ccc} 2724 original & replacement & displayed latex \\ 2725 \lstinline!grad*A! & \lstinline!\bm{\nabla}A! & $\bm{\nabla}A$ \\ 2726 \lstinline!A^B! & \lstinline!A\wedge B! & $A\wedge B$ \\ 2727 \lstinline!A|B! & \lstinline!A\cdot B! & $A\cdot B$ \\ 2728 \lstinline!A*B! & \lstinline!AB! & $AB$ \\ 2729 \lstinline!A<B! & \lstinline!A\rfloor B! & $A\rfloor B$ \\ 2730 \lstinline!A>B! & \lstinline!A\lfloor B! & $A\lfloor B$ \\ 2731 \lstinline!A>>B! & \lstinline!A\times B! & $A\times B$ \\ 2732 \lstinline!A<<B! & \lstinline!A\bar{\times} B! & $A\bar{\times} B$ 2733 2734 \end{tabular} 2735 \end{center} 2736 2737 If the first character in the string to be printed is a \T{\%} none of the above substitutions 2738 are made before the latex processor is applied. In general for the latex 2739 printer strings are assumed to be in a math environment (equation or 2740 align) unless the first character in the string is a \T{\#}.\footnote{Preprocessing do not occur for the Ipython notebook and the 2741 string post processing commands \T{\%} and \T{\#} are not used in this case.} 2742 2743 \notebox{ 2744 Except where noted the conventions for latex printing follow those of the 2745 latex printing module of \emph{sympy}. This includes translating \emph{sympy} variables 2746 with Greek name (such as \T{alpha}) to the equivalent Greek symbol 2747 ($\alpha$) for the purpose of latex printing. Also a single 2748 underscore in the variable name (such as ``\lstinline!X_j!``) indicates a subscript 2749 ($X_{j}$), and a double underscore (such as ``\lstinline!X__k!``) a 2750 superscript ($X^{k}$). The only other change with regard to the 2751 \emph{sympy} latex printer is that matrices are printed full size (equation 2752 displaystyle). 2753 } 2754 2755 There are two member functions for returning {\LaTeX} string representations of multivectors. If \T{A} is a multivector then \T{A.Mv\_latex\_str()} 2756 returns a {\LaTeX} string in which the scalar coefficients of the multivector bases have been simplified (grouped, factored, etc.). This function 2757 is used when using \T{print} in the {\LaTeX} mode. The member function \T{A.raw\_latex\_str()} returns a {\LaTeX} string in which the scalar coefficients 2758 of the multivector bases have not been simplified. 2759 2760 2761 \subsection{Printing Lists/Tuples of Multivectors/Differential Operators} 2762 2763 Since the expressions for multivectors or differential operators can be very long printing lists or tuples of such items can easily exceed the 2764 page with when printing in {\LaTeX} or in ``ipython notebook.'' I order to alleviate this problem the function \T{Fmt} can be used. 2765 2766 \T{Fmt(obj,fmt=0)} 2767 \begin{quote} 2768 This function from the \T{printer} module allows the formatted printing of lists/tuples or multivectors/differential operators. 2769 2770 \begin{center} 2771 \begin{tabular}{ll} 2772 \T{obj} & \T{obj} is a list or tuple of multivectors and/or differential operators. \\ 2773 \T{fmt=0} & \T{fmt=0} prints each element of the list/tuple on an individual lines\footnote{The formatting of 2774 each element is respected as applied by \T{A.Fmt(fmt=1,2, or 3)} where \T{A} is an element of \T{obj }so that if 2775 multivector/differential operation have been formatted to print on multiple 2776 lines it will printed on multiple lines.\label{Fmt_format}}. \\ 2777 &\T{fmt=1} prints all elements of the list/tuple on a single line\footref{Fmt_format}. 2778 \end{tabular} 2779 \end{center} 2780 If l is a list or tuple to print in the {\LaTeX} environment use the command 2781 \begin{lstlisting} 2782 print Fmt(l) # One element of l per line 2783 \end{lstlisting} 2784 or 2785 \begin{lstlisting} 2786 print Fmt(l,1) # All elements of l on one line 2787 \end{lstlisting} 2788 If you are printing in ``ipython notebook'' then enter 2789 \begin{lstlisting} 2790 Fmt(l) # One element of l per line 2791 \end{lstlisting} 2792 or 2793 \begin{lstlisting} 2794 Fmt(l,1) # All elements of l on one line 2795 \end{lstlisting} 2796 \end{quote} 2797 2798 \begin{thebibliography}{99} 2799 \bibitem {Doran} Chris Doran and Anthony Lasenby, ``Geometric Algebra for Physicists,'' Cambridge University 2800 Press, 2003. \url{http://www.mrao.cam.ac.uk/~clifford} 2801 \bibitem {Hestenes} David Hestenes and Garret Sobczyk, ``Clifford Algebra to Geometric Calculus,'' Kluwer Academic 2802 Publishers, 1984. \url{http://geocalc.clas.asu.edu/html/CA_to_GC.html} 2803 \bibitem {Macdonald 1} Alan Macdonald, ``Linear and Geometric Algebra,'' 2010. \url{http://faculty.luther.edu/~macdonal/laga} 2804 \bibitem {Macdonald 2} Alan Macdonald, ``Vector and Geometric Calculus,'' 2012. \url{http://faculty.luther.edu/~macdonal/vagc} 2805 \bibitem {Hestenes Mech} D. Hestenes, ``\emph{New Foundations for Classical Mechanics},'' Kluwer Academic Publishers, 1999. \url{http://geocalc.clas.asu.edu/html/NFCM.html} 2806 \bibitem {Dorst} L. Dorst, D. Fontijne, S. Mann, ``\emph{Geometric Algebra for Computer Science}: 2807 \emph{An Object-Oriented Approach to Geometry},'' Morgan Kaufmann, $2^{\text{nd}}$ printing, 2009. 2808 \url{http://www.geometricalgebra.net/} 2809 \bibitem {Perwass} Christian Perwass, ``\emph{Geometric Algebra with Applications in Engineering},'' Springer, 2008 2810 \bibitem {Arthur} John W. Arthur, ``\emph{Understanding Geometric Algebra for Electromagnetic Theory},'' Wiley-IEEE Press, 2011. 2811 \end{thebibliography} 2812 \end{document} 2813 2814 2815