.. _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 function :func:`symbols` as
follows::

   xalpha,Gammavec__1_rho,delta__j_k = symbols('xalpha Gammavec__1_rho delta__j_k')

``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\boldsymbol{\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::
        :delim: ;
	: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^{rd}`;   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 they 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^{rd}` 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^{rd}` 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} {}\boldsymbol{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:`\boldsymbol{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.


: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}\wedge {\gamma}_{x}\wedge {\gamma}_{y} \\ & + \left( -\partial_{x} {E^{z}} + \partial_{t} {B^{y}} + \partial_{z} {E^{x}}\right){\gamma}_{t}\wedge {\gamma}_{x}\wedge {\gamma}_{z} \\ & + \left( -\partial_{t} {B^{x}} -\partial_{y} {E^{z}} + \partial_{z} {E^{y}}\right){\gamma}_{t}\wedge {\gamma}_{y}\wedge {\gamma}_{z} \\ & + \left( \partial_{y} {B^{y}} + \partial_{z} {B^{z}} + \partial_{x} {B^{x}}\right){\gamma}_{x}\wedge {\gamma}_{y}\wedge {\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.

