.. _extended-latex: ********************************** Extended LaTeXModule for Sympy ********************************** :Author: Alan Bromborsky .. |release| replace:: 0.10 .. % .. math:: .. % :nowrap: .. % Complete documentation on the extended LaTeX markup used for Python .. % documentation is available in ``Documenting Python'', which is part .. % of the standard documentation for Python. It may be found online .. % at: .. % .. % http://www.python.org/doc/current/doc/doc.html .. % \input{macros} .. % This is a template for short or medium-size Python-related documents, .. % mostly notably the series of HOWTOs, but it can be used for any .. % document you like. .. % The title should be descriptive enough for people to be able to find .. % the relevant document. .. % Increment the release number whenever significant changes are made. .. % The author and/or editor can define 'significant' however they like. .. % At minimum, give your name and an email address. You can include a .. % snail-mail address if you like. .. % This makes the Abstract go on a separate page in the HTML version; .. % if a copyright notice is used, it should go immediately after this. .. % .. % \ifhtml .. % \chapter*{Front Matter\label{front}} .. % \fi .. % Copyright statement should go here, if needed. .. % ... .. % The abstract should be a paragraph or two long, and describe the .. % scope of the document. .. topic:: Abstract This document describes the extension of the latex module for :mod:`sympy`. The python module :mod:`latex_ex` extends the capabilities of the current :mod:`latex` (while preserving the current capabilities) to geometric algebra multivectors, :mod:`numpy` array's, and extends the ascii formatting of greek symbols, accents, and subscripts and superscripts. Additionally the module is configured to use the print command to generate a LaTeX output file and display it using xdvi in Linux and yap in Windows. To get LaTeX displayed text latex and xdvi must be installed on a Linux system and MikTex on a Windows system. Extended Symbol Coding ====================== One of the main extensions in :mod:`latex_ex` is the ability to encode complex symbols (multiple greek letters with accents and superscripts and subscripts) is ascii strings containing only letters, numbers, and underscores. These restrictions allow :mod:`sympy` variable names to represent complex symbols. For example if we use the :mod:`GA` module function :func:`make_symbols` as follows:: make_symbols('xalpha Gammavec__1_rho delta__j_k') ``make_symbols`` creates the three :mod:`sympy` symbols *xalpha*, *Gammavec__1_rho*, and *delta__j_k*. If these symbols are printed with the :mod:`latex_ex` modules the results are .. csv-table:: :header: " Ascii String ", " LaTeX Output " :widths: 15, 15 " ``xalpha`` ", " :math:`x\alpha` " " ``Gammavec__1_rho`` ", " :math:`\vec{\Gamma}^{1}_{\rho}` " " ``delta__j_k`` ", " :math:`\delta^{j}_{k}` " A single underscore denotes a subscript and a double undscore a superscript. In addition to all normal LaTeX accents boldmath is supported so that ``omegaomegabm``:math:`\rightarrow \Omega\bm{\Omega}` so an accent (or boldmath) only applies to the character (characters in the case of the string representing a greek letter) immediately preceeding the accent command. How LatexPrinter Works ====================== The actual :class:`LatexPrinter` class is hidden with the helper functions :func:`Format`, :func:`LaTeX`, and :func:`xdvi`. :class:`LatexPrinter` is setup when :func:`Format` is called. In addition to setting format switches in :class:`LatexPrinter`, :func:`Format` does two other critical tasks. Firstly, the :mod:`sympy` function :func:`Basic.__str__` is redirected to the :class:`LatexPrinter` helper function :func:`LaTeX`. If nothing more that this were done the python print command would output LaTeX code. Secondly, *sys.stdout* is redirected to a file until :func:`xdvi` is called. This file is then compiled with the :program:`latex` program (if present) and the dvi output file is displayed with the :program:`xdvi` program (if present). Thus for :class:`LatexPrinter` to display the output in a window both :program:`latex` and :program:`xdvi` must be installed on your system and in the execution path. One problem for :class:`LatexPrinter` is determining when equation mode should be use in the output formatting. To allow for printing output not in equation mode the program attemps to determine from the output string context when to use equation mode. The current test is to use equation mode if the string contains an =, \_, \^, or \\. This is not a foolproof method. The safest thing to do if you wish to print an object, *X*, in math mode is to use *print 'X =',X* so the = sign triggers math mode. LatexPrinter Functions ====================== LatexPrinter Class Functions for Extending LatexPrinter Class ------------------------------------------------------------- The :class:`LatexPrinter` class functions are not called directly, but rather are called when :func:`print`, :func:`LaTeX`, or :func:`str` are called. The two new functions for extending the :mod:`latex` module are :func:`_print_ndarray` and :func:`_print_MV`. Some other functions in :class:`LatexPrinter` have been modified to increase their utility. .. function:: _print_ndarray(self,expr) :func:`_print_ndarray` returns a latex formatted string for the *expr* equal to a :class:`numpy` array with elements that can be :class:`sympy` expressions. The :class:`numpy` array's can have up to three dimensions. .. function:: _print_MV(self,expr) :func:`_print_MV` returns a latex formatted string for the *expr* equal to a :class:`GA` multivector. .. function:: str_basic(in_str) :func:`str_basic` returns a string without the latex formatting provided by :class:`LatexPrinter`. This is needed since :class:`LatexPrinter` takes over the :func:`str` fuction and there are instances when the unformatted string is needed such as during the automatic generation of multivector coefficients and the reduction of multivector coefficients for printing. Helper Functions for Extending LatexPrinter Class ------------------------------------------------- .. function:: Format(fmt='1 1 1 1') ``Format`` iniailizes ``LatexPrinter`` and set the format for ``sympy`` symbols, functions, and derivatives and for ``GA`` multivectors. The switch are encoded in the text string argument of ``Format`` as follows. It is assumed that the text string ``fmt`` always contains four integers separated by blanks. .. csv-table:: :header: " Position ", " Switch ", " Values " :widths: 4, 6, 40 " :math:`1^{st}` ", " symbol ", " 0: Use symbol encoding in ``latex.py`` " " ", " ", " 1: Use extended symbol encoding in ``latex_ex.py`` " " :math:`2^{nd}` ", " function ", " 0: Use symbol encoding in ``latex.py``. Print functions args, use ``\operator{ }`` format. " " ", " ", " 1: Do not print function args. Do not use ``\operator{}`` format. Suppress printing of function arguments. " " :math:`3^{d}` ", " partial derivative", " 0: Use partial derivative format in ``latex.py``. " " ", " ", " 1: Use format :math:`\partial_{x}` instead of :math:`\partial/\partial x`. " " :math:`4^{th}` ", " multivector ", " 1: Print entire multivector on one line. " " ", " ", " 2: Print each grade of multivector on one line. " " ", " ", " 3: Print each base of multivector on one line. " .. function:: LaTeX(expr, inline=True) :func:`LaTeX` returns the latex formatted string for the :class:`sympy`, :class:`GA`, or :class:`numpy` expression *expr*. This is needed since :class:`numpy` cannot be subclassed and hence cannot be used with the :class:`LatexPrinter` modified :func:`print` command. Thus is *A* is a :class:`numpy` array containing :class:`sympy` expressions one cannot simply code :: print A but rather must use :: print LaTeX(A) .. function:: xdvi(filename='tmplatex.tex',debug=False) :func:`xdvi` postprocesses the output of the print statements and generates the latex file with name *filename*. If the :program:`latex` and :program:`xdvi` programs are present on the system they are invoked to display the latex file in a window. If *debug=True* the associated output of :program:`latex` is sent to *stdout*, otherwise it is sent to */dev/null* for linux and *NUL* for Windows. If :class:`LatexPrinter` has not been initialized :func:`xdvi` does nothing. After the .dvi file is generated it is displayed with :program:`xdvi` for linux (if latex and xdvi are installed ) and :program:`yap` for Windows (if MikTex is installed). The functions :func:`sym_format`, :func:`fct_format`, :func:`pdiff_format`, and :func:`MV_format` allow one to change various formatting aspects of the :class:`LatexPrinter`. They do not initialize the class and if the are called with the class not initialized they have no effect. These functions and the function :func:`xdvi` are designed so that if the :class:`LatexPrinter` class is not initialized the program output is as if the :class:`LatexPrinter` class is not used. Thus all one needs to do to get simple ascii output (possibly for program debugging) is to comment out the one function call that initializes the :class:`LatexPrinter` class. All other :mod:`latex_ex` function calls can remain in the program and have no effect on program output. .. function:: sym_format(sym_fmt) :func:`sym_format` allows one to change the latex format options for :class:`sympy` symbol output independent of other format switches (see :math:`1^{st}` switch in Table I). .. function:: fct_format(fct_fmt) :func:`fct_format` allows one to change the latex format options for :class:`sympy` function output independent of other format switches (see :math:`2^{nd}` switch in Table I). .. function:: pdiff_format(pdiff_fmt) :func:`pdiff_format` allows one to change the latex format options for :class:`sympy` partial derivative output independent of other format switches (see :math:`3^{d}` switch in Table I). .. function:: MV_format(mv_fmt) :func:`MV_format` allows one to change the latex format options for :class:`sympy` partial derivative output independent of other format switches (see :math:`3^{d}` switch in Table I). Examples ======== :program:`latexdemo.py` a simple example ---------------------------------------- :program:`latexdemo.py` example of using :mod:`latex_ex` with :mod:`sympy` .. include:: latexdemo.py :literal: Start of Program Output .. math:: :nowrap: \begin{equation*} x = \frac{{\alpha}_{1} {}\bm{x}}{{\delta}^{{\nu}{\gamma}}_{r}} \end{equation*} End of Program Output The program :program:`latexdemo.py` demonstrates the extended symbol naming conventions in :mod:`latex_ex`. the statment ``Format()`` starts the :class:`LatexPrinter` driver with default formatting. Note that on the right hand side of the output that *xbm* gives :math:`\bm{x}`, *alpha_1* gives :math:`\alpha_{1}` and *delta__nugamma_r* gives :math:`\delta^{\nu\gamma}_{r}`. Also the fraction is printed correctly. The statment ``print 'x =',x`` sends the string ``'x = '+str(x)`` to the output processor (:func:`xdvi`). Because the string contains an :math:`=` sign the processor treats the string as an LaTeX equation (unnumbered). If ``'x ='`` was not in the print statment a LaTeX error would be generated. In the case of a :class:`GA` multivector one does not need the ``'x ='`` if the multivector has been given a name. In the example the :class:`GA` function :func:`make_symbols` has been used to create the :class:`sympy` symbols for convenience. The :class:`sympy` function :func:`Symbol` could have also been used. :program:`Maxwell.py` a multivector example ------------------------------------------- :program:`Maxwell.py` example of using :mod:`latex_ex` with :mod:`GA` .. include:: Maxwell.py :literal: Start of Program Output :math:`I` Pseudo-Scalar .. math:: :nowrap: \begin{equation*} I = {\gamma}_{t}{\gamma}_{x}{\gamma}_{y}{\gamma}_{z} \end{equation*} :math:`B` Magnetic Field Bi-Vector .. math:: :nowrap: \begin{equation*} B = - {B^{x}}{\gamma}_{t}{\gamma}_{x}- {B^{y}}{\gamma}_{t}{\gamma}_{y}- {B^{z}}{\gamma}_{t}{\gamma}_{z} \end{equation*} :math:`F` Electric Field Bi-Vector .. math:: :nowrap: \begin{equation*} E = - {E^{x}}{\gamma}_{t}{\gamma}_{x}- {E^{y}}{\gamma}_{t}{\gamma}_{y}- {E^{z}}{\gamma}_{t}{\gamma}_{z} \end{equation*} :math:`E+IB` Electo-Magnetic Field Bi-Vector .. math:: :nowrap: \begin{equation*} F = - {E^{x}}{\gamma}_{t}{\gamma}_{x}- {E^{y}}{\gamma}_{t}{\gamma}_{y}- {B^{z}}{\gamma}_{x}{\gamma}_{y}- {E^{z}}{\gamma}_{t}{\gamma}_{z}+ {B^{y}}{\gamma}_{x}{\gamma}_{z}- {B^{x}}{\gamma}_{y}{\gamma}_{z} \end{equation*} :math:`J` Four Current .. math:: :nowrap: \begin{equation*} J = {J^{t}}{\gamma}_{t}+ {J^{x}}{\gamma}_{x}+ {J^{y}}{\gamma}_{y}+ {J^{z}}{\gamma}_{z} \end{equation*} Geometric Derivative of Electo-Magnetic Field Bi-Vector .. math:: :nowrap: \begin{align*} \nabla F & = \left(\partial_{z} {E^{z}} + \partial_{y} {E^{y}} + \partial_{x} {E^{x}}\right){\gamma}_{t} \\ & + \left(-\partial_{t} {E^{x}} + \partial_{y} {B^{z}} -\partial_{z} {B^{y}}\right){\gamma}_{x} \\ & + \left(\partial_{z} {B^{x}} -\partial_{t} {E^{y}} -\partial_{x} {B^{z}}\right){\gamma}_{y} \\ & + \left(-\partial_{y} {B^{x}} -\partial_{t} {E^{z}} + \partial_{x} {B^{y}}\right){\gamma}_{z} \\ & + \left(-\partial_{x} {E^{y}} -\partial_{t} {B^{z}} + \partial_{y} {E^{x}}\right){\gamma}_{t}{\gamma}_{x}{\gamma}_{y} \\ & + \left(-\partial_{x} {E^{z}} + \partial_{t} {B^{y}} + \partial_{z} {E^{x}}\right){\gamma}_{t}{\gamma}_{x}{\gamma}_{z} \\ & + \left(-\partial_{t} {B^{x}} -\partial_{y} {E^{z}} + \partial_{z} {E^{y}}\right){\gamma}_{t}{\gamma}_{y}{\gamma}_{z} \\ & + \left(\partial_{y} {B^{y}} + \partial_{z} {B^{z}} + \partial_{x} {B^{x}}\right){\gamma}_{x}{\gamma}_{y}{\gamma}_{z}\end{align*} All Maxwell Equations are .. math:: :nowrap: \begin{equation*} \nabla F = J \end{equation*} Div :math:`E` and Curl :math:`H` Equations .. math:: :nowrap: \begin{align*} <\nabla F>_1 -J & = \left(-{J^{t}} + \partial_{z} {E^{z}} + \partial_{y} {E^{y}} + \partial_{x} {E^{x}}\right){\gamma}_{t} \\ & + \left(-{J^{x}} -\partial_{t} {E^{x}} + \partial_{y} {B^{z}} -\partial_{z} {B^{y}}\right){\gamma}_{x} \\ & + \left(\partial_{z} {B^{x}} -\partial_{t} {E^{y}} -{J^{y}} -\partial_{x} {B^{z}}\right){\gamma}_{y} \\ & + \left(-\partial_{y} {B^{x}} -\partial_{t} {E^{z}} -{J^{z}} + \partial_{x} {B^{y}}\right){\gamma}_{z}\end{align*} .. math:: :nowrap: \begin{equation*} = 0 \end{equation*} Curl :math:`E` and Div :math:`B` equations .. math:: :nowrap: \begin{align*} <\nabla F>_3 & = \left( -\partial_{x} {E^{y}} -\partial_{t} {B^{z}} + \partial_{y} {E^{x}}\right){\gamma}_{t}\W {\gamma}_{x}\W {\gamma}_{y} \\ & + \left( -\partial_{x} {E^{z}} + \partial_{t} {B^{y}} + \partial_{z} {E^{x}}\right){\gamma}_{t}\W {\gamma}_{x}\W {\gamma}_{z} \\ & + \left( -\partial_{t} {B^{x}} -\partial_{y} {E^{z}} + \partial_{z} {E^{y}}\right){\gamma}_{t}\W {\gamma}_{y}\W {\gamma}_{z} \\ & + \left( \partial_{y} {B^{y}} + \partial_{z} {B^{z}} + \partial_{x} {B^{x}}\right){\gamma}_{x}\W {\gamma}_{y}\W {\gamma}_{z}\end{align*} .. math:: :nowrap: \begin{equation*} = 0 \end{equation*} End of Program Output The program :program:`Maxwell.py` demonstrates the use of the :class:`LatexPrinter` class with the :mod:`GA` module multivector class, :class:`MV`. The :func:`Format` call initializes :class:`LatexPrinter`. The only other explicit :mod:`latex_x` module formatting statement used is ``MV_format(3)``. This statment changes the multivector latex format so that instead of printing the entire multivector on one line, which would run off the page, each multivector base and its coefficient are printed on individual lines using the latex align environment. Another option used is that the printing of function arguments is suppressed since :math:`E`, :math:`B`, :math:`J`, and :math:`F` are multivector fields and printing out the argument, :math:`(t,x,y,z)`, for every field component would greatly lengthen the output and make it more difficult to format in a pleasing way.