[pypy-commit] benchmarks default: add sympy benchmarks

fijal noreply at buildbot.pypy.org
Sat Oct 8 14:01:29 CEST 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r145:335e29a9381a
Date: 2011-10-08 13:56 +0200
http://bitbucket.org/pypy/benchmarks/changeset/335e29a9381a/

Log:	add sympy benchmarks

diff too long, truncating to 10000 out of 268124 lines

diff --git a/benchmarks.py b/benchmarks.py
--- a/benchmarks.py
+++ b/benchmarks.py
@@ -45,6 +45,12 @@
     'bm_chameleon': {'bm_env': {'PYTHONPATH': relative('lib/chameleon/src')}},
 }
 
+for name in ['expand', 'integrate', 'sum', 'str']:
+    _register_new_bm('bm_sympy', 'sympy_' + name,
+                     globals(), bm_env={'PYTHONPATH': relative('lib/sympy')},
+                     extra_args=['--benchmark=' + name],
+                     iteration_scaling=0.1)
+
 for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch',
              'spectral-norm', 'chaos', 'telco', 'go', 'pyflate-fast',
              'raytrace-simple', 'crypto_pyaes', 'bm_mako', 'bm_chameleon']:
diff --git a/lib/sympy/.mailmap b/lib/sympy/.mailmap
new file mode 100644
--- /dev/null
+++ b/lib/sympy/.mailmap
@@ -0,0 +1,19 @@
+Ondrej Certik <ondrej at certik.cz> ondrej.certik <devnull at localhost>
+Fredrik Johansson <fredrik.johansson at gmail.com> fredrik.johansson <devnull at localhost>
+Kirill Smelkov <kirr at landau.phys.spbu.ru> kirill.smelkov <devnull at localhost>
+Kirill Smelkov <kirr at landau.phys.spbu.ru> convert-repo <devnull at localhost>
+Mateusz Paprocki <mattpap at gmail.com> mattpap <devnull at localhost>
+Fabian Pedregosa <fabian at fseoane.net> Fabian Seoane <fabian at fseoane.net>
+Fabian Pedregosa <fabian at fseoane.net> fabian <fabian at debian.(none)>
+Jason Gedge <inferno1386 at gmail.com> inferno1386 <devnull at localhost>
+Robert Schwarz <lethargo at googlemail.com> lethargo <devnull at localhost>
+Sebastian Kr&#228;mer <basti.kr at gmail.com> basti.kr <devnull at localhost>
+David Roberts <dvdr18 at gmail.com> David Roberts (dvdr18 [at] gmail [dot] com) <devnull at localhost>
+Saroj Adhikari <adh.saroj at gmail.com> Saroj <adh.saroj at gmail.com>
+Rizgar Mella <rizgar.mella at gmail.com> RizgarMella rizgar.mella at gmail.com <RizgarMella rizgar.mella at gmail.com>
+Pearu Peterson <pearu.peterson at gmail.com> pearu.peterson <devnull at localhost>
+Brian Jorgensen <brian.jorgensen at gmail.com> brian.jorgensen <devnull at localhost>
+Chris Wu <chris.wu at gmail.com> Chris.Wu <devnull at localhost>
+Jezreel Ng <jezreel at gmail.com>
+James Pearson <xiong.chiamiov at gmail.com>
+Crist&#243;v&#227;o Sousa <crisjss at gmail.com>
diff --git a/lib/sympy/AUTHORS b/lib/sympy/AUTHORS
new file mode 100644
--- /dev/null
+++ b/lib/sympy/AUTHORS
@@ -0,0 +1,135 @@
+All people who contributed to SymPy by sending at least a patch or more (in
+the order of the date of their first contribution), except those who
+explicitely didn't want to be mentioned:
+
+Ondrej Certik <ondrej at certik.cz>
+Fabian Pedregosa <fabian at fseoane.net>
+Jurjen N.E. Bos <jnebos at gmail.com>
+Mateusz Paprocki <mattpap at gmail.com>
+Marc-Etienne M.Leveille <protonyc at gmail.com>
+Brian Jorgensen <brian.jorgensen at gmail.com>
+Jason Gedge <inferno1386 at gmail.com>
+Robert Schwarz <lethargo at googlemail.com>
+Pearu Peterson <pearu.peterson at gmail.com>
+Fredrik Johansson <fredrik.johansson at gmail.com>
+Chris Wu <chris.wu at gmail.com>
+Ulrich Hecht <ulrich.hecht at gmail.com>
+Goutham Lakshminarayan <dl.goutham at gmail.com>
+David Lawrence <dmlawrence at gmail.com>
+Jaroslaw Tworek <dev.jrx at gmail.com>
+David Marek <h4wk.cz at gmail.com>
+Bernhard R. Link <brlink at debian.org>
+Andrej Tokar&#269;&#237;k <androsis at gmail.com>
+Or Dvory <gidesa at gmail.com>
+Saroj Adhikari <adh.saroj at gmail.com>
+Pauli Virtanen <pav at iki.fi>
+Robert Kern <robert.kern at gmail.com>
+James Aspnes <aspnes at cs.yale.edu>
+Nimish Telang <ntelang at gmail.com>
+Abderrahim Kitouni <a.kitouni at gmail.com>
+Pan Peng <pengpanster at gmail.com>
+Friedrich Hagedorn <friedrich_h at gmx.de>
+Elrond der Elbenfuerst <elrond+sympy.org at samba-tng.org>
+Rizgar Mella <rizgar.mella at gmail.com>
+Felix Kaiser <felix.kaiser at fxkr.net>
+Roberto Nobrega <rwnobrega at gmail.com>
+David Roberts <dvdr18 at gmail.com>
+Sebastian Kr&#228;mer <basti.kr at gmail.com>
+Vinzent Steinberg <vinzent.steinberg at gmail.com>
+Riccardo Gori <goriccardo at gmail.com>
+Case Van Horsen <casevh at gmail.com>
+Stepan Roucka <stepan at roucka.eu>
+Ali Raza Syed <arsyed at gmail.com>
+Stefano Maggiolo <s.maggiolo at gmail.com>
+Robert Cimrman <cimrman3 at ntc.zcu.cz>
+Bastian Weber <bastian.weber at gmx-topmail.de>
+Sebastian Krause <sebastian.krause at gmx.de>
+Sebastian Kreft <skreft at gmail.com>
+Dan <coolg49964 at gmail.com>
+Alan Bromborsky <abrombo at verizon.net>
+Boris Timokhin <qoqenator at gmail.com>
+Robert <average.programmer at gmail.com>
+Andy R. Terrel <aterrel at uchicago.edu>
+Hubert Tsang <intsangity at gmail.com>
+Konrad Meyer <konrad.meyer at gmail.com>
+Henrik Johansson <henjo2006 at gmail.com>
+Priit Laes <plaes at plaes.org>
+Freddie Witherden <freddie at witherden.org>
+Brian E. Granger <ellisonbg at gmail.com>
+Andrew Straw <strawman at astraw.com>
+Kaifeng Zhu <cafeeee at gmail.com>
+Ted Horst <ted.horst at earthlink.net>
+Akshay Srinivasan <akshaysrinivasan at gmail.com>
+Aaron Meurer <asmeurer at gmail.com>
+Barry Wardell <barry.wardell at gmail.com>
+Tomasz Buchert <thinred at gmail.com>
+Vinay Kumar <gnulinooks at gmail.com>
+Johann Cohen-Tanugi <johann.cohentanugi at gmail.com>
+Jochen Voss <voss at seehuhn.de>
+Luke Peterson <hazelnusse at gmail.com>
+Chris Smith <smichr at gmail.com>
+Thomas Sidoti <TSidoti at gmail.com>
+Florian Mickler <florian at mickler.org>
+Nicolas Pourcelot <nicolas.pourcelot at gmail.com>
+Ben Goodrich <goodrich.ben at gmail.com>
+Toon Verstraelen <Toon.Verstraelen at UGent.be>
+Ronan Lamy <ronan.lamy at gmail.com>
+James Abbatiello <abbeyj at gmail.com>
+Ryan Krauss <ryanlists at gmail.com>
+Bill Flynn <wflynny at gmail.com>
+Jorn Baayen <jorn.baayen at gmail.com>
+Eh Tan <tan2tan2 at gmail.com>
+Renato Coutinho <renato.coutinho at gmail.com>
+Oscar Benjamin
+&#216;yvind Jensen <jensen.oyvind at gmail.com>
+Julio Idichekop Filho <idichekop at yahoo.com.br>
+&#321;ukasz Pankowski <lukpank at o2.pl>
+Chu-Ching Huang <cchuang at mail.cgu.edu.tw>
+Fernando Perez <Fernando.Perez at berkeley.edu>
+Raffaele De Feo <alberthilbert at gmail.com>
+Christian Muise <christian.muise at gmail.com>
+Matt Curry <mattjcurry at gmail.com>
+Kazuo Thow <kazuo.thow at gmail.com>
+Jezreel Ng <jezreel at gmail.com>
+Matthew Brett <matthew.brett at gmail.com>
+Addison Cugini <ajcugini at gmail.com>
+Nicholas J.S. Kinar <n.kinar at usask.ca>
+Thomas Dixon <thom at thomdixon.org>
+Crist&#243;v&#227;o Sousa <crisjss at gmail.com>
+Andre de Fortier Smit <freevryheid at gmail.com>
+Alexey U. Goodchenko <proga at goodok.ru>
+Gary Kerr <gary.kerr at blueyonder.co.uk>
+Sherjil Ozair <sherjilozair at gmail.com>
+Oleksandr Gituliar <gituliar at gmail.com>
+Sean Vig <sean.v.775 at gmail.com>
+Prafullkumar P. Tale <hector1618 at gmail.com>
+Vladimir Peri&#263; <vlada.peric at gmail.com>
+Tom Bachmann <e_mc_h2 at web.de>
+Yuri Karadzhov <yuri.karadzhov at gmail.com>
+Vladimir Lagunov <werehuman at gmail.com>
+Matthew Rocklin <mrocklin at cs.uchicago.edu>
+Saptarshi Mandal <sapta.iitkgp at gmail.com>
+Gilbert Gede <gilbertgede at gmail.com>
+Anatolii Koval <weralwolf at gmail.com>
+Tomo Lazovich <lazovich at gmail.com>
+Pavel Fedotov <fedotovp at gmail.com>
+Kibeom Kim <kk1674 at nyu.edu>
+Gregory Ksionda <ksiondag846 at gmail.com>
+Tom&#225;&#353; Bambas <tomas.bambas at gmail.com>
+Jeremias Yehdegho <j.yehdegho at gmail.com>
+Jack McCaffery <jpmccaffery at gmail.com>
+Luca Weihs <astronomicalcuriosity at gmail.com>
+Shai 'Deshe' Wyborski <shaide at cs.huji.ac.il>
+Thomas Wiecki <thomas.wiecki at gmail.com>
+&#211;scar N&#225;jera <najera.oscar at gmail.com>
+Mario Pernici <mario.pernici at gmail.com>
+Benjamin McDonald <mcdonald.ben at gmail.com>
+Sam Magura <samtheman132 at gmail.com>
+Stefan Krastanov <krastanov.stefan at gmail.com>
+Bradley Froehle <brad.froehle at gmail.com>
+Min Ragan-Kelley <benjaminrk at gmail.com>
+Emma Hogan <ehogan at gemini.edu>
+Julien Rioux <julien.rioux at gmail.com>
+Roberto Colistete, Jr. <roberto.colistete at gmail.com>
+Raoul Bourquin <raoulb at bluewin.ch>
+Gert-Ludwig Ingold <gert.ingold at physik.uni-augsburg.de>
diff --git a/lib/sympy/LICENSE b/lib/sympy/LICENSE
new file mode 100644
--- /dev/null
+++ b/lib/sympy/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011 SymPy Development Team
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  a. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+  b. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+  c. Neither the name of the SymPy nor the names of its contributors
+     may be used to endorse or promote products derived from this software
+     without specific prior written permission.
+
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/lib/sympy/MANIFEST.in b/lib/sympy/MANIFEST.in
new file mode 100644
--- /dev/null
+++ b/lib/sympy/MANIFEST.in
@@ -0,0 +1,10 @@
+recursive-include data *
+recursive-include doc *
+prune doc/_build
+recursive-include examples *.py README
+
+include sympy/utilities/mathml/data/*.xsl
+
+include LICENSE
+include TODO
+include AUTHORS
diff --git a/lib/sympy/Makefile b/lib/sympy/Makefile
new file mode 100644
--- /dev/null
+++ b/lib/sympy/Makefile
@@ -0,0 +1,9 @@
+# build or clean Cythonized modules
+
+all:
+	python build.py build_ext --inplace
+
+clean:
+	rm -rf sympy/polys/*.{pyc,c,so}
+	rm -rf build/
+
diff --git a/lib/sympy/README.rst b/lib/sympy/README.rst
new file mode 100644
--- /dev/null
+++ b/lib/sympy/README.rst
@@ -0,0 +1,138 @@
+SymPy
+=====
+
+A Python library for symbolic mathematics.
+
+http://sympy.org/
+
+See the AUTHORS file for the list of authors.
+
+And many more people helped on the SymPy mailinglist, reported bugs, helped
+organize SymPy's participation in the Google Summer of Code, the Google Highly
+Open Participation Contest, wrote and blogged about SymPy...
+
+License: New BSD License (see the LICENSE file for details)
+covers all files in the sympy repository unless stated otherwise.
+
+0. Download
+-----------
+
+::
+
+    $ git clone git://github.com/sympy/sympy.git
+
+For other options (tarballs, debs, etc.), see the web page of SymPy.
+
+1. Documentation and usage
+--------------------------
+
+Everything is at:
+
+http://docs.sympy.org/
+
+You can generate everything at the above site in your local copy of SymPy by::
+
+    $ cd doc
+    $ make html
+    $ epiphany _build/html/index.html # Or your preferred web browser
+
+If you don't want to read that, here is a short usage:
+
+From this directory, start python and::
+
+    >>> from sympy import Symbol, cos
+    >>> x = Symbol('x')
+    >>> e = 1/cos(x)
+    >>> print e.series(x, 0, 10)
+    1 + (1/2)*x**2 + (5/24)*x**4 + (61/720)*x**6 + (277/8064)*x**8 + O(x**10)
+
+SymPy also comes with a console that is a simple wrapper around the
+classic python console (or ipython when available) that loads the
+sympy namespace and executes some common commands for you.
+
+To start it, issue::
+
+    $ bin/isympy
+
+from this directory if SymPy is not installed or simply::
+
+    $ isympy
+
+if SymPy is installed somewhere in your ``PATH``.
+
+3. Installation
+---------------
+
+To install SymPy, simply run::
+
+    $ python setup.py install
+
+If you install it system-wide, you may need to prefix the previous command with ``sudo``::
+
+    $ sudo python setup.py install
+
+4. Tests
+--------
+
+To execute all tests, run::
+
+    $./setup.py test
+
+in the current directory.
+
+For more fine-grained running of tests, use ``bin/test`` or respectively
+``bin/doctest``.
+
+
+5. Clean
+--------
+
+To clean everything (thus getting the same tree as in the repository)::
+
+    $./setup.py clean
+
+6. Brief History
+----------------
+
+SymPy was started by Ondrej Certik in 2005, he wrote some code during the
+summer, then he wrote some more code during the summer 2006. In February 2007,
+Fabian Pedregosa joined the project and helped fixed many things, contributed
+documentation and made it alive again. 5 students (Mateusz Paprocki, Brian
+Jorgensen, Jason Gedge, Robert Schwarz and Chris Wu) improved SymPy incredibly
+during the summer 2007 as part of the Google Summer of Code. Pearu Peterson
+joined the development during the summer 2007 and he has made SymPy much more
+competitive by rewriting the core from scratch, that has made it from 10x to
+100x faster. Jurjen N.E. Bos has contributed pretty printing and other patches.
+Fredrik Johansson has wrote mpmath and contributed a lot of patches. Since
+then, a lot more people have joined the development and some people have also
+left. You can see the full list in doc/src/aboutus.txt, or online at:
+
+http://docs.sympy.org/aboutus.html#sympy-development-team
+
+For people that don't want to be listed there, see the git history.
+
+
+7. Citation
+-----------
+
+To cite SymPy in publications use::
+
+    SymPy Development Team (2011). SymPy: Python library for symbolic mathematics
+    URL http://www.sympy.org.
+
+A BibTeX entry for LaTeX users is::
+
+    @Manual{,
+    title = {SymPy: Python library for symbolic mathematics},
+    author = {{SymPy Development Team}},
+    year = {2011},
+    url = {http://www.sympy.org},
+    }
+
+SymPy is BSD licensed, so you are free to use it whatever you like, be it
+academic, commercial, creating forks or derivatives, as long as you copy the BSD
+statement if you redistribute it (see the LICENSE file for details).
+That said, although not required by the SymPy license, if it is convenient for
+you, please cite SymPy when using it in your work and also consider
+contributing all your changes back, so that we can incorporate it and all of us
+will benefit in the end.
diff --git a/lib/sympy/TODO b/lib/sympy/TODO
new file mode 100644
--- /dev/null
+++ b/lib/sympy/TODO
@@ -0,0 +1,8 @@
+Current problems are tracked at:
+
+http://code.google.com/p/sympy/issues/list
+
+for ideas what should be done in the more distant future, see:
+http://code.google.com/p/sympy/wiki/Discussion
+
+but generally ask on the SymPy mailinglist for uptodate future plan. :)
diff --git a/lib/sympy/bin/adapt_paths.py b/lib/sympy/bin/adapt_paths.py
new file mode 100644
--- /dev/null
+++ b/lib/sympy/bin/adapt_paths.py
@@ -0,0 +1,40 @@
+"""
+This script adapts import statements in sympy/mpmath/tests to work properly.
+
+We want to have this fully automatic, so that we don't have to do it by hand
+each time we copy files from mpmath to sympy.
+
+Usage:
+
+$ python bin/adapt_paths.py > /tmp/x
+$ patch -p0 < /tmp/x
+
+You can use the "--dry-run" parameter to 'patch' to see if all is ok and you
+should also inspect the /tmp/x that all the changes generated are actually
+correct.
+"""
+
+from glob import glob
+import re
+import difflib
+
+def get_files_mpmath():
+    return glob("sympy/mpmath/tests/test_*.py")
+
+def fix_file(filename):
+    f = open(filename)
+    orig = f.read()
+    # This converts stuff like "mpmath.dps -> sympy.mpmath.dps", but will leave
+    # "sympy.mpmath.dps" untouched.
+    s = re.sub("(?<!sympy\.)mpmath", "sympy.mpmath", orig)
+
+    # print differences in an unified diff format
+    d = difflib.unified_diff(orig.split("\n"), s.split("\n"),
+        fromfile=filename, tofile=filename+".new", lineterm="")
+    import sys
+    for l in d:
+        print l
+
+
+for x in get_files_mpmath():
+    fix_file(x)
diff --git a/lib/sympy/bin/coverage_doctest.py b/lib/sympy/bin/coverage_doctest.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/bin/coverage_doctest.py
@@ -0,0 +1,161 @@
+#! /usr/bin/env python
+
+"""
+Program to test that all methods/functions have at least one example doctest.
+
+Usage:
+
+bin/coverage_doctest.py sympy/core
+
+or
+
+bin/coverage_doctest.py sympy/core/basic.py
+
+This script is based on the sage-coverage script from Sage written by William
+Stein.
+"""
+
+import os
+import re
+import sys
+from optparse import OptionParser
+
+def parse_file(file, verbose=False):
+    skipped = []
+    missing_docstring = []
+    missing_doctest = []
+    has_doctest = []
+    indirect_doctest = []
+    while True:
+        i = file.find("def ")
+        if i == -1:
+            break
+
+        e = re.compile('\)\s*:')
+        m = e.search(file[i:])
+        if m is None:
+            break
+        j = m.end() + i
+
+        # "j" now points to the end of the function definition.
+
+        function_name = (' '.join(file[i:j].lstrip('def').split()))[:-1]
+        bare_function_name = function_name[:function_name.find("(")]
+
+        skip_this = False
+        for skip in ['__dealloc__', '__new__', '_']:
+            if function_name.startswith(skip + '('):
+                skip_this = True
+                break
+        if function_name.startswith("_"):
+            # For the time being, let's skip all "private" functions, that
+            # beging with "_". Later, when our doctests are in a good shape, we
+            # may doctest those too.
+            skip_this = True
+        if skip_this:
+            if verbose:
+                skipped.append(function_name)
+            file = file[j:]
+            continue
+
+        k = file[j:].find('\n')
+        if k == -1:
+            break
+        k += j
+        kk = file[k+1:].find('\n')
+        if kk == -1:
+            break
+        kk += k+1
+
+        q0 = file[k:kk].find('"""')
+        if q0 == -1:
+            missing_docstring.append(function_name)
+        else:
+            q0 += k
+            q1 = file[q0+3:].find('"""')
+            if q1 == -1:
+                print "ERROR: Error parsing %s" % function_name
+            else:
+                q1 += q0 + 3
+                # the docstring is now between q0:q1
+                d = file[q0:q1].find('>>>')
+                if d == -1:
+                    missing_doctest.append(function_name)
+                else:
+                    has_doctest.append(function_name)
+                    if not (bare_function_name[0:2] == '__' and
+                        bare_function_name[-2:] == '__'):
+                        d = file[q0:q1].find(bare_function_name)
+                        e = file[q0:q1].find('indirect doctest')
+                        if d == -1 and e == -1:
+                            indirect_doctest.append(function_name)
+
+        file = file[j+3:]
+    return skipped, missing_docstring, missing_doctest, has_doctest, \
+            indirect_doctest
+
+
+def coverage(filename, file, verbose=False):
+    skipped, missing_docstring, missing_doctest, has_doctest, \
+        indirect_doctest = parse_file(file, verbose)
+    num_functions = len(missing_docstring + missing_doctest + has_doctest)
+    if num_functions == 0:
+        print "No functions in %s" % filename
+        return
+    print '-'*70
+    print filename
+    score = 100 * float(len(has_doctest)) / num_functions
+    score = int(score)
+
+    if missing_docstring:
+        print "\nMissing documentation:\n\t * %s\n" % \
+                ('\n\t * '.join(missing_docstring))
+    if missing_doctest:
+        print "\nMissing doctests:\n\t * %s\n" % \
+                ('\n\t * '.join(missing_doctest))
+
+    if indirect_doctest:
+        print "\nIndirect doctest (function name doesn't occur in doctests):\n"\
+                "\t * %s\n"%('\n\t * '.join(indirect_doctest))
+        print 'Use "# indirect doctest" in the docstring to surpress this ' \
+                'warning'
+
+    print "SCORE %s: %s%% (%s of %s)" % (filename, score,
+            len(has_doctest), num_functions)
+
+    print '-'*70
+
+
+
+def go(file, verbose=False, exact=True):
+    if os.path.isdir(file):
+        for F in os.listdir(file):
+            go('%s/%s'%(file,F), verbose, exact=False)
+        return
+    if not (file.endswith('.py') or file.endswith('.pyx')) or \
+        not exact and ('test_' in file or 'bench_' in file):
+            return
+    if not os.path.exists(file):
+        print "File %s does not exist."%file
+        sys.exit(1)
+    f = open(file).read()
+    coverage(file, f, verbose)
+
+if __name__ == "__main__":
+    bintest_dir = os.path.abspath(os.path.dirname(__file__))   # bin/cover...
+    sympy_top  = os.path.split(bintest_dir)[0]      # ../
+    sympy_dir  = os.path.join(sympy_top, 'sympy')  # ../sympy/
+    if os.path.isdir(sympy_dir):
+        sys.path.insert(0, sympy_top)
+
+    parser = OptionParser()
+    parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
+            default=False)
+
+    options, args = parser.parse_args()
+
+    if len(args) == 0:
+        parser.print_help()
+    else:
+        for file in args:
+            go(file, options.verbose)
diff --git a/lib/sympy/bin/coverage_report.py b/lib/sympy/bin/coverage_report.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/bin/coverage_report.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+"""
+Script to generate test coverage reports.
+
+Usage:
+
+$ bin/coverage_report.py
+
+This will create a directory covhtml with the coverage reports.To restrict the analysis
+to a directory, you just need to pass its name as
+argument. For example:
+
+$ bin/coverage_report.py sympy/logic
+
+runs only the tests in sympy/logic/ and reports only on the modules in
+sympy/logic/.  You can also get a report on the parts of the whole sympy code
+covered by the tests in sympy/logic/ by following up the previous command with
+
+$ bin/coverage_report.py -c
+
+"""
+import os, sys, re
+from optparse import OptionParser
+
+try:
+    import coverage
+except ImportError:
+    print "You need to install module coverage. See http://nedbatchelder.com/code/coverage/"
+    sys.exit(-1)
+
+REPORT_DIR = "covhtml"
+REFRESH = False
+
+omit_dir_patterns= ['.*tests', 'benchmark', 'examples',
+                    'mpmath', 'pyglet', 'test_external']
+omit_dir_re = re.compile(r'|'.join(omit_dir_patterns))
+source_re = re.compile(r'.*\.py$')
+
+def generate_covered_files(top_dir):
+    for dirpath, dirnames, filenames in os.walk(top_dir):
+        omit_dirs = [dirn for dirn in dirnames if omit_dir_re.match(dirn)]
+        for x in omit_dirs:
+            dirnames.remove(x)
+        for filename in filenames:
+            if source_re.match(filename):
+                yield os.path.join(dirpath, filename)
+
+
+def make_report(source_dir, report_dir, use_cache=False):
+    #code adapted from /bin/test
+    bin_dir = os.path.abspath(os.path.dirname(__file__))         # bin/
+    sympy_top  = os.path.split(bin_dir)[0]      # ../
+    sympy_dir  = os.path.join(sympy_top, 'sympy')  # ../sympy/
+    if os.path.isdir(sympy_dir):
+        sys.path.insert(0, sympy_top)
+    os.chdir(sympy_top)
+
+    cov = coverage.coverage()
+    cov.exclude("raise NotImplementedError")
+    cov.exclude("def canonize")      #this should be "@decorated"
+    if use_cache:
+        cov.load()
+    else:
+        cov.erase()
+        cov.start()
+        import sympy
+        sympy.test(source_dir)
+        #sympy.doctest()        #coverage doesn't play well with doctests
+        cov.stop()
+        cov.save()
+
+    covered_files = list(generate_covered_files(source_dir))
+
+    if report_dir in os.listdir(os.curdir):
+        for f in os.listdir(report_dir):
+            if f.split('.')[-1] in ['html', 'css', 'js']:
+                os.remove(os.path.join(report_dir, f))
+
+    cov.html_report(morfs=covered_files, directory=report_dir)
+
+if __name__ == '__main__':
+    parser = OptionParser()
+    parser.add_option('-c', '--use-cache', action='store_true', default=False,
+                        help='Use cached data.')
+    parser.add_option('-d', '--report-dir', default='covhtml',
+                        help='Directory to put the generated report in.')
+
+    options, args = parser.parse_args()
+
+    if args:
+        source_dir = args[0]
+    else:
+        source_dir = 'sympy/'
+
+    make_report(source_dir, **options.__dict__)
diff --git a/lib/sympy/bin/doctest b/lib/sympy/bin/doctest
new file mode 100755
--- /dev/null
+++ b/lib/sympy/bin/doctest
@@ -0,0 +1,59 @@
+#! /usr/bin/env python
+
+"""
+Program to execute doctests using the py.test like interface.
+
+The advantage over py.test is that it only depends on sympy and should just
+work in any circumstances. See "sympy.dotest?" for documentation.
+"""
+
+# files listed here can be in unix forward slash format with paths
+# listed relative to sympy (which contains bin, etc...)
+blacklist = []
+
+import sys
+import os
+from optparse import OptionParser
+
+from get_sympy import path_hack
+path_hack()
+
+parser = OptionParser()
+parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
+        default=False)
+
+# if you don't see a -n `default=False`;
+# if you do see a -n `store_true` means to store a True value for it;
+# dest is where in options to put it, options.normal will hold the bool;
+# when the user enters -h or --help, print the `help` text
+parser.add_option("-n", "--normal", action="store_true", dest="normal",
+        help="run normal doctests; do not require explicit imports", default=False)
+parser.add_option('-t', '--types', dest='types', action='store',
+        default=None, choices=['gmpy', 'python', 'sympy'],
+        help='setup ground types: gmpy | python | sympy')
+parser.add_option('-C', '--no-cache', dest='cache', action='store_false',
+        default=True, help='disable caching mechanism')
+parser.set_usage("test [options ...] [files ...]")
+parser.epilog = """\
+"options" are any of the options above. "files" are 0 or more glob strings of \
+files to run doctests on. If no file arguments are given, all doctests will be \
+run. This program runs both doctests in the source and doctests in the Sphinx \
+documentation (doc/src/ directory).\
+"""
+
+options, args = parser.parse_args()
+
+if not options.cache:
+    os.environ['SYMPY_USE_CACHE'] = 'no'
+if options.types:
+    os.environ['SYMPY_GROUND_TYPES'] = options.types
+
+import sympy
+
+ok = sympy.doctest(*args, **{"verbose": options.verbose,
+    "blacklist": blacklist, "normal": options.normal})
+
+if ok:
+    sys.exit(0)
+else:
+    sys.exit(1)
diff --git a/lib/sympy/bin/generate_test_list.py b/lib/sympy/bin/generate_test_list.py
new file mode 100644
--- /dev/null
+++ b/lib/sympy/bin/generate_test_list.py
@@ -0,0 +1,62 @@
+"""
+Execute like this:
+
+$ python bin/generate_test_list.py
+tests = [
+    'sympy.concrete.tests',
+    'sympy.core.tests',
+    'sympy.functions.combinatorial.tests',
+    'sympy.functions.elementary.tests',
+    'sympy.functions.special.tests',
+    'sympy.geometry.tests',
+    'sympy.integrals.tests',
+    'sympy.matrices.tests',
+    'sympy.ntheory.tests',
+    'sympy.numerics.tests',
+    'sympy.parsing.tests',
+    'sympy.physics.tests',
+    'sympy.plotting.tests',
+    'sympy.polynomials.tests',
+    'sympy.printing.tests',
+    'sympy.series.tests',
+    'sympy.simplify.tests',
+    'sympy.solvers.tests',
+    'sympy.specfun.tests',
+    'sympy.statistics.tests',
+    'sympy.test_external',
+    'sympy.utilities.tests',
+    ]
+
+"""
+
+from glob import glob
+
+def get_paths(level=15):
+    """
+    Generates a set of paths for testfiles searching.
+
+    Example:
+    >>> get_paths(2)
+    ['sympy/test_*.py', 'sympy/*/test_*.py', 'sympy/*/*/test_*.py']
+    >>> get_paths(6)
+    ['sympy/test_*.py', 'sympy/*/test_*.py', 'sympy/*/*/test_*.py',
+    'sympy/*/*/*/test_*.py', 'sympy/*/*/*/*/test_*.py',
+    'sympy/*/*/*/*/*/test_*.py', 'sympy/*/*/*/*/*/*/test_*.py']
+
+    """
+    wildcards = ["/"]
+    for i in range(level):
+        wildcards.append(wildcards[-1]+"*/")
+    p = ["sympy"+x+"test_*.py" for x in wildcards]
+    return p
+
+g = []
+for x in get_paths():
+    g.extend(glob(x))
+g = [".".join(x.split("/")[:-1]) for x in g]
+g = list(set(g))
+g.sort()
+print "tests = ["
+for x in g:
+    print "    '%s'," % x
+print "    ]"
diff --git a/lib/sympy/bin/get_sympy.py b/lib/sympy/bin/get_sympy.py
new file mode 100644
--- /dev/null
+++ b/lib/sympy/bin/get_sympy.py
@@ -0,0 +1,13 @@
+"""Functions to get the correct sympy version to run tests."""
+
+import os
+import sys
+
+def path_hack():
+    """
+    Hack sys.path to import correct (local) sympy.
+    """
+    this_file = os.path.abspath(__file__)
+    sympy_dir = os.path.join(os.path.dirname(this_file), "..")
+    sympy_dir = os.path.normpath(sympy_dir)
+    sys.path.insert(0, sympy_dir)
diff --git a/lib/sympy/bin/isympy b/lib/sympy/bin/isympy
new file mode 100755
--- /dev/null
+++ b/lib/sympy/bin/isympy
@@ -0,0 +1,163 @@
+#! /usr/bin/env python
+
+"""Python shell for SymPy.
+
+   This is just a normal Python shell (IPython shell if you have the
+   IPython package installed),  that executes the following commands
+   for the user:
+
+       >>> from __future__ import division
+       >>> from sympy import *
+       >>> x, y, z, t = symbols('x y z t')
+       >>> k, m, n = symbols('k m n', integer=True)
+       >>> f, g, h = symbols('f g h', cls=Function)
+
+   So starting 'isympy' is equivalent to starting Python (or IPython)
+   and executing the above commands by hand.  It is intended for easy
+   and quick experimentation with SymPy.
+
+   COMMAND LINE OPTIONS
+   --------------------
+
+   -c CONSOLE, --console=CONSOLE
+
+     Use the specified Python or IPython shell as console backend instead
+     of the default one (IPython if present or Python otherwise), e.g.:
+
+        isympy -c python
+
+   -p PRETTY, --pretty PRETTY
+
+     Setup pretty printing in SymPy. By default the most pretty,  Unicode
+     printing is enabled. User can use less pretty ASCII printing instead
+     or no pretty printing at all, e.g.:
+
+   -q, --quiet
+
+     Print only Python's and SymPy's versions to stdout at startup.
+
+   -- IPython's options
+
+     Additionally you can pass command line options directly to IPython
+     interpreter (standard Python shell is not supported).  However you
+     need to add '--' separator between two types of options. To run
+     SymPy without startup banner and colors, for example, issue:
+
+        isympy -q -- -colors NoColor
+
+"""
+
+import os, sys
+
+# hook in-tree SymPy into Python path, if possible
+
+isympy_path = os.path.abspath(__file__)
+isympy_dir  = os.path.dirname(isympy_path)
+sympy_top   = os.path.split(isympy_dir)[0]
+sympy_dir   = os.path.join(sympy_top, 'sympy')
+
+if os.path.isdir(sympy_dir):
+    sys.path.insert(0, sympy_top)
+
+def main():
+    from optparse import OptionParser
+
+    usage = 'usage: isympy [options] -- [ipython options]'
+    parser = OptionParser(usage)
+
+    parser.add_option(
+        '-c', '--console',
+        dest='console',
+        action='store',
+        default=None,
+        choices=['ipython', 'python'],
+        help='select type of interactive session: ipython | python')
+
+    parser.add_option(
+        '-p', '--pretty',
+        dest='pretty',
+        action='store',
+        default=None,
+        choices=['unicode', 'ascii', 'no'],
+        help='setup pretty printing: unicode | ascii | no')
+
+    parser.add_option(
+        '-t', '--types',
+        dest='types',
+        action='store',
+        default=None,
+        choices=['gmpy', 'python', 'sympy'],
+        help='setup ground types: gmpy | python | sympy')
+
+    parser.add_option(
+        '-o', '--order',
+        dest='order',
+        action='store',
+        default=None,
+        choices=['lex', 'grlex', 'grevlex', 'rev-lex', 'rev-grlex', 'rev-grevlex', 'old', 'none'],
+        help='setup ordering of terms: [rev-]lex | [rev-]grlex | [rev-]grevlex | old | none')
+
+    parser.add_option(
+        '-q', '--quiet',
+        dest='quiet',
+        action='store_true',
+        default=False,
+        help='print only version information at startup')
+
+    parser.add_option(
+        '-d', '--doctest',
+        dest='doctest',
+        action='store_true',
+        default=False,
+        help='use the doctest format for output (you can just copy and paste it)')
+
+    parser.add_option(
+        '-C', '--no-cache',
+        dest='cache',
+        action='store_false',
+        default=True,
+        help='disable caching mechanism')
+
+    (options, ipy_args) = parser.parse_args()
+
+    if not options.cache:
+        os.environ['SYMPY_USE_CACHE'] = 'no'
+
+    if options.types:
+        os.environ['SYMPY_GROUND_TYPES'] = options.types
+
+    if options.doctest:
+        options.pretty = 'no'
+        options.console = 'python'
+
+    session = options.console
+
+    if session is not None:
+        ipython = session == 'ipython'
+    else:
+        ipython = None
+
+    args = {
+        'pretty_print' : True,
+        'use_unicode'  : None,
+        'order'        : None,
+        'argv'         : ipy_args,
+    }
+
+    if options.pretty == 'unicode':
+        args['use_unicode'] = True
+    elif options.pretty == 'ascii':
+        args['use_unicode'] = False
+    elif options.pretty == 'no':
+        args['pretty_print'] = False
+
+    if options.order is not None:
+        args['order'] = options.order
+
+    args['quiet'] = options.quiet
+
+    from sympy.interactive import init_session
+    init_session(ipython, **args)
+
+if __name__ == "__main__":
+    main()
diff --git a/lib/sympy/bin/py.bench b/lib/sympy/bin/py.bench
new file mode 100755
--- /dev/null
+++ b/lib/sympy/bin/py.bench
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+
+# hook in-tree SymPy into Python path, if possible
+# TODO this should be shared with isympy
+import os, sys
+
+isympy_dir = os.path.dirname(__file__)         # bin/isympy
+sympy_top  = os.path.split(isympy_dir)[0]      # ../
+sympy_dir  = os.path.join(sympy_top, 'sympy')  # ../sympy/
+
+if os.path.isdir(sympy_dir):
+    sys.path.insert(0, sympy_top)
+
+
+from sympy.utilities import benchmarking
+
+if __name__ == '__main__':
+    benchmarking.main()
diff --git a/lib/sympy/bin/strip_whitespace b/lib/sympy/bin/strip_whitespace
new file mode 100755
--- /dev/null
+++ b/lib/sympy/bin/strip_whitespace
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+import os
+
+def strip_file(filename, write, report):
+    # .readlines() retains \n chars, while .read().splitlines() does not.
+    # Assuming that whitespace errors will be few, we will thus only need
+    # to re-add \n to a few right-stripped lines. The hit flag will keep us
+    # from unecessarily re-writing files with no changes.
+
+    lines = open(filename, 'rb').readlines() # without "b" all lines appear as \n terminated
+    hit = False
+    cr = False
+    for index, line in enumerate(lines):
+        if line.endswith(" \n"):
+            if report:
+                print "%s, line %s" % (filename, index + 1)
+            if write:
+                lines[index] = line.rstrip() + "\n"
+                hit = True
+        if line.endswith("\r\n"):
+            if report and not cr:
+                print "%s, line %s (crlf now silent)" % (filename, index + 1)
+                cr = True
+            if write:
+                lines[index] = line.rstrip() + "\n"
+                hit = True
+
+    # correct no newline at eof
+    if lines and not lines[-1].endswith("\n"):
+        lines[-1] += "\n"
+        if report:
+            print "%s, no newline at eof" % filename
+        if write:
+            hit = True
+
+    if write and hit:
+        f = open(filename, "wb") # without "b" the lines may be written in sys-dep format
+        f.writelines(lines)
+        f.close()
+
+def go(path, write, report):
+    allowed_ext = [
+            ".cpp",
+            ".cc",
+            ".h",
+            ".py",
+            ]
+    for root, dirs, files in os.walk(path):
+        if ".git" in dirs:
+            dirs.remove(".git")
+        for file in files:
+            if os.path.splitext(file)[1] not in allowed_ext:
+                continue
+            filename = os.path.join(root, file)
+            strip_file(filename, write, report)
+
+def main():
+    from optparse import OptionParser
+    p = OptionParser("usage: %prog [options] filename")
+    p.add_option("-d", "--dry", action="store_true", dest="dry",
+                 help="Do not modify files.")
+    p.add_option("-v", "--verbose", action="store_true", dest="verbose",
+                 help="Report all changes.")
+    p.add_option("-r", "--recursive", action="store_true", dest="recursive",
+                 help="Recursively correct all files in a directory.")
+    options, args = p.parse_args()
+    if options.dry:
+        options.verbose = True
+    if len(args) == 1:
+        if options.recursive:
+            go(args[0], not options.dry, options.verbose)
+        else:
+            strip_file(args[0], not options.dry, options.verbose)
+    else:
+        p.print_help()
+
+if __name__ == "__main__":
+    main()
diff --git a/lib/sympy/bin/sympy_time.py b/lib/sympy/bin/sympy_time.py
new file mode 100644
--- /dev/null
+++ b/lib/sympy/bin/sympy_time.py
@@ -0,0 +1,49 @@
+import time
+from get_sympy import path_hack
+path_hack()
+
+seen = set()
+import_order = []
+elapsed_times = {}
+level = 0
+parent = None
+children = {}
+
+def new_import(name, globals={}, locals={}, fromlist=[]):
+    global level, parent
+    if name in seen:
+        return old_import(name, globals, locals, fromlist)
+    seen.add(name)
+    import_order.append((name, level, parent))
+    t1 = time.time()
+    old_parent = parent
+    parent = name
+    level += 1
+    module = old_import(name, globals, locals, fromlist)
+    level -= 1
+    parent = old_parent
+    t2 = time.time()
+    elapsed_times[name] = t2-t1
+    return module
+
+old_import = __builtins__.__import__
+
+__builtins__.__import__ = new_import
+from sympy import *
+
+parents = {}
+is_parent = {}
+for name, level, parent in import_order:
+    parents[name] = parent
+    is_parent[parent] = True
+
+print "== Tree =="
+for name, level, parent in import_order:
+    print "%s%s: %.3f (%s)" % (" "*level, name, elapsed_times.get(name,0),
+            parent)
+
+print "\n"
+print "== Slowest (including children) =="
+slowest = sorted((t, name) for (name, t) in elapsed_times.items())[-50:]
+for elapsed_time, name in slowest[::-1]:
+    print "%.3f %s (%s)" % (elapsed_time, name, parents[name])
diff --git a/lib/sympy/bin/sympy_time_cache.py b/lib/sympy/bin/sympy_time_cache.py
new file mode 100644
--- /dev/null
+++ b/lib/sympy/bin/sympy_time_cache.py
@@ -0,0 +1,128 @@
+import time, timeit
+
+class TreeNode(object):
+    def __init__(self, name):
+        self._name = name
+        self._children = []
+        self._time = 0
+
+    def __str__(self):
+        return "%s: %s"%(self._name, self._time)
+
+    __repr__ = __str__
+
+    def add_child(self, node):
+        self._children.append(node)
+
+    def children(self):
+        return self._children
+
+    def child(self, i):
+        return self.children()[i]
+
+    def set_time(self, time):
+        self._time = time
+
+    def time(self):
+        return self._time
+
+    total_time = time
+
+    def exclusive_time(self):
+        return self.total_time() - sum(child.time() for child in self.children())
+
+    def name(self):
+        return self._name
+
+    def linearize(self):
+        res = [self]
+        for child in self.children():
+            res.extend(child.linearize())
+        return res
+
+    def print_tree(self, level=0, max_depth=None):
+        print "  "*level + str(self)
+        if max_depth is not None and max_depth <= level:
+            return
+        for child in self.children():
+            child.print_tree(level+1, max_depth=max_depth)
+
+    def print_generic(self, n=50, method="time"):
+        slowest = sorted((getattr(node, method)(), node.name()) for node in self.linearize())[-n:]
+        for time, name in slowest[::-1]:
+            print "%s %s"%(time, name)
+
+    def print_slowest(self, n=50):
+        self.print_generic(n=50, method="time")
+
+    def print_slowest_exclusive(self, n=50):
+        self.print_generic(n, method="exclusive_time")
+
+    def write_cachegrind(self, f):
+        if isinstance(f, str):
+            f = open(f, "w")
+            f.write("events: Microseconds\n")
+            f.write("fl=sympyallimport\n")
+            must_close = True
+        else:
+            must_close = False
+
+        f.write("fn=%s\n"%self.name())
+        f.write("1 %s\n"%self.exclusive_time())
+
+        counter = 2
+        for child in self.children():
+            f.write("cfn=%s\n"%child.name())
+            f.write("calls=1 1\n")
+            f.write("%s %s\n"%(counter, child.time()))
+            counter += 1
+
+        f.write("\n\n")
+
+        for child in self.children():
+            child.write_cachegrind(f)
+
+        if must_close:
+            f.close()
+
+
+pp = TreeNode(None)  #We have to use pp since there is a sage function
+                     #called parent that gets imported
+seen = set()
+
+def new_import(name, globals={}, locals={}, fromlist=[]):
+    global pp
+    if name in seen:
+        return old_import(name, globals, locals, fromlist)
+    seen.add(name)
+
+    node = TreeNode(name)
+
+    pp.add_child(node)
+    old_pp = pp
+    pp = node
+
+    #Do the actual import
+    t1 = timeit.default_timer()
+    module = old_import(name, globals, locals, fromlist)
+    t2 = timeit.default_timer()
+    node.set_time(int(1000000*(t2-t1)))
+
+
+    pp = old_pp
+
+    return module
+
+old_import = __builtins__.__import__
+
+__builtins__.__import__ = new_import
+old_sum = sum
+
+from sympy import *
+
+sum = old_sum
+
+sageall = pp.child(0)
+sageall.write_cachegrind("sympy.cachegrind")
+
+print "Timings saved. Do:\n$ kcachegrind sympy.cachegrind"
diff --git a/lib/sympy/bin/test b/lib/sympy/bin/test
new file mode 100755
--- /dev/null
+++ b/lib/sympy/bin/test
@@ -0,0 +1,62 @@
+#! /usr/bin/env python
+
+"""
+Program to execute tests using the py.test like interface.
+
+The advantage over py.test is that it only depends on sympy and should just
+work in any circumstances. See "sympy.test?" for documentation.
+"""
+
+import sys
+import os
+from optparse import OptionParser
+
+from get_sympy import path_hack
+path_hack()
+
+parser = OptionParser()
+parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
+        default=False)
+parser.add_option("--pdb", action="store_true", dest="pdb",
+        default=False, help="Run post mortem pdb on each failure")
+parser.add_option("--no-colors", action="store_false", dest="colors",
+        default=True, help="Do not report colored [OK] and [FAIL]")
+parser.add_option("-k", dest="kw",
+        help="only run tests matching the given keyword expression",
+        metavar="KEYWORD", default="")
+parser.add_option("--tb", dest="tb",
+        help="traceback verboseness (short/no) [default: %default]",
+        metavar="TBSTYLE", default="short")
+parser.add_option("--random", action="store_false", dest="sort", default=True,
+        help="Run tests in random order instead of sorting them")
+parser.add_option("--seed", dest="seed", type="int",
+        help="use this seed for randomised tests",
+        metavar="SEED")
+parser.add_option('-t', '--types', dest='types', action='store',
+        default=None, choices=['gmpy', 'python', 'sympy'],
+        help='setup ground types: gmpy | python | sympy')
+parser.add_option('-C', '--no-cache', dest='cache', action='store_false',
+        default=True, help='disable caching mechanism')
+parser.set_usage("test [options ...] [tests ...]")
+parser.epilog = """\
+"options" are any of the options above. "tests" are 0 or more glob strings of \
+tests to run. If no test arguments are given, all tests will be run.\
+"""
+
+options, args = parser.parse_args()
+
+if not options.cache:
+    os.environ['SYMPY_USE_CACHE'] = 'no'
+if options.types:
+    os.environ['SYMPY_GROUND_TYPES'] = options.types
+
+import sympy
+
+ok = sympy.test(*args, **{"verbose": options.verbose, "kw": options.kw,
+    "tb": options.tb, "pdb": options.pdb, "colors": options.colors,
+    "sort": options.sort, "seed": options.seed})
+
+if ok:
+    sys.exit(0)
+else:
+    sys.exit(1)
diff --git a/lib/sympy/bin/test_import b/lib/sympy/bin/test_import
new file mode 100755
--- /dev/null
+++ b/lib/sympy/bin/test_import
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+"""
+Tests the speed of "import sympy" by measuring it many times in a row and
+averaging the values.
+
+Usage:
+
+$ bin/test_import
+"""
+
+n_tests = 50
+
+from pexpect import run
+from numpy import mean, std
+
+def test():
+    t = run("python bin/test_import.py")
+    t = float(t)
+    return t
+
+tests = [test() for x in range(n_tests+1)]
+print "Note: the first run (warm up) was not included in the average + std dev"
+print "All runs (including warm up):"
+print tests
+# skip the first run (warm up):
+tests = tests[1:]
+print "Number of tests: %d" % (n_tests)
+print 'The speed of "import sympy" is: %f +- %f' % (mean(tests), std(tests))
diff --git a/lib/sympy/bin/test_import.py b/lib/sympy/bin/test_import.py
new file mode 100644
--- /dev/null
+++ b/lib/sympy/bin/test_import.py
@@ -0,0 +1,7 @@
+from timeit import default_timer as clock
+from get_sympy import path_hack
+path_hack()
+t = clock()
+import sympy
+t = clock()-t
+print t
diff --git a/lib/sympy/bin/test_isolated b/lib/sympy/bin/test_isolated
new file mode 100755
--- /dev/null
+++ b/lib/sympy/bin/test_isolated
@@ -0,0 +1,115 @@
+#! /usr/bin/env python
+"""
+Generates a bash script, that executes py.test or nosetest on each file
+individually.
+
+Usage and help:
+
+    $ bin/test_isolated -h
+
+and read the instructions.
+"""
+
+from os import chmod, getcwd
+from glob import glob
+from optparse import OptionParser
+from stat import S_IREAD, S_IWRITE, S_IXUSR, S_IRGRP, S_IROTH, S_IXGRP, S_IXOTH
+
+filemode = S_IREAD | S_IWRITE | S_IXUSR | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH
+
+def get_paths(level=6):
+    """
+    Generates a set of paths for testfiles searching.
+
+    Example:
+    >>> get_paths(2)
+    ['sympy/test_*.py', 'sympy/*/test_*.py', 'sympy/*/*/test_*.py']
+    >>> get_paths(6)
+    ['sympy/test_*.py', 'sympy/*/test_*.py', 'sympy/*/*/test_*.py',
+    'sympy/*/*/*/test_*.py', 'sympy/*/*/*/*/test_*.py',
+    'sympy/*/*/*/*/*/test_*.py', 'sympy/*/*/*/*/*/*/test_*.py']
+    """
+    wildcards = ["/"]
+    for i in range(level):
+        wildcards.append(wildcards[-1]+"*/")
+    my_dir = getcwd()
+    p = [my_dir+"/sympy"+x+"test_*.py" for x in wildcards]
+    return p
+
+def generate_test_script1(testlib="py.test"):
+    """Generates a bash script for doing the test.
+
+    "testlib" is the name of the executable, that is going to execute the test,
+    for example "py.test" or "nosetests".
+    """
+    g = []
+    for x in get_paths(10):
+        g.extend(glob(x))
+    f = open("/tmp/test_sympy.sh","w")
+    f.write("#! /bin/sh\n")
+    f.write("# Autogenerated script for a reliable test of SymPy.\n")
+    f.write("# Execute with 'sh test_sympy.sh' (in any directory).\n\n")
+    for x in g:
+        f.write(testlib+" " + x + "\n")
+    chmod(f.name, filemode)
+
+def generate_test_script2(testlib="nosetests"):
+    """Generates a bash script for doing the test.
+
+    "testlib" is the name of the executable, that is going to execute the test,
+    for example "py.test" or "nosetests".
+    """
+    g = []
+    for x in get_paths(10):
+        g.extend(glob(x))
+    f = open("/tmp/test_sympy.sh","w")
+    f.write("#! /bin/sh\n")
+    f.write("# Autogenerated script for a reliable test of SymPy.\n")
+    f.write("# Execute with 'sh test_sympy.sh' (in any directory).\n\n")
+    for x in g:
+        f.write(testlib+" " + x + " && \\\n")
+    f.write("echo 'all tests passed, ok to commit'")
+    chmod(f.name, filemode)
+
+usage = """%prog [options]
+
+Generates a bash script, that executes py.test or nosetest on each file
+individually.
+
+Usage:
+
+    $ bin/test_isolated
+    Generating py.test isolated testsuite...
+    Done. Run (search for 'COMMIT' in the less environment):
+    /tmp/test_sympy.sh | less
+    $ /tmp/test_sympy.sh | less
+
+Let the tests run and then search if any test failed (it will write DO NOT
+COMMIT), so search for COMMIT."""
+
+def main():
+    parser = OptionParser(usage=usage)
+    parser.add_option("-p","--py.test", action="store_false", dest="nosetests",
+            help="Use py.test (default)")
+    parser.add_option("-n","--nosetests", action="store_true", dest="nosetests",
+            help="Use nosetests")
+    parser.add_option("-q","--quiet", action="store_false", dest="verbose")
+    parser.set_defaults(nosetests=False, verbose=True)
+
+    options, args = parser.parse_args()
+    if len(args) != 0:
+        parser.error("too many arguments")
+    if options.nosetests:
+        if options.verbose:
+            print "Generating nosetests isolated testsuite..."
+        generate_test_script2("nosetests")
+    else:
+        if options.verbose:
+            print "Generating py.test isolated testsuite..."
+        generate_test_script1("py.test")
+    if options.verbose:
+        print "Done. Run (search for 'COMMIT' in the less environment):"
+        print "/tmp/test_sympy.sh | less"
+
+if __name__ == "__main__":
+    main()
diff --git a/lib/sympy/bin/use2to3 b/lib/sympy/bin/use2to3
new file mode 100755
--- /dev/null
+++ b/lib/sympy/bin/use2to3
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+
+"""
+This script converts SymPy code to a Python 3-compatible version.
+
+The script copies all files except the ones related to mpmath to a sympy-py3k
+directory, runs 2to3 on them and then copies the vanilla mpmath files over. We
+need this because running 2to3 on mpmath (which is already Python 3 compatible)
+produces errors. You can then use SymPy normally from the sympy-py3k directory
+(installing it or importing it directly).
+
+Because copying and running 2to3 can take a lot of time, we try to do it only on
+files that have been modified since the last run.
+
+Note that the 2to3 shipped with Python 2.6 crashes when converting doctests. It
+is recommended to use the Python 3.2 version (or newer) as it is much faster.
+
+TODO: Add --destination argument (others?)
+ --destination # copy over the source to a user-specified destination
+"""
+import os
+import fnmatch
+import shutil
+
+destination = "sympy-py3k" # directory to copy to
+
+# TODO: build this from .gitignore
+skip_dirs = (
+    '.*',       # skip hidden dirs; .git and .tox in particular can be quite big
+    'mpmath',   # everything related to mpmath, both in doc/ and sympy/
+    '_build',   # files built by Sphinx
+    '__pycache__',
+    'covhtml',  # files produced by bin/test_coverage
+    'my',       # the user can have stuff here we don't want to copy
+    destination # this prevents infinite recursion if the dir already exists
+    )
+
+skip_files = (
+    '*.pyc',
+    '.*',
+    'ast_parser_python25.py', # this files produces doctest errors under py3k
+                              # as we need it only for 2.5, just skip copying it
+    )
+
+modified_files = []
+modified_txt_files = []
+
+# we need to run 2to3 on .txt files; however, not all .txt files are doctests,
+# so we need a list of files we care about
+relevant_txt_files = []
+
+# generate the relevant txt files
+# most of them should be in this directory:
+for root, dirs, files in os.walk('./doc/src/modules'):
+    # NOTE: this will consider mpmath-related files relevant, but it doesn't matter
+    for filename in fnmatch.filter(files, '*.txt'):
+        relevant_txt_files.append(os.path.join(root,filename))
+
+# some files aren't in /doc/src/modules, add them explicitly
+relevant_txt_files.append('./doc/src/tutorial.txt')
+relevant_txt_files.append('./doc/src/gotchas.txt')
+relevant_txt_files.append('./doc/src/guide.txt')
+relevant_txt_files.append('./doc/src/python-comparisons.txt')
+
+# walk the tree and copy over files as necessary
+for root, dirs, files in os.walk('.'):
+    for pattern in skip_dirs:
+        for directory in fnmatch.filter(dirs, pattern):
+            dirs.remove(directory)
+    for pattern in skip_files:
+        for filename in fnmatch.filter(files, pattern):
+            files.remove(filename)
+    for directory in dirs:
+        dstdir = os.path.join(destination, root, directory)
+        if not os.path.exists(dstdir):
+            os.makedirs(dstdir)
+    for filename in files:
+        src = os.path.join(root, filename)
+        dst = os.path.join(destination, root, filename)
+        if os.path.isfile(dst):
+            if os.path.getmtime(src) - os.path.getmtime(dst) < 1:
+                # the file hasn't been modified since the last run, so skip it
+                # we check for one second of difference because Python can be
+                # imprecise (when copying) with smaller time periods
+                continue
+        shutil.copy2(src, dst)
+        # add to the list of files to pass to 2to3 if needed
+        if filename.endswith(".py"):
+            modified_files.append(dst)
+        elif filename.endswith(".txt"):
+            # we need to check the exact path here, not just the filename
+            # as there are eg. multiple index.txt files and not all are relevant
+            if src in relevant_txt_files:
+                modified_txt_files.append(dst)
+
+
+# arguments to call 2to3 with
+args_2to3 = [
+    "-w",         # writes back the changes
+    "-n",         # doesn't write a backup file
+    "--no-diffs", # don't show the diffs for individual files
+]
+
+args_2to3_doctests = args_2to3 + ["-d"] # convert doctests too
+
+# extend the argument list with the list of files that need it
+args_2to3.extend(modified_files)
+args_2to3_doctests.extend(modified_files)
+args_2to3_doctests.extend(modified_txt_files)
+
+# call 2to3, once for regular files and once for doctests
+from lib2to3.main import main as main2to3
+main2to3("lib2to3.fixes", args_2to3)
+main2to3("lib2to3.fixes", args_2to3_doctests)
+
+# once we are finished with everything, we should finally copy over the files
+# provided by mpmath; these should all be in the following two directories
+
+# to skip checking if something has been updated, just copy everything always
+# the main bottleneck is running 2to3, not copying files
+# TODO: only copy updated files; this would need a heavy modification to the
+#       above code, or copy-pasting the relevant part over
+try:
+    shutil.rmtree(os.path.join(destination, "./sympy/mpmath"))
+    shutil.rmtree(os.path.join(destination, "./doc/src/modules/mpmath"))
+except OSError: # directories don't exist
+    pass
+
+shutil.copytree("sympy/mpmath", os.path.join(destination, "./sympy/mpmath"))
+shutil.copytree("doc/src/modules/mpmath", os.path.join(destination, "./doc/src/modules/mpmath"))
diff --git a/lib/sympy/build.py b/lib/sympy/build.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/build.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+import os
+
+from Cython.Compiler.Main import compile
+
+from distutils.core import setup, Extension
+from distutils.command.build_ext import build_ext
+
+source_root = os.path.dirname(__file__)
+
+compiled_modules = [
+    "sympy.polys.densearith",
+    "sympy.polys.densebasic",
+    "sympy.polys.densetools",
+    "sympy.polys.euclidtools",
+    "sympy.polys.factortools",
+    "sympy.polys.galoistools",
+    "sympy.polys.monomialtools",
+    "sympy.polys.orthopolys",
+    "sympy.polys.specialpolys",
+    "sympy.polys.sqfreetools",
+]
+
+extensions = []
+
+for module in compiled_modules:
+    source_file = os.path.join(source_root, *module.split('.')) + ".py"
+
+    print("Compiling module %s ..." % module)
+    result = compile(source_file)
+
+    if result.c_file is None:
+        raise RuntimeError("failed to compile %s" % module)
+
+    extensions.append(
+        Extension(module, sources=[str(result.c_file)],
+            extra_compile_args=['-O2', '-Wall'],
+        )
+    )
+
+setup(
+    name        = "SymPy",
+    packages    = [
+        "sympy",
+        "sympy.polys",
+    ],
+    cmdclass    = {
+        "build_ext": build_ext
+    },
+    ext_modules = extensions
+)
+
diff --git a/lib/sympy/data/IPython/ipythonrc-sympy b/lib/sympy/data/IPython/ipythonrc-sympy
new file mode 100644
--- /dev/null
+++ b/lib/sympy/data/IPython/ipythonrc-sympy
@@ -0,0 +1,31 @@
+# -*- Mode: Shell-Script -*-  Not really, but shows comments correctly
+#*******************************************************************************
+# Configuration file for ipython -- ipythonrc format
+#
+# The format of this file is one of 'key value' lines.
+#
+# Lines containing only whitespace at the beginning and then a '#' are
+# ignored as comments.  But comments can NOT be put on lines with data.
+#*******************************************************************************
+#
+# This configuration file is  a  customization to turn IPython into a
+# very capable environment for high-end purely symbolic and numerical
+# work, using SymPy, similar to Mathematica, AXIOM etc.  but with the
+# beauty and flexibility of the Python language.
+#
+# SymPy is a Python library for symbolic mathematics. It aims to become
+# a  full-featured computer algebra system (CAS) while keeping the code
+# as simple as possible in order to be comprehensible and easily exten-
+# sible.  SymPy is written entirely in  Python and does not require any
+# external libraries.
+#
+# For more information visit www.sympy.org
+#
+
+include ipythonrc
+
+banner 0
+
+import_all sympy.interactive
+
+execute init_session()
diff --git a/lib/sympy/data/TeXmacs/LICENSE b/lib/sympy/data/TeXmacs/LICENSE
new file mode 100644
--- /dev/null
+++ b/lib/sympy/data/TeXmacs/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011 SymPy developers
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  a. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+  b. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+  c. Neither the name of the SymPy nor the names of its contributors
+     may be used to endorse or promote products derived from this software
+     without specific prior written permission.
+
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/lib/sympy/data/TeXmacs/bin/tm_sympy b/lib/sympy/data/TeXmacs/bin/tm_sympy
new file mode 100755
--- /dev/null
+++ b/lib/sympy/data/TeXmacs/bin/tm_sympy
@@ -0,0 +1,97 @@
+#!/usr/bin/python
+#
+# TeXmacs interface for SymPy
+#
+# This plugin supports LaTeX printing of SymPy expressions
+# using sympy.printing.latex function. It handles pretty
+# printing of containers. If you wish to display raw
+# Python code, then use 'print' before an expression.
+#
+# TeXmacs encodes new-lines as spaces so we must use
+# heuristics to know where a multi-line expression is
+# broken. As a result you can't use more than one space
+# in a sequence. However you can and must indent your
+# expression using standard Pyhon rules.
+#
+# You can retrive the last output using '_' built-in
+# symbol. If the previous command did not generate
+# any ouput, it will be assigned with None.
+#
+# For a complete Python interface visit:
+#
+#  http://dkbza.org/tmPython.html
+#
+
+import os
+import re
+import traceback
+
+from sympy import __version__
+from sympy.printing import latex
+
+BEGIN, END = chr(2), chr(5)
+
+DATA_COMMAND = chr(16)
+DATA_ESCAPE = chr(27)
+
+def send(kind, output=None):
+    if output is None:
+        output = ""
+    elif kind == "latex":
+        output = latex(output)
+
+    message = "%s:%s" %  (kind, output)
+
+    os.sys.stdout.write(BEGIN)
+    os.sys.stdout.write(message)
+    os.sys.stdout.write(END)
+    os.sys.stdout.flush()
+
+send("verbatim", "Welcome to SymPy " + __version__)
+
+_globals = {}
+
+_init = \
+"""
+from sympy import *
+
+_ = None
+
+x, y, z, t = symbols('x,y,z,t')
+k, i, m, n = symbols('k,i,m,n', integer=True)
+
+f = Function('f')
+
+Gamma, Zeta = gamma, zeta
+
+_greek = 'alpha beta gamma delta epsilon zeta eta '  \
+         'theta iota kappa mu nu xi omicron pi rho ' \
+         'sigma tau upsilon phi chi psi omega'
+
+for _symbol in _greek.split(' '):
+    exec "%s = Symbol('%s')" % (_symbol, _symbol)
+
+del _symbol
+"""
+
+eval(compile(_init, 'tm_sympy', 'exec'), _globals)
+
+while True:
+    line = os.sys.stdin.readline().strip()
+
+    if not line:
+        send("verbatim")
+    elif line[0] != DATA_COMMAND:
+        line = re.sub(r' {2}(\s*)', r'\n \1', line)
+
+        try:
+            output = eval(line, _globals)
+        except:
+            try:
+                output = eval(compile(line, 'tm_sympy', 'exec'), _globals)
+            except:
+                send("verbatim", traceback.format_exc(limit = 0))
+                continue
+
+        _globals['_'] = output
+        send("latex", output)
diff --git a/lib/sympy/data/TeXmacs/progs/init-sympy.scm b/lib/sympy/data/TeXmacs/progs/init-sympy.scm
new file mode 100755
--- /dev/null
+++ b/lib/sympy/data/TeXmacs/progs/init-sympy.scm
@@ -0,0 +1,4 @@
+(plugin-configure sympy
+  (:require (url-exists-in-path? "tm_sympy"))
+  (:launch "tm_sympy --texmacs")
+  (:session "SymPy"))
diff --git a/lib/sympy/doc/Makefile b/lib/sympy/doc/Makefile
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/Makefile
@@ -0,0 +1,96 @@
+# Makefile for Sphinx documentation
+#
+PYTHON       = python
+RST2HTML     = rst2html
+
+# You can set these variables from the command line.
+SPHINXOPTS   =
+SPHINXVER    = 0.5
+#SPHINXBUILDpy  = sphinx/Sphinx-$(SPHINXVER)/sphinx-build.py
+SPHINXBUILDpy  = sphinx-build
+SPHINXBUILD  = PYTHONPATH=..:$(PYTHONPATH) $(SPHINXBUILDpy)
+PAPER        =
+
+ALLSPHINXOPTS = -d _build/doctrees -D latex_paper_size=$(PAPER) \
+                $(SPHINXOPTS) src
+
+ALLSPHINXOPTSapi = -d _build/doctreesapi -D latex_paper_size=$(PAPER) \
+                $(SPHINXOPTS) api
+
+.PHONY: help clean html web htmlhelp latex changes linkcheck
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html      to make standalone HTML files"
+	@echo "  web       to make files usable by Sphinx.web"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview over all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+
+clean:
+	-rm -rf _build
+	-rm -rf sphinx
+
+$(SPHINXBUILDpy):
+	rm -rf sphinx
+#	mkdir sphinx
+#	cd sphinx; wget http://pypi.python.org/packages/source/S/Sphinx/Sphinx-$(SPHINXVER).tar.gz;
+#	cd sphinx; tar xzf Sphinx-$(SPHINXVER).tar.gz
+
+html: $(SPHINXBUILDpy)
+	mkdir -p src/.static
+	mkdir -p _build/html
+	mkdir -p _build/doctrees
+	mkdir -p src/modules
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
+	cp -r src/pics _build/html/
+	cp -r src/figures _build/html/
+	@echo
+	@echo "Build finished. The HTML pages are in _build/html."
+
+htmlapi: $(SPHINXBUILDpy)
+	mkdir -p api/.static
+	mkdir -p api/modules
+	mkdir -p _build/api _build/doctreesapi
+	rm -f api/modules/sympy*.txt
+	./generate_reference.py
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTSapi) _build/api
+	@echo
+	@echo "Build finished. The API docs pages are in _build/api."
+
+web:
+	mkdir -p _build/web _build/doctrees
+	$(SPHINXBUILD) -b web $(ALLSPHINXOPTS) _build/web
+	@echo
+	@echo "Build finished; now you can run"
+	@echo "  python -m sphinx.web _build/web"
+	@echo "to start the server."
+
+htmlhelp:
+	mkdir -p _build/htmlhelp _build/doctrees
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in _build/htmlhelp."
+
+latex: $(SPHINXBUILDpy)
+	mkdir -p _build/latex _build/doctrees
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in _build/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	mkdir -p _build/changes _build/doctrees
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
+	@echo
+	@echo "The overview file is in _build/changes."
+
+linkcheck:
+	mkdir -p _build/linkcheck _build/doctrees
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in _build/linkcheck/output.txt."
diff --git a/lib/sympy/doc/README b/lib/sympy/doc/README
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/README
@@ -0,0 +1,12 @@
+To make the html documentation, install the prerequisites, e.g. on
+Debian/Ubuntu (similarly for other distributions):
+
+apt-get install python-sphinx texlive-latex-recommended dvipng
+
+and do:
+
+$ make html
+
+and to view it, do:
+
+$ epiphany _build/html/index.html
diff --git a/lib/sympy/doc/api/conf.py b/lib/sympy/doc/api/conf.py
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/api/conf.py
@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*-
+#
+# SymPy documentation build configuration file, created by
+# sphinx-quickstart.py on Sat Mar 22 19:34:32 2008.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# All configuration values have a default value; values that are commented out
+# serve to show the default value.
+
+import sys
+
+# If your extensions are in another directory, add it here.
+#sys.path.append('some/directory')
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['.templates']
+
+# The suffix of source filenames.
+source_suffix = '.txt'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'SymPy'
+copyright = '2011, SymPy Development Team'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+#
+# The short X.Y version.
+version = '0.7.1'
+# The full version, including alpha/beta/rc tags.
+release = '0.7.1-git'
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+html_style = 'default.css'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['.static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Content template for the index page.
+#html_index = ''
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'SymPydoc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+latex_documents = [('index', 'sympy.tex', 'SymPy Documentation',
+                        'SymPy Development Team', 'manual')]
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
diff --git a/lib/sympy/doc/api/index.txt b/lib/sympy/doc/api/index.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/api/index.txt
@@ -0,0 +1,10 @@
+Welcome to SymPy API reference
+==============================
+
+This is an automaticaly generated API documentation from SymPy sources.
+
+Click the  "modules" (:ref:`modindex`) link in the top right corner to
+browse the modules.
+
+Or click the "index" to see an index of all SymPy functions, methods and
+classes.
diff --git a/lib/sympy/doc/apidoc.conf b/lib/sympy/doc/apidoc.conf
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/apidoc.conf
@@ -0,0 +1,19 @@
+[epydoc]
+
+name : Sympy
+url: http://code.google.com/p/sympy
+
+modules : sympy, sympy.core, sympy.modules
+
+output : html
+target : ../api/
+
+dotpath : /usr/bin/dot
+
+parse: yes
+introspect: yes
+
+private : no
+frames: no
+
+docformat : epytext
diff --git a/lib/sympy/doc/ext/mathjax.py b/lib/sympy/doc/ext/mathjax.py
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/ext/mathjax.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinx.ext.mathjax
+    ~~~~~~~~~~~~~~~~~~
+
+    Allow `MathJax <http://mathjax.org/>`_ to be used to display math in
+    Sphinx's HTML writer -- requires the MathJax JavaScript library on your
+    webserver/computer.
+
+    :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from docutils import nodes
+
+from sphinx.application import ExtensionError
+from sphinx.ext.mathbase import setup_math as mathbase_setup
+
+
+def html_visit_math(self, node):
+    self.body.append(self.starttag(node, 'span', '', CLASS='math'))
+    self.body.append(self.builder.config.mathjax_inline[0] +
+                     self.encode(node['latex']) +
+                     self.builder.config.mathjax_inline[1] + '</span>')
+    raise nodes.SkipNode
+
+def html_visit_displaymath(self, node):
+    self.body.append(self.starttag(node, 'div', CLASS='math'))
+    if node['nowrap']:
+        self.body.append(self.builder.config.mathjax_display[0] +
+                         node['latex'] +
+                         self.builder.config.mathjax_display[1])
+        self.body.append('</div>')
+        raise nodes.SkipNode
+
+    parts = [prt for prt in node['latex'].split('\n\n') if prt.strip()]
+    for i, part in enumerate(parts):
+        part = self.encode(part)
+        if i == 0:
+            # necessary to e.g. set the id property correctly
+            if node['number']:
+                self.body.append('<span class="eqno">(%s)</span>' %
+                                 node['number'])
+        if '&' in part or '\\\\' in part:
+            self.body.append(self.builder.config.mathjax_display[0] +
+                             '\\begin{split}' + part + '\\end{split}' +
+                             self.builder.config.mathjax_display[1])
+        else:
+            self.body.append(self.builder.config.mathjax_display[0] + part +
+                             self.builder.config.mathjax_display[1])
+    self.body.append('</div>\n')
+    raise nodes.SkipNode
+
+def builder_inited(app):
+    if not app.config.mathjax_path:
+        raise ExtensionError('mathjax_path config value must be set for the '
+                             'mathjax extension to work')
+    app.add_javascript(app.config.mathjax_path)
+
+
+def setup(app):
+    mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
+    app.add_config_value('mathjax_path',
+                         'http://cdn.mathjax.org/mathjax/latest/MathJax.js?'
+                         'config=TeX-AMS-MML_HTMLorMML', False)
+    app.add_config_value('mathjax_inline', [r'\(', r'\)'], 'html')
+    app.add_config_value('mathjax_display', [r'\[', r'\]'], 'html')
+    app.connect('builder-inited', builder_inited)
diff --git a/lib/sympy/doc/generate_reference.py b/lib/sympy/doc/generate_reference.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/doc/generate_reference.py
@@ -0,0 +1,164 @@
+#! /usr/bin/python2.5
+
+# See the README in this directory how to generate the documentation.
+
+# This script generates the reference, however, it currently doesn't produce a
+# nicely polished documentation.
+
+# You need to run python2.5 with this, because python2.4 has some weird
+# Exception hierarchy classes that causes Exceptions to be ignored by this
+# script
+
+import types
+import os
+import sys
+
+def isclass(x):
+    from inspect import isclass as _isclass
+    return _isclass(x)
+
+def ismethod(x):
+    from inspect import ismethod as _ismethod
+    if _ismethod(x) or isinstance(x, (types.MethodType, types.FunctionType,
+                    types.UnboundMethodType)) or str(type(x)) in [
+                    "<type 'classmethod'>", "<type 'staticmethod'>"]:
+        return True
+    else:
+        return False
+
+def get_method_name(x):
+    if hasattr(x, "__name__"):
+        return x.__name__
+    # This is a static method, don't know how to read the name.
+    return None
+
+def get_method_args(x):
+    from inspect import getsource
+    try:
+        s = getsource(x)
+    except TypeError:
+        return ""
+    s = s[s.find("("):s.find(":")]
+    assert s is not None
+    return s
+
+def getdoc(x):
+    from inspect import getdoc as _getdoc
+    s = _getdoc(x)
+    return s
+
+class Parser(object):
+
+    def __init__(self):
+        self.modules = {}
+
+    def generate_doc(self, module, outdir="/tmp/", importpath = ""):
+        """
+        Takes the "module" string and generates a rst for this module.
+
+        modules is just the name, like "sympy", i.e. without a path.
+        """
+
+        print "Generating API documentation ... (this may take a while)"
+        sys.path.insert(0, importpath)
+        m = __import__(module)
+        self.main_module = module
+        self.handle_module(m)
+        print "  saving..."
+        for x in self.modules:
+            if x.startswith(module):
+                f = open(outdir+x+".txt", "w")
+                f.write(self.modules[x])
+        print "API generated in %s." % (outdir)
+
+
+    def handle_module(self, mod):
+        mname = mod.__name__
+        if mname in self.modules:
+            # we already handled this module
+            return
+        self.modules[mname] = ""
+
+        # if you want to get the top level modules without "sympy.", uncomment
+        # this:
+        #if mname.startswith(self.main_module):
+        #    #strip the "sympy.":
+        #    s = ".. module:: %s\n\n" % mname[len(self.main_module)+1:]
+        #else:
+        #    s = ".. module:: %s\n\n" % mname
+
+        s = "=" * len(mname) + "\n"
+        s += mname + "\n"
+        s += "=" * len(mname) + "\n" + "\n"
+
+        s += ".. module:: %s\n\n" % mname
+        if hasattr(mod, __file__):
+            s += "filename: %s\n" % mod.__file__
+        for x in mod.__dict__.values():
+            if isinstance(x, types.ModuleType):
+                self.handle_module(x)
+            elif x is None:
+                pass
+            elif isinstance(x, (int, float, str, list, dict)):
+                # skip these
+                pass
+            elif str(type(x)) == "<type 'classobj'>":
+                # old style classes
+                pass
+            elif hasattr(x, "__class__"):
+                s += self.handle_class(x)
+            else:
+                print "  Ignored:", type(x), x
+        self.modules[mod.__name__] = s
+
+    def handle_class(self, cls):
+        if hasattr(cls, "__name__"):
+            s = "\n.. class:: %s\n" % cls.__name__
+        else:
+            return ""
+
+        # Uncomment this to generate class docstrings too:
+        # unfortunately, sphinx fails to read them, so we need to fix sympy
+        # first.
+        #doc = getdoc(cls)
+        #if doc is not None:
+        #    s += doc
+        #    s += "\n"
+
+        if hasattr(cls, "__dict__"):
+            for x in cls.__dict__.values():
+                if isinstance(x, types.ModuleType):
+                    self.handle_module(x)
+                elif str(type(x)) == "<type 'classobj'>":
+                    # old style classes
+                    pass
+                elif x is None:
+                    pass
+                elif ismethod(x):
+                    s += self.handle_method(x)
+                elif str(type(x)) == "<type 'property'>":
+                    pass
+                elif isinstance(x, (int, float, str, list, tuple, dict)):
+                    # skip these
+                    pass
+                elif hasattr(x, "__class__"):
+                    # ignore nested classes
+                    pass
+                else:
+                    print "    Ignored in class:", type(x), x
+
+        return s
+
+    def handle_method(self, m):
+        mname = get_method_name(m)
+        if mname is None:
+            s = ""
+        else:
+            s = "\n.. method:: %s%s\n\n" % (mname, get_method_args(m))
+            doc = getdoc(m)
+            if doc is not None:
+                s += doc
+                s += "\n"
+        return s
+
+Parser().generate_doc("sympy", importpath = "..", outdir="api/modules/")
diff --git a/lib/sympy/doc/logo/logo.txt b/lib/sympy/doc/logo/logo.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/logo/logo.txt
@@ -0,0 +1,10 @@
+I created this logo and permit its free use on the same terms as the rest of Sympy's code and documentation.
+
+Fredrik Johansson
+
+----------------
+
+This directory only contain the logo, that is distributed in the tarball.
+All files can be downloaded from:
+
+http://sympy.googlecode.com/svn/materials/logo/
diff --git a/lib/sympy/doc/logo/sympy-160px.png b/lib/sympy/doc/logo/sympy-160px.png
new file mode 100644
index 0000000000000000000000000000000000000000..66f923ed1b90005b02b1cb4d980800ffc741b7e4
GIT binary patch

[cut]

diff --git a/lib/sympy/doc/man/isympy.1 b/lib/sympy/doc/man/isympy.1
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/man/isympy.1
@@ -0,0 +1,73 @@
+'\" -*- coding: us-ascii -*-
+.if \n(.g .ds T< \\FC
+.if \n(.g .ds T> \\F[\n[.fam]]
+.de URL
+\\$2 \(la\\$1\(ra\\$3
+..
+.if \n(.g .mso www.tmac
+.TH isympy 1 2007-10-8 "" ""
+.SH NAME
+isympy \- interactive shell for SymPy
+.SH SYNOPSIS
+'nh
+.fi
+.ad l
+\fBisympy\fR \kx
+.if (\nx>(\n(.l/2)) .nr x (\n(.l/5)
+'in \n(.iu+\nxu
+[\fB-c\fR | \fB--console\fR]
+'in \n(.iu-\nxu
+.ad b
+'hy
+'nh
+.fi
+.ad l
+\fBisympy\fR \kx
+.if (\nx>(\n(.l/2)) .nr x (\n(.l/5)
+'in \n(.iu+\nxu
+[
+{\fB-h\fR | \fB--help\fR}
+| 
+{\fB-v\fR | \fB--version\fR}
+]
+'in \n(.iu-\nxu
+.ad b
+'hy
+.SH DESCRIPTION
+isympy is a Python shell for SymPy. It is just a normal python shell
+(ipython shell if you have the ipython package installed) that executes
+the following commands so that you don't have to:
+.PP
+.nf
+\*(T<
+>>> from __future__ import division
+>>> from sympy import *
+>>> x, y, z = symbols("xyz")
+>>> k, m, n = symbols("kmn", integer=True)
+    \*(T>
+.fi
+.PP
+So starting isympy is equivalent to starting python (or ipython) and
+executing the above commands by hand. It is intended for easy and quick
+experimentation with SymPy. For more complicated programs, it is recommended
+to write a script and import things explicitly (using the "from sympy
+import sin, log, Symbol, ..." idiom).
+.SH OPTIONS
+.TP 
+\*(T<\fB\-c \fR\*(T>\fIshell\fR, \*(T<\fB\-\-console=\fR\*(T>\fIshell\fR
+Use the specified shell (python or ipython) as
+console backend instead of the default one (ipython
+if present or python otherwise).
+
+Example: isympy -c python
+.SH FILES
+.TP 
+\*(T<\fI${HOME}/.sympy\-history\fR\*(T>
+Saves the history of commands when using the python
+shell as backend.
+.SH BUGS
+The upstreams BTS can be found at \(lahttp://code.google.com/p/sympy/issues/list\(ra
+Please report all bugs that you find in there, this will help improve
+the overall quality of SymPy.
+.SH "SEE ALSO"
+\fBipython\fR(1), \fBpython\fR(1)
diff --git a/lib/sympy/doc/man/isympy.xml b/lib/sympy/doc/man/isympy.xml
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/man/isympy.xml
@@ -0,0 +1,193 @@
+<?xml version='1.0' encoding='ISO-8859-1'?>
+<?xml-stylesheet type="text/xsl"
+	href="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+	"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+<!-- Process this file docbook2x-man:
+
+docbook2x-man isympy.xml
+
+this will generate isympy.1 in the current directory. -->
+
+  <!-- Fill in your name for FIRSTNAME and SURNAME.              -->
+  <!ENTITY dhfirstname "Fabian">
+  <!ENTITY dhsurname   "Seoane">
+  <!ENTITY dhemail     "fabian at fseoane.net">
+  <!-- dhusername could also be set to "&firstname; &surname;".  -->
+  <!ENTITY dhusername  "&dhfirstname; &dhsurname;">
+
+  <!-- Please adjust the date whenever revising the manpage.     -->
+  <!ENTITY dhdate      "2007-10-8">
+  <!ENTITY dhrelease   "unused">
+
+  <!-- TITLE should be something like "User commands",           -->
+  <!-- "&dhpackage; command-line reference" or similar (see e.g. -->
+  <!-- http://www.tldp.org/HOWTO/Man-Page/q2.html). But limit    -->
+  <!-- the length to 30 chars.                                   -->
+  <!ENTITY dhtitle     "&dhpackage; command-line reference">
+
+  <!ENTITY dhucpackage "isympy">
+  <!ENTITY dhpackage   "isympy">
+
+  <!-- If the application e.g. belongs to a package like X.org,  -->
+  <!-- this should be set to the its name instead.               -->
+  <!ENTITY dhproduct   "python-sympy">
+
+  <!-- SECTION should be 1-8, maybe w/ subsection other          -->
+  <!-- parameters are allowed: see man(7), man(1) and            -->
+  <!-- http://www.tldp.org/HOWTO/Man-Page/q2.html.               -->
+  <!ENTITY dhsection   "1">
+
+]>
+
+<refentry>
+	<refentryinfo>
+		<title>&dhtitle;</title>
+		<productname>&dhpackage;</productname>
+		<releaseinfo role="version">&dhrelease;</releaseinfo>
+		<date>&dhdate;</date>
+		<authorgroup>
+			<author>
+				<firstname>Ondrej</firstname>
+				<surname>Certik</surname>
+				<contrib>Design, programming.</contrib>
+				<address>
+					<email>ondrej at certik.cz</email>
+				</address>
+			</author>
+			<author>
+				<firstname>&dhfirstname;</firstname>
+				<surname>&dhsurname;</surname>
+				<contrib>Programming.</contrib>
+				<address>
+					<email>&dhemail;</email>
+				</address>
+			</author>
+		</authorgroup>
+		<copyright>
+			<year>2011</year>
+			<holder>SymPy Development Team</holder>
+		</copyright>
+		<legalnotice>
+			<para>Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:</para>
+			<orderedlist>
+				<listitem>
+					<para>Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.</para>
+				</listitem>
+				<listitem>
+					<para>Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.</para>
+				</listitem>
+			</orderedlist>
+			<para>THIS SOFTWARE IS PROVIDED BY THE AUTHOR &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</para>
+		</legalnotice>
+	</refentryinfo>
+	<refmeta>
+		<refentrytitle>&dhucpackage;</refentrytitle>
+		<manvolnum>&dhsection;</manvolnum>
+	</refmeta>
+	<refnamediv>
+		<refname>&dhpackage;</refname>
+		<refpurpose>interactive shell for SymPy</refpurpose>
+	</refnamediv>
+	<refsynopsisdiv>
+		<cmdsynopsis>
+			<command>&dhpackage;</command>
+			<group choice="opt">
+				<arg choice="plain"><option>-c</option></arg>
+				<arg choice="plain"><option>--console</option></arg>
+			</group>
+		</cmdsynopsis>
+		<cmdsynopsis>
+			<command>&dhpackage;</command>
+      <!-- Normally the help and version options make the programs stop
+			     right after outputting the requested information. -->
+			<group choice="opt">
+				<arg choice="plain">
+					<group choice="req">
+						<arg choice="plain"><option>-h</option></arg>
+						<arg choice="plain"><option>--help</option></arg>
+					</group>
+				</arg>
+				<arg choice="plain">
+					<group choice="req">
+						<arg choice="plain"><option>-v</option></arg>
+						<arg choice="plain"><option>--version</option></arg>
+					</group>
+				</arg>
+			</group>
+		</cmdsynopsis>
+	</refsynopsisdiv>
+	<refsect1 id="description">
+		<title>DESCRIPTION</title>
+    <para>isympy is a Python shell for SymPy. It is just a normal python shell
+        (ipython shell if you have the ipython package installed) that executes
+        the following commands so that you don't have to:
+    </para>
+
+    <programlisting>
+>>> from __future__ import division
+>>> from sympy import *
+>>> x, y, z = symbols("x,y,z")
+>>> k, m, n = symbols("k,m,n", integer=True)
+    </programlisting>
+
+    <para>So starting isympy is equivalent to starting python (or ipython) and
+    executing the above commands by hand. It is intended for easy and quick
+    experimentation with SymPy. For more complicated programs, it is recommended
+    to write a script and import things explicitly (using the "from sympy
+        import sin, log, Symbol, ..." idiom).</para>
+
+	</refsect1>
+	<refsect1 id="options">
+		<title>OPTIONS</title>
+		<variablelist>
+			<!-- Use the variablelist.term.separator and the
+			     variablelist.term.break.after parameters to
+			     control the term elements. -->
+			<varlistentry>
+				<term><option>-c <replaceable class="parameter">shell</replaceable></option></term>
+				<term><option>--console=<replaceable class="parameter">shell</replaceable></option></term>
+				<listitem>
+					<para>Use the specified shell (python or ipython) as
+                        console backend instead of the default one (ipython
+                        if present or python otherwise).</para>
+					<para>Example: isympy -c python</para>
+				</listitem>
+			</varlistentry>
+		</variablelist>
+	</refsect1>
+	<refsect1 id="files">
+		<title>FILES</title>
+		<variablelist>
+			<varlistentry>
+				<term><filename>${HOME}/.sympy-history</filename></term>
+				<listitem>
+					<para>Saves the history of commands when using the python
+                        shell as backend.</para>
+				</listitem>
+			</varlistentry>
+		</variablelist>
+	</refsect1>
+
+	<refsect1 id="bugs">
+		<!-- Or use this section to tell about upstream BTS. -->
+		<title>BUGS</title>
+		<para>The upstreams <acronym>BTS</acronym> can be found at <ulink
+                url="http://code.google.com/p/sympy/issues/list">http://code.google.com/p/sympy/issues/list</ulink>
+        Please report all bugs that you find in there, this will help improve
+        the overall quality of SymPy.</para>
+	</refsect1>
+	<refsect1 id="see_also">
+		<title>SEE ALSO</title>
+		<!-- In alpabetical order. -->
+		<para><citerefentry>
+				<refentrytitle>ipython</refentrytitle>
+				<manvolnum>1</manvolnum>
+			</citerefentry>, <citerefentry>
+				<refentrytitle>python</refentrytitle>
+				<manvolnum>1</manvolnum>
+			</citerefentry></para>
+	</refsect1>
+</refentry>
+
diff --git a/lib/sympy/doc/src/_static/sympylogo.png b/lib/sympy/doc/src/_static/sympylogo.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0d969e5b6df1c72198888d27470cd466904971b
GIT binary patch

[cut]

diff --git a/lib/sympy/doc/src/aboutus.txt b/lib/sympy/doc/src/aboutus.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/aboutus.txt
@@ -0,0 +1,172 @@
+About
+=====
+
+SymPy Development Team
+----------------------
+
+SymPy is a team project and it was developed by a lot of people.
+
+Here is a list of contributors together with what they do, (and in some cases links to their
+wiki pages), where they describe in
+more details what they do and what they are interested in (some people didn't
+want to be mentioned here, so see our repository history for a full list).
+
+#. Ond&#345;ej &#268;ert&#237;k: started the project in 2006, on Jan 4, 2011 passed the project leadership to Aaron Meurer
+#. Fabian Pedregosa: everything, reviewing patches, releases, general advice (issues and mailinglist), GSoC 2009
+#. Jurjen N.E. Bos: pretty printing and other patches
+#. Mateusz Paprocki: GSoC 2007, concrete math module, integration module, new core integration, a lot of patches, general advice, new polynomial module, improvements to solvers, simplifications, patch review
+#. Marc-Etienne M.Leveille: matrix patch
+#. Brian Jorgensen: GSoC 2007, plotting module and related things, patches
+#. Jason Gedge: GSoC 2007, geometry module, a lot of patches and fixes, new core integration
+#. Robert Schwarz: GSoC 2007, polynomials module, patches
+#. `Pearu Peterson <https://github.com/sympy/sympy/wiki/Pearu-Peterson>`_: new core, sympycore project, general advice (issues and mailinglist)
+#. `Fredrik Johansson <https://github.com/sympy/sympy/wiki/Fredrik-Johansson>`_: mpmath project and its integration in SymPy, number theory, combinatorial functions, products & summation, statistics, units, patches, documentation, general advice (issues and mailinglist)
+#. Chris Wu: GSoC 2007, linear algebra module
+#. Ulrich Hecht: pattern matching and other patches
+#. Goutham Lakshminarayan: number theory functions
+#. David Lawrence: GHOP, Mathematica parser, square root denesting
+#. Jaroslaw Tworek: GHOP, sympify AST implementation, sqrt() refactoring, maxima parser and other patches
+#. David Marek: GHOP, derivative evaluation patch, int(NumberSymbol) fix
+#. Bernhard R. Link: documentation patch
+#. Andrej Tokar&#269;&#237;k: GHOP, python printer
+#. Or Dvory: GHOP, documentation
+#. Saroj Adhikari: bug fixes
+#. Pauli Virtanen: bug fix
+#. Robert Kern: bug fix, common subexpression elimination
+#. James Aspnes: bug fixes
+#. Nimish Telang: multivariate lambdas
+#. Abderrahim Kitouni: pretty printing + complex expansion bug fixes
+#. Pan Peng: ode solvers patch
+#. Friedrich Hagedorn: many bug fixes, refactorings and new features added
+#. Elrond der Elbenfuerst: pretty printing fix
+#. Rizgar Mella: BBP formula for pi calculating algorithm
+#. Felix Kaiser: documentation + whitespace testing patches
+#. Roberto Nobrega: several pretty printing patches
+#. David Roberts: latex printing patches
+#. Sebastian Kr&#228;mer: implemented lambdify/numpy/mpmath cooperation, bug fixes, refactoring, lambdifying of matrices, large printing refactoring and bugfixes
+#. Vinzent Steinberg: docstring patches, a lot of bug fixes, nsolve (nonlinear equation systems solver), compiling functions to machine code, patches review
+#. Riccardo Gori: improvements and speedups to matrices, many bug fixes
+#. Case Van Horsen: implemented optional support for gmpy in mpmath
+#. &#352;t&#283;p&#225;n Rou&#269;ka: a lot of bug fixes all over sympy (matrix, simplification, limits, series, ...)
+#. Ali Raza Syed: pretty printing/isympy on windows fix
+#. Stefano Maggiolo: many bug fixes, polishings and improvements
+#. Robert Cimrman: matrix patches
+#. Bastian Weber: latex printing patches
+#. Sebastian Krause: match patches
+#. Sebastian Kreft: latex printing patches, Dirac delta function, other fixes
+#. Dan (coolg49964): documentation fixes
+#. Alan Bromborsky: geometric algebra modules
+#. Boris Timokhin: matrix fixes
+#. Robert (average.programmer): initial piecewise function patch
+#. Andy R. Terrel: piecewise function polishing and other patches
+#. Hubert Tsang: LaTeX printing fixes
+#. Konrad Meyer: policy patch
+#. Henrik Johansson: matrix zero finder patch
+#. Priit Laes: line integrals, cleanups in ODE, tests added
+#. Freddie Witherden: trigonometric simplifications fixes, LaTeX printer improvements
+#. Brian E. Granger: second quantization physics module
+#. Andrew Straw: lambdify() improvements
+#. Kaifeng Zhu: factorint() fix
+#. Ted Horst: Basic.__call__() fix, pretty printing fix
+#. Akshay Srinivasan: printing fix, improvements to integration
+#. Aaron Meurer: ODE solvers (GSoC 2009), The Risch Algorithm for integration (GSoC 2010), other fixes, project leader as of Jan 4, 2011
+#. Barry Wardell: implement series as function, several tests added
+#. Tomasz Buchert: ccode printing fixes, code quality concerning exceptions, documentation
+#. Vinay Kumar: polygamma tests
+#. Johann Cohen-Tanugi: commutative diff tests
+#. Jochen Voss: a test for the @cachit decorator and several other fixes
+#. Luke Peterson: improve solve() to handle Derivatives
+#. Chris Smith: improvements to solvers, many bug fixes, documentation and test improvements
+#. Thomas Sidoti: MathML printer improvements
+#. Florian Mickler: reimplementation of convex_hull, several geometry module fixes
+#. Nicolas Pourcelot: Infinity comparison fixes, latex fixes
+#. Ben Goodrich: Matrix.jacobian() function improvements and fixes
+#. Toon Verstraelen: code generation module, latex printing improvements
+#. Ronan Lamy: test coverage script; limit, expansion and other fixes and improvements; cleanup
+#. James Abbatiello: fixes tests on windows
+#. Ryan Krauss: fixes could_extract_minus_sign(), latex fixes and improvements
+#. Bill Flynn: substitution fixes
+#. Jorn Baayen: improvements to piecewise functions and latex printing, bug fixes
+#. Eh Tan: improve trigonometric simplification
+#. Renato Coutinho: derivative improvements
+#. Oscar Benjamin: latex printer fix
+#. &#216;yvind Jensen: implemented coupled cluster expansion and wick theorem, improvements to assumptions, bugfixes
+#. Julio Idichekop Filho: indentation fixes, docstring improvements
+#. &#321;ukasz Pankowski: fix matrix multiplication with numpy scalars
+#. Chu-Ching Huang: fix 3d plotting example
+#. Fernando Perez: symarray() implemented
+#. Raffaele De Feo: fix non-commutative expansion
+#. Christian Muise: fixes to logic module
+#. Matt Curry: GSoC 2010 project (symbolic quantum mechanics)
+#. Kazuo Thow: cleanup pretty printing tests
+#. Jezreel Ng: fix hyperbolic functions rewrite
+#. Matthew Brett: fixes to lambdify
+#. Addison Cugini: GSoC 2010 project (quantum computing)
+#. Nicholas J.S. Kinar: improved documentation about "Immutability of Expressions"
+#. Thomas Dixon: fix a limit bug
+#. Crist&#243;v&#227;o Sousa: implements _sage_ method for sign function.
+#. Andre de Fortier Smit: doctests in matrices improved
+#. Alexey U. Goodchenko: various work in matrices
+#. Gary Kerr: fix examples, docs
+#. Sherjil Ozair: fixes to SparseMatrix
+#. Oleksandr Gituliar: fixes to Matrix
+#. Sean Vig: Quantum improvement
+#. Prafullkumar P. Tale: fixed plotting documentation
+#. Vladimir Peri&#263;: fix some Python 3 issues
+#. Tom Bachmann: fixes to Real
+#. Yuri Karadzhov: improvements to hyperbolic identities
+#. Vladimir Lagunov: improvements to the geometry module
+#. Matthew Rocklin: improvements to Number instantiation
+#. Saptarshi Mandal: Test for an integral
+#. Gilbert Gede: Tests for solvers
+#. Anatolii Koval: Infinite 1D box example
+#. Tomo Lazovich: fixes to quantum operators
+#. Pavel Fedotov: fix to is_number
+#. Kibeom Kim: fixes to cse function and preorder_traversal
+#. Gregory Ksionda: fixes to Integral instantiation
+#. Tom&#225;&#353; Bambas: prettier printing of examples
+#. Jeremias Yehdegho: fixes to the nthoery module
+#. Jack McCaffery: fixes to asin and acos
+#. Luca Weihs: improvements to the geometry module
+#. Shai 'Deshe' Wyborski: fix to numeric evaluation of hypergeometric sums
+#. Thomas Wiecki: Fix Sum.diff
+#. &#211;scar N&#225;jera: better Laguerre polynomial generator
+#. Mario Pernici: faster algorithm for computing Groebner bases
+#. Benjamin McDonald: Fix bug in geometry
+#. Sam Magura: Improvements to Plot.saveimage
+#. Stefan Krastanov: Make Pyglet an external dependency
+#. Bradley Froehle: Fix shell command to generate modules in setup.py
+#. Min Ragan-Kelley: Fix isympy to work with IPython 0.11
+#. Emma Hogan: Fixes to the documentation
+#. Julien Rioux: Fix behavior of some deprecated methods
+#. Roberto Colistete, Jr.: Add num_columns option to the pretty printer
+#. Raoul Bourquin: Implement Euler numbers
+#. Gert-Ludwig Ingold: Correct derivative of coth
+
+Up-to-date list in the order of the first contribution is given in the `AUTHORS
+<https://github.com/sympy/sympy/blob/master/AUTHORS>`_ file.
+
+You can find a brief history of SymPy in the README.
+
+Financial and Infrastructure Support
+------------------------------------
+
+* `Google <http://www.google.com/corporate/>`_: SymPy has received generous financial support from Google in 2007 by financing 5 students through the Google Summer of Code (GSOC 2007) program (`more info <http://code.google.com/p/sympy/wiki/GSoC2007>`_) and 1 student in 2008 (`more info <http://code.google.com/p/sympy/wiki/GSoC2008>`_)
+
+* `Python Software Foundation <http://www.python.org/psf/>`_: PSF hosted 3 GSoC 2007 students (Brian, Robert and Jason), and 1 GSoC 2008 student (Fredrik)
+
+* `the Space Telescope Science Institute <http://www.stsci.edu/portal/>`_: STScI hosted 1 GSoC 2007 student (Mateusz)
+
+* `Portland State University <http://www.pdx.edu/>`_: PSU hosted 1 GSoC 2007 student (Chris)
+
+* `Simula Research Laboratory <http://www.simula.no/>`_: supports Pearu Peterson work in SymPy/Sympy Core projects
+
+License
+-------
+
+Unless stated otherwise, all files in the SymPy project, SymPy's webpage (and
+wiki), all images and all documentation including this User's Guide is licensed
+using the new BSD license:
+
+.. literalinclude:: ../../LICENSE
+
diff --git a/lib/sympy/doc/src/conf.py b/lib/sympy/doc/src/conf.py
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/conf.py
@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*-
+#
+# SymPy documentation build configuration file, created by
+# sphinx-quickstart.py on Sat Mar 22 19:34:32 2008.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# All configuration values have a default value; values that are commented out
+# serve to show the default value.
+
+import sys
+
+# If your extensions are in another directory, add it here.
+sys.path.extend(['../sympy', 'ext'])
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'mathjax', ]
+
+# Use this to use pngmath instead
+#extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.pngmath', ]
+
+# MathJax file, which is free to use.  See https://bitbucket.org/kevindunn/sphinx-extension-mathjax/wiki/Home
+mathjax_path = 'http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full'
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['.templates']
+
+# The suffix of source filenames.
+source_suffix = '.txt'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'SymPy'
+copyright = '2008, 2009, 2010, 2011 SymPy Development Team'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+#
+# The short X.Y version.
+version = '0.7.1'
+# The full version, including alpha/beta/rc tags.
+release = '0.7.1-git'
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+html_style = 'default.css'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+html_logo = '_static/sympylogo.png'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Content template for the index page.
+#html_index = ''
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'SymPydoc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+latex_documents = [('index', 'sympy.tex', 'SymPy Documentation',
+                        'SymPy Development Team', 'manual')]
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
+
+default_role = 'math'
+pngmath_divpng_args = ['-gamma 1.5','-D 110']
+# Note, this is ignored by the mathjax extension
+# Any \newcommand should be defined in the file
+pngmath_latex_preamble =  '\\usepackage{amsmath}\n'+\
+              '\\usepackage{bm}\n'+\
+              '\\usepackage{amsfonts}\n'+\
+              '\\usepackage{amssymb}\n'+\
+              '\\setlength{\\parindent}{0pt}\n'
diff --git a/lib/sympy/doc/src/figures/admon-note.png b/lib/sympy/doc/src/figures/admon-note.png
new file mode 100644
index 0000000000000000000000000000000000000000..4ffa19c734b05a4092ffcd79b3219476f1fde4a1
GIT binary patch

[cut]

diff --git a/lib/sympy/doc/src/figures/featured-downloads.png b/lib/sympy/doc/src/figures/featured-downloads.png
new file mode 100644
index 0000000000000000000000000000000000000000..db50c63ed3fb3c3360c067158b1a5e1f05ecad0c
GIT binary patch

[cut]

diff --git a/lib/sympy/doc/src/gotchas.txt b/lib/sympy/doc/src/gotchas.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/gotchas.txt
@@ -0,0 +1,624 @@
+.. _gotchas:
+
+====================
+Gotchas and Pitfalls
+====================
+
+.. role:: input(strong)
+
+Introduction
+============
+SymPy runs under the `Python Programming Language
+<http://www.python.org/>`_, so there are some things that may behave
+differently than they do in other, independent computer algebra systems
+like Maple or Mathematica.  These are some of the gotchas and pitfalls
+that you may encounter when using SymPy.  See also the `FAQ
+<https://github.com/sympy/sympy/wiki/Faq>`_, the :ref:`Tutorial<tutorial>`, the
+remainder of the SymPy Docs, and the `official Python Tutorial
+<http://docs.python.org/tutorial/>`_.
+
+If you are already familiar with C or Java, you might also want to look
+this `4 minute Python tutorial
+<http://www.nerdparadise.com/tech/python/4minutecrashcourse/>`_.
+
+Ignore ``#doctest: +SKIP`` in the examples.  That has to do with
+internal testing of the examples.
+
+.. _equals-signs:
+
+Equals Signs (=)
+================
+Single Equals Sign
+------------------
+The equals sign (``=``) is the assignment operator, not an equality.  If
+you want to do :math:`x=y`, use ``Eq(x,y)`` for equality.
+Alternatively, all expressions are assumed to equal zero, so you can
+just subtract one side and use ``x - y``.
+
+The proper use of the equals sign is to assign expressions to variables.
+
+For example:
+
+    >>> from sympy.abc import x, y
+    >>> a = x - y
+    >>> print a
+    x - y
+
+Double Equals Signs
+-------------------
+Double equals signs (``==``) are used to test equality.  However, this
+tests expressions exactly, not symbolically.  For example:
+
+    >>> (x + 1)**2 == x**2 + 2*x + 1
+    False
+    >>> (x + 1)**2 == (x + 1)**2
+    True
+
+If you want to test for symbolic equality, one way is to subtract one
+expression from the other and run it through functions like
+:func:`expand`, :func:`simplify`, and :func:`trigsimp` and see if the
+equation reduces to 0.
+
+    >>> from sympy import simplify, cos, sin, expand
+    >>> simplify((x + 1)**2 - (x**2 + 2*x + 1))
+    0
+    >>> simplify(sin(2*x) - 2*sin(x)*cos(x))
+    -2*sin(x)*cos(x) + sin(2*x)
+    >>> expand(sin(2*x) - 2*sin(x)*cos(x), trig=True)
+    0
+
+.. note::
+
+    See also `Why does SymPy say that two equal expressions are unequal? 
+    <https://github.com/sympy/sympy/wiki/Faq>`_ in the FAQ.
+
+
+Variables
+=========
+Variables Assignment does not Create a Relation Between Expressions
+-------------------------------------------------------------------
+When you use ``=`` to do assignment, remember that in Python, as in most
+programming languages, the variable does not change if you change the
+value you assigned to it.  The equations you are typing use the values
+present at the time of creation to "fill in" values, just like regular
+Python definitions. They are not altered by changes made afterwards.
+Consider the following:
+
+    >>> from sympy import Symbol
+    >>> a = Symbol('a') # Create a Symbol named a, that is also stored in the variable "a"
+    >>> b = a + 1       # Create another object, b, that refers to 'a'
+    >>> print b
+    a + 1
+    >>> a = 4           # a now points to the literal integer 4, not Symbol('a')
+    >>> print a
+    4
+    >>> b               # But b is still pointing at Symbol('a')
+    a + 1
+
+Changing quantity :obj:`a` does not change :obj:`b`; you are not working
+with a set of simultaneous equations. It might be helpful to remember
+that the string that gets printed when you print a variable referring to
+a SymPy object is the string that was given to it when it was created;
+that string does not have to be the same as the variable that you assign
+it to.
+
+    >>> from sympy import var
+    >>> r, t, d = var('rate time short_life')
+    >>> d = r*t
+    >>> print d
+    rate*time
+    >>> r=80
+    >>> t=2
+    >>> print d         # We haven't changed d, only r and t
+    rate*time
+    >>> d=r*t
+    >>> print d         # Now d is using the current values of r and t
+    160
+
+
+If you need variables that have dependence on each other, you can define
+functions.  Use the ``def`` operator.  Indent the body of the function.
+See the Python docs for more information on defining functions.
+
+    >>> c, d = var('c d')
+    >>> print c
+    c
+    >>> print d
+    d
+    >>> def ctimesd():
+    ...     """
+    ...     This function returns whatever c is times whatever d is.
+    ...     """
+    ...     return c*d
+    ...
+    >>> ctimesd()
+    c*d
+    >>> c = 2
+    >>> print c
+    2
+    >>> ctimesd()
+    2*d
+
+
+If you define a circular relationship, you will get a
+:exc:`RuntimeError`.
+
+    >>> def a():
+    ...     return b()
+    ...
+    >>> def b():
+    ...     return a()
+    ...
+    >>> a()
+    Traceback (most recent call last):
+      File "...", line ..., in ...
+        compileflags, 1) in test.globs
+      File "<...>", line 1, in <module>
+        a()
+      File "<...>", line 2, in a
+        return b()
+      File "<...>", line 2, in b
+        return a()
+      File "<...>", line 2, in a
+        return b()
+    ...
+    RuntimeError: maximum recursion depth exceeded
+
+
+.. note::
+    See also `Why doesn't changing one variable change another that depends on it? 
+    <https://github.com/sympy/sympy/wiki/Faq>`_ in the FAQ.
+
+.. _symbols:
+
+Symbols
+-------
+Symbols are variables, and like all other variables, they need to be
+assigned before you can use them.  For example:
+
+    >>> import sympy
+    >>> z**2 # z is not defined yet #doctest: +SKIP
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    NameError: name 'z' is not defined
+    >>> sympy.var('z') # This is the easiest way to define z as a standard symbol
+    z
+    >>> z**2
+    z**2
+
+
+If you use :command:`isympy`, it runs the following commands for you,
+giving you some default Symbols and Functions.
+
+    >>> from __future__ import division
+    >>> from sympy import *
+    >>> x, y, z, t = symbols('x y z t')
+    >>> k, m, n = symbols('k m n', integer=True)
+    >>> f, g, h = map(Function, 'fgh')
+
+You can also import common symbol names from :mod:`sympy.abc`.
+
+    >>> from sympy.abc import w
+    >>> w
+    w
+    >>> import sympy
+    >>> dir(sympy.abc) #doctest: +SKIP
+    ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+    'P', 'Q', 'R', 'S', 'Symbol', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+    '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_greek',
+    '_latin', 'a', 'alpha', 'b', 'beta', 'c', 'chi', 'd', 'delta', 'e',
+    'epsilon', 'eta', 'f', 'g', 'gamma', 'h', 'i', 'iota', 'j', 'k', 'kappa',
+    'l', 'm', 'mu', 'n', 'nu', 'o', 'omega', 'omicron', 'p', 'phi', 'pi',
+    'psi', 'q', 'r', 'rho', 's', 'sigma', 't', 'tau', 'theta', 'u', 'upsilon',
+    'v', 'w', 'x', 'xi', 'y', 'z', 'zeta']
+
+If you want control over the assumptions of the variables, use
+:func:`Symbol` and :func:`symbols`.  See :ref:`Keyword
+Arguments<keyword-arguments>` below.
+
+Lastly, it is recommended that you not use :obj:`I`, :obj:`E`, :obj:`S`,
+:obj:`N`, :obj:`C`, :obj:`O`, or :obj:`Q` for variable or symbol names, as those
+are used for the imaginary unit (:math:`i`), the base of the natural
+logarithm (:math:`e`), the :func:`sympify` function (see :ref:`Symbolic
+Expressions<symbolic-expressions>` below), numeric evaluation (:func:`N`
+is equivalent to :ref:`evalf()<evalf-label>` ), the class registry (for
+things like :func:`C.cos`, to prevent cyclic imports in some code),
+the `big O <http://en.wikipedia.org/wiki/Big_O_notation>`_ order symbol
+(as in :math:`O(n\log{n})`), and the assumptions object that holds a list of
+supported ask keys (such as :obj:`Q.real`), respectively.  You can use the
+mnemonic ``QCOSINE`` to remember what Symbols are defined by default in SymPy.
+Or better yet, always use lowercase letters for Symbol names.  Python will
+not prevent you from overriding default SymPy names or functions, so be
+careful.
+
+    >>> cos(pi) # cos and pi are a built-in sympy names.
+    -1
+    >>> pi = 3 # Notice that there is no warning for overriding pi.
+    >>> cos(pi)
+    cos(3)
+    >>> def cos(x): # No warning for overriding built-in functions either.
+    ...     return 5*x
+    ...
+    >>> cos(pi)
+    15
+
+
+
+To get a full list of all default names in SymPy do:
+
+    >>> import sympy
+    >>> dir(sympy) #doctest: +SKIP
+    # A big list of all default sympy names and functions follows.
+    # Ignore everything that starts and ends with __.
+
+If you have `iPython <http://ipython.scipy.org/moin/>`_ installed and
+use :command:`isympy`, you can also press the TAB key to get a list of
+all built-in names and to autocomplete.  Also, see `this page
+<http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks>`_ for a
+trick for getting tab completion in the regular Python console.
+
+.. note::
+    See also `What is the best way to create symbols? 
+    <https://github.com/sympy/sympy/wiki/Faq>`_ in the FAQ.
+
+.. _symbolic-expressions:
+
+Symbolic Expressions
+====================
+.. _python-vs-sympy-numbers:
+
+Python numbers vs. SymPy Numbers
+--------------------------------
+SymPy uses its own classes for integers, rational numbers, and floating
+point numbers instead of the default Python :obj:`int` and :obj:`float`
+types because it allows for more control.  But you have to be careful.
+If you type an expression that just has numbers in it, it will default
+to a Python expression.  Use the :func:`sympify` function, or just
+:func:`S`, to ensure that something is a SymPy expression.
+
+    >>> 6.2 # Python float. Notice the floating point accuracy problems. #doctest: +SKIP
+    6.2000000000000002
+    >>> type(6.2)
+    <... 'float'>
+    >>> S(6.2) # SymPy Float has no such problems because of arbitrary precision.
+    6.20000000000000
+    >>> type(S(6.2))
+    <class 'sympy.core.numbers.Float'>
+
+If you include numbers in a SymPy expression, they will be sympified
+automatically, but there is one gotcha you should be aware of.  If you
+do ``<number>/<number>`` inside of a SymPy expression, Python will
+evaluate the two numbers before SymPy has a chance to get
+to them.  The solution is to :func:`sympify` one of the numbers, or use
+:mod:`Rational`.
+
+    >>> x**(1/2) # evaluates to x**0 or x**0.5 #doctest: +SKIP
+    x**0.5
+    >>> x**(S(1)/2) # sympyify one of the ints
+    sqrt(x)
+    >>> x**Rational(1, 2) # use the Rational class
+    sqrt(x)
+
+With a power of ``1/2`` you can also use ``sqrt`` shorthand:
+
+    >>> sqrt(x) == x**Rational(1, 2)
+    True
+
+If the two integers are not directly separated by a division sign then
+you don't have to worry about this problem:
+
+    >>> x**(2*x/3)
+    x**(2*x/3)
+
+.. note::
+
+    A common mistake is copying an expression that is printed and
+    reusing it.  If the expression has a :mod:`Rational` (i.e.,
+    ``<number>/<number>``) in it, you will not get the same result,
+    obtaining the Python result for the division rather than a SymPy
+    Rational.
+
+    >>> x = Symbol('x')
+    >>> print solve(7*x -22,x)
+    [22/7]
+    >>> 22/7 # If we just copy and paste we get int 3 or a float #doctest: +SKIP
+    3.142857142857143
+    >>> # One solution is to just assign the expression to a variable
+    >>> # if we need to use it again.
+    >>> a = solve(7*x - 22,x)
+    >>> a
+    [22/7]
+    >>> # The other solution is to put quotes around the expression and run it through S() (sympify)
+    >>> S("22/7")
+    22/7
+
+Also, if you do not use :command:`isympy`, you could use ``from
+__future__ import division`` to prevent the ``/`` sign from performing
+`integer division <http://en.wikipedia.org/wiki/Integer_division>`_.
+
+    >>> from __future__ import division
+    >>> 1/2 # with division imported it evaluates to a python float #doctest: +SKIP
+    0.5
+    >>> 1//2 # You can still achieve integer division with //
+    0
+
+    But be careful: you will now receive floats where you might have desired
+    a Rational:
+
+    >>> x**(1/2) #doctest: +SKIP
+    x**0.5
+
+:mod:`Rational` only works for number/number and is only meant for
+rational numbers.  If you want a fraction with symbols or expressions in
+it, just use ``/``.  If you do number/expression or expression/number,
+then the number will automatically be converted into a SymPy Number.
+You only need to be careful with number/number.
+
+    >>> Rational(2, x)
+    Traceback (most recent call last):
+      File "...", line ..., in ...
+        compileflags, 1) in test.globs
+      File "<...>", line 1, in <module>
+        Rational(2, x)
+      ...
+    TypeError: int() argument must be a string or a number, not 'Symbol'
+    >>> 2/x
+    2/x
+
+
+.. _Immutability-of-Expressions:
+
+Immutability of Expressions
+---------------------------
+
+Expressions in SymPy are immutable, and cannot be modified by an in-place
+operation.  This means that a function will always return an object, and the
+original expression will not be modified. The following example snippet
+demonstrates how this works::
+
+	def main():
+	    var('x y a b')
+	    expr = 3*x + 4*y
+	    print 'original =', expr
+	    expr_modified = expr.subs({x:a, y:b})
+	    print 'modified = ', expr_modified
+
+	if __name__ == "__main__":
+	    main()
+
+The output shows that the :func:`subs` function has replaced variable
+:obj:`x` with variable :obj:`a`, and variable :obj:`y` with variable :obj:`b`::
+
+	original = 3*x + 4*y
+	modified =  3*a + 4*b
+
+The :func:`subs` function does not modify the original expression :obj:`expr`.
+Rather, a modified copy of the expression is returned. This returned object
+is stored in the variable :obj:`expr_modified`. Note that unlike C/C++ and
+other high-level languages, Python does not require you to declare a variable
+before it is used.
+
+
+Mathematical Operators
+----------------------
+SymPy uses the same default operators as Python.  Most of these, like
+``*/+-``, are standard.  Aside from integer division discussed in
+:ref:`Python numbers vs. SymPy Numbers <python-vs-sympy-numbers>` above,
+you should also be aware that implied multiplication is not allowed. You
+need to use ``*`` whenever you wish to multiply something.  Also, to
+raise something to a power, use ``**``, not ``^`` as many computer
+algebra systems use.  Parentheses ``()`` change operator precedence as
+you would normally expect.
+
+In :command:`isympy`, with the :command:`ipython` shell::
+
+    >>> 2x
+    Traceback (most recent call last):
+    ...
+    SyntaxError: invalid syntax
+    >>> 2*x
+    2*x
+    >>> (x+1)^2 # This is not power.  Use ** instead.
+    Traceback (most recent call last):
+    ...
+    TypeError: unsupported operand type(s) for ^: 'Add' and 'int'
+    >>> (x+1)**2
+    (x + 1)**2
+    >>> pprint(3 - x**(2*x)/(x + 1))
+        2*x
+       x
+    - ----- + 3
+      x + 1
+
+
+Inverse Trig Functions
+----------------------
+SymPy uses different names for some functions than most computer algebra
+systems.  In particular, the inverse trig functions use the python names
+of :func:`asin`, :func:`acos` and so on instead of the usual ``arcsin``
+and ``arccos``.  Use the methods described in :ref:`Symbols <symbols>`
+above to see the names of all SymPy functions.
+
+Special Symbols
+===============
+The symbols ``[]``, ``{}``, ``=``, and ``()`` have special meanings in
+Python, and thus in SymPy.  See the Python docs linked to above for
+additional information.
+
+.. _lists:
+
+Lists
+-----
+Square brackets ``[]`` denote a list.  A list is a container that holds
+any number of different objects.  A list can contain anything, including
+items of different types.  Lists are mutable, which means that you can
+change the elements of a list after it has been created.  You access the
+items of a list also using square brackets, placing them after the list
+or list variable.  Items are numbered using the space before the item.
+
+.. note::
+
+    List indexes begin at 0.
+
+Example:
+
+    >>> a = [x, 1] # A simple list of two items
+    >>> a
+    [x, 1]
+    >>> a[0] # This is the first item
+    x
+    >>> a[0] = 2 # You can change values of lists after they have been created
+    >>> print a
+    [2, 1]
+    >>> print solve(x**2+2*x-1,x) # Some functions return lists
+    [-1 + sqrt(2), -sqrt(2) - 1]
+
+
+.. note::
+    See the Python docs for more information on lists and the square
+    bracket notation for accessing elements of a list.
+
+Dictionaries
+------------
+Curly brackets ``{}`` denote a dictionary, or a dict for short.  A
+dictionary is an unordered list of non-duplicate keys and values.  The
+syntax is ``{key:value}``.  You can access values of keys using square
+bracket notation.
+
+    >>> d = {'a':1, 'b':2} # A dictionary.
+    >>> d
+    {'a': 1, 'b': 2}
+    >>> d['a'] # How to access items in a dict
+    1
+    >>> roots((x-1)**2*(x-2),x) # some functions return dicts
+    {1: 2, 2: 1}
+    >>> # Some SymPy functions return dictionaries.  For example,
+    >>> # roots returns a dictionary of root:multiplicity items.
+    >>> roots((x - 5)**2*(x + 3),x)
+    {-3: 1, 5: 2}
+    >>> # This means that the root -3 occurs once and the root 5 occurs twice.
+
+.. note::
+
+    See the Python docs for more information on dictionaries.
+
+Tuples
+------
+Parentheses ``()``, aside from changing operator precedence and their
+use in function calls, (like ``cos(x)``), are also used for tuples.  A
+``tuple`` is identical to a :ref:`list <lists>`, except that it is not
+mutable.  That means that you can not change their values after they
+have been created.  In general, you will not need tuples in SymPy, but
+sometimes it can be more convenient to type parentheses instead of
+square brackets.
+
+    >>> t = (1, 2, x) # Tuples are like lists
+    >>> t
+    (1, 2, x)
+    >>> t[0]
+    1
+    >>> t[0] = 4 # Except you can not change them after they have been created
+    Traceback (most recent call last):
+      File "<console>", line 1, in <module>
+    TypeError: 'tuple' object does not support item assignment
+    >>> (x,) # Single element tuples, unlike lists, must have a comma in them.
+    (x,)
+    >>> (x) # Not a tuple
+    x
+    >>> # integrate takes a tuple as the second argument if you want to integrate with limits.
+    >>> integrate(x**2, (x, 0, 1))
+    1/3
+    >>> integrate(x**2, [x, 0, 1]) # But a list works too.
+    1/3
+
+
+.. note::
+
+    See the Python docs for more information on tuples.
+
+.. _keyword-arguments:
+
+Keyword Arguments
+-----------------
+Aside from the usage described :ref:`above <equals-signs>`, equals signs
+(``=``) are also used to give named arguments to functions.  Any
+function that has ``key=value`` in its parameters list (see below on how
+to find this out), then ``key`` is set to ``value`` by default.  You can
+change the value of the key by supplying your own value using the equals
+sign in the function call.  Also, functions that have ``**`` followed by
+a name in the parameters list (usually ``**kwargs`` or
+``**assumptions``) allow you to add any number of ``key=value`` pairs
+that you want, and they will all be evaluated according to the function.
+
+    >>> # sqrt(x**2) doesn't auto simplify to x because x is assumed to be
+    >>> # complex by default, and, for example, sqrt((-1)**2) == sqrt(1) == 1 != -1.
+    >>> sqrt(x**2)
+    sqrt(x**2)
+    >>> x = Symbol('x', positive=True) # One example of keyword arguments is assumptions for Symbols
+    >>> sqrt(x**2) # only == x if x >= 0
+    x
+    >>> pprint(powsimp(x**n*x**m*y**n*y**m)) # powsimp has a default argument, combine='all'
+         m + n
+    (x*y)
+    >>> # Setting combine to the default value is the same as not setting it.
+    >>> pprint(powsimp(x**n*x**m*y**n*y**m, combine='all'))
+         m + n
+    (x*y)
+    >>> # The non-default options are 'exp', which combines exponents...
+    >>> pprint(powsimp(x**n*x**m*y**n*y**m, combine='exp'))
+     m + n  m + n
+    x     *y
+    >>> # ...and 'base', which combines bases.
+    >>> pprint(powsimp(x**n*x**m*y**n*y**m, combine='base'))
+         m      n
+    (x*y) *(x*y)
+
+.. note::
+
+    See the Python docs for more information on function parameters.
+
+Getting help from within SymPy
+==============================
+help()
+------
+Although all docs are available at `docs.sympy.org <http://docs.sympy.org/>`_ or on the 
+`SymPy Wiki <http://wiki.sympy.org/>`_, you can also get info on functions from within the 
+Python interpreter that runs SymPy.  The easiest way to do this is to do 
+``help(function)``, or ``function?`` if you are using :command:`ipython`::
+
+    In [1]: help(powsimp) # help() works everywhere
+
+    In [2]: # But in ipython, you can also use ?, which is better because it
+    In [3]: # it gives you more information
+    In [4]: powsimp?
+
+These will give you the function parameters and docstring for
+:func:`powsimp`.  The output will look something like this:
+
+.. module:: sympy.simplify.simplify
+.. autofunction:: powsimp
+
+source()
+--------
+Another useful option is the :func:`source` function.  This will print
+the source code of a function, including any docstring that it may have.
+You can also do ``function??`` in :command:`ipython`.  For example,
+from SymPy 0.6.5:
+
+    >>> source(simplify) # simplify() is actually only 2 lines of code. #doctest: +SKIP
+    In file: ./sympy/simplify/simplify.py
+    def simplify(expr):
+        """Naively simplifies the given expression.
+           ...
+           Simplification is not a well defined term and the exact strategies
+           this function tries can change in the future versions of SymPy. If
+           your algorithm relies on "simplification" (whatever it is), try to
+           determine what you need exactly  -  is it powsimp()? radsimp()?
+           together()?, logcombine()?, or something else? And use this particular
+           function directly, because those are well defined and thus your algorithm
+           will be robust.
+           ...
+        """
+        expr = Poly.cancel(powsimp(expr))
+        return powsimp(together(expr.expand()), combine='exp', deep=True)
+
diff --git a/lib/sympy/doc/src/guide.txt b/lib/sympy/doc/src/guide.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/guide.txt
@@ -0,0 +1,536 @@
+.. _guide:
+
+==================
+SymPy User's Guide
+==================
+
+.. role:: input(strong)
+
+Introduction
+============
+
+If you are new to Sympy, start with the :ref:`Tutorial <tutorial>`. If you went
+through it, now
+it's time to learn how SymPy works internally and this is what this guide is
+about. Once you grasp the idea behind SymPy, you will be able to use it
+effectively and also know how to extend it and fix it.
+You may also be just interested in :ref:`SymPy Modules Reference <module-docs>`.
+
+Learning SymPy
+==============
+
+Everyone has different ways of understanding the code written by others.
+
+Ond&#345;ej's approach
+-----------------
+
+Let's say I'd like to understand how ``x+y+x`` works and how it is possible
+that it gets simplified to ``2*x+y``.
+
+I write a simple script, I usually call it ``t.py`` (I don't remember anymore
+why I call it that way)::
+
+    from sympy.abc import x, y
+
+    e = x + y +x
+
+    print e
+
+And I try if it works
+
+.. parsed-literal::
+
+    $ :input:`python t.py`
+    y + 2*x
+
+Now I start `winpdb <http://winpdb.org/>`_ on it (if you've never used winpdb
+-- it's an excellent multiplatform debugger, works on Linux, Windows and Mac OS
+X):
+
+.. parsed-literal::
+
+    $ :input:`winpdb t.py`
+    y + 2*x
+
+and a winpdb window will popup, I move to the next line using F6:
+
+.. image:: pics/winpdb1.png
+
+Then I step into (F7) and after a little debugging I get for example:
+
+.. image:: pics/winpdb2.png
+
+.. tip:: Make the winpdb window larger on your screen, it was just made smaller to fit in
+         this guide.
+
+I see values of all local variables in the left panel, so it's very easy to see
+what's happening. You can see, that the ``y+2*x`` is emerging in the ``obj``
+variable. Observing that ``obj`` is constructed from ``c_part`` and ``nc_part``
+and seeing what ``c_part`` contains (``y`` and ``2*x``). So looking at the line
+28 (the whole line is not visible on the screenshot, so here it is)::
+
+    c_part, nc_part, lambda_args, order_symbols = cls.flatten(map(_sympify, args))
+
+you can see that the simplification happens in ``cls.flatten``. Now you can set
+the breakpoint on the line 28, quit winpdb (it will remember the breakpoint),
+start it again, hit F5, this will stop at this breakpoint, hit F7, this will go
+into the function ``Add.flatten()``::
+
+    @classmethod
+    def flatten(cls, seq):
+        """
+        Takes the sequence "seq" of nested Adds and returns a flatten list.
+
+        Returns: (commutative_part, noncommutative_part, lambda_args,
+            order_symbols)
+
+        Applies associativity, all terms are commutable with respect to
+        addition.
+        """
+        terms = {}      # term -> coeff
+                        # e.g. x**2 -> 5   for ... + 5*x**2 + ...
+
+        coeff = S.Zero  # standalone term
+                        # e.g. 3 + ...
+        lambda_args = None
+        order_factors = []
+        while seq:
+            o = seq.pop(0)
+
+and then you can study how it works. I am going to stop here, this should be
+enough to get you going -- with the above technique, I am able to understand
+almost any Python code.
+
+
+SymPy's Architecture
+====================
+
+We try to make the sources easily understandable, so you can look into the sources and
+read the doctests, it should be well documented and if you don't understand something,
+ask on the mailinglist_.
+
+You can find all the decisions archived in the issues_, to see rationale for
+doing this and that.
+
+Basics
+------
+
+All symbolic things are implemented using subclasses of the ``Basic`` class.
+First, you need to create symbols using ``Symbol("x")`` or numbers using
+``Integer(5)`` or ``Float(34.3)``. Then you construct the expression using any
+class from SymPy.  For example ``Add(Symbol("a"), Symbol("b"))`` gives an
+instance of the ``Add`` class.  You can call all methods, which the particular
+class supports.
+
+For easier use, there is a syntactic sugar for expressions like:
+
+``cos(x)+1`` is equal to ``cos(x).__add__(1)`` is equal to ``Add(cos(x),Integer(1))``
+
+or
+
+``2/cos(x)`` is equal to ``cos(x).__rdiv__(2)`` is equal to
+``Mul(Rational(2),Pow(cos(x),Rational(-1)))``.
+
+So, you can write normal expressions using python arithmetics like this::
+
+    a=Symbol("a")
+    b=Symbol("b")
+    e=(a+b)**2
+    print e
+
+but from the sympy point of view, we just need the classes ``Add``, ``Mul``, ``Pow``,
+``Rational``, ``Integer``.
+
+Automatic evaluation to canonical form
+--------------------------------------
+
+For computation, all expressions need to be in a
+canonical form, this is done during the creation of the particular instance
+and only inexpensive operations are performed, necessary to put the expression
+in the
+canonical form.  So the canonical form doesn't mean the simplest possible
+expression. The exact list of operations performed depend on the
+implementation.  Obviously, the definition of the canonical form is arbitrary,
+the only requirement is that all equivalent expressions must have the same
+canonical form.  We tried the conversion to a canonical (standard) form to be
+as fast as possible and also in a way so that the result is what you would
+write by hand - so for example ``b*a + -4 + b + a*b + 4 + (a+b)**2`` becomes
+``2*a*b + b + (a+b)**2``.
+
+Whenever you construct an expression, for example ``Add(x, x)``, the
+``Add.__new__()`` is called and it determines what to return. In this case::
+
+    >>> from sympy import Add
+    >>> from sympy.abc import x
+    >>> e = Add(x, x)
+    >>> e
+    2*x
+
+    >>> type(e)
+    <class 'sympy.core.mul.Mul'>
+
+``e`` is actually an instance of ``Mul(2, x)``, because ``Add.__new__()``
+returned ``Mul``.
+
+Comparisons
+-----------
+
+Expressions can be compared using a regular python syntax::
+
+    >>> from sympy.abc import x, y
+    >>> x+y == y+x
+    True
+
+    >>> x+y == y-x
+    False
+
+We made the following decision in SymPy: ``a=Symbol("x")`` and another
+``b=Symbol("x")`` (with the same string "x") is the same thing, i.e ``a==b`` is
+``True``. We chose ``a==b``, because it is more natural - ``exp(x)==exp(x)`` is
+also ``True`` for the same instance of ``x`` but different instances of ``exp``,
+so we chose to have ``exp(x)==exp(x)`` even for different instances of ``x``.
+
+Sometimes, you need to have a unique symbol, for example as a temporary one in
+some calculation, which is going to be substituted for something else at the
+end anyway. This is achieved using ``Dummy("x")``. So, to sum it
+up::
+
+    >>> from  sympy import Symbol, Dummy
+    >>> Symbol("x") == Symbol("x")
+    True
+
+    >>> Dummy("x") == Dummy("x")
+    False
+
+
+Debugging
+---------
+
+Starting with 0.6.4, you can turn on/off debug messages with the environment variable
+SYMPY_DEBUG, which is expected to have the values True or False. For example, to turn on
+debugging, you would issue::
+
+    [user at localhost]: SYMPY_DEBUG=True ./bin/isympy
+
+Functionality
+-------------
+
+There are no given requirements on classes in the library. For example, if they
+don't implement the ``fdiff()`` method and you construct an expression using
+such a class, then trying to use the ``Basic.series()`` method will raise an
+exception of not finding the ``fdiff()`` method in your class.  This "duck
+typing" has an advantage that you just implement the functionality which you
+need.
+
+You can define the ``cos`` class like this::
+
+    class cos(Function):
+        pass
+
+and use it like ``1+cos(x)``, but if you don't implement the ``fdiff()`` method,
+you will not be able to call ``(1+cos(x)).series()``.
+
+The symbolic object is characterized (defined) by the things which it can do,
+so implementing more methods like ``fdiff()``, ``subs()`` etc., you are creating a
+"shape" of the symbolic object. Useful things to implement in new classes are:
+``hash()`` (to use the class in comparisons), ``fdiff()`` (to use it in series
+expansion), ``subs()`` (to use it in expressions, where some parts are being
+substituted) and ``series()`` (if the series cannot be computed using the general
+``Basic.series()`` method). When you create a new class, don't worry about this
+too much - just try to use it in your code and you will realize immediately
+which methods need to be implemented in each situation.
+
+All objects in sympy are immutable - in the sense that any operation just
+returns a new instance (it can return the same instance only if it didn't
+change). This is a common mistake to change the current instance, like
+``self.arg=self.arg +1`` (wrong!). Use ``arg=self.arg + 1; return arg`` instead.
+The object is immutable in the
+sense of the symbolic expression it represents. It can modify itself to keep
+track of, for example, its hash. Or it can recalculate anything regarding the
+expression it contains. But the expression cannot be changed. So you can pass
+any instance to other objects, because you don't have to worry that it will
+change, or that this would break anything.
+
+Conclusion
+----------
+
+Above are the main ideas behind SymPy that we try to obey. The rest
+depends on the current implementation and may possibly change in the future.
+The point of all of this is that the interdependencies inside SymPy should be
+kept to a minimum. If one wants to add new functionality to SymPy, all that is
+necessary is to create a subclass of ``Basic`` and implement what you want.
+
+Functions
+---------
+
+How to create a new function with one variable::
+
+    class sign(Function):
+
+        nargs = 1
+
+        @classmethod
+        def eval(cls, arg):
+            if isinstance(arg, Basic.NaN):
+                return S.NaN
+            if isinstance(arg, Basic.Zero):
+                return S.Zero
+            if arg.is_positive:
+                return S.One
+            if arg.is_negative:
+                return S.NegativeOne
+            if isinstance(arg, Basic.Mul):
+                coeff, terms = arg.as_coeff_terms()
+                if not isinstance(coeff, Basic.One):
+                    return cls(coeff) * cls(Basic.Mul(*terms))
+
+        is_bounded = True
+
+        def _eval_conjugate(self):
+            return self
+
+        def _eval_is_zero(self):
+            return isinstance(self[0], Basic.Zero)
+
+and that's it. The ``_eval_*`` functions are called when something is needed.
+The ``eval`` is called when the class is about to be instantiated and it
+should return either some simplified instance of some other class or if the
+class should be unmodified, return ``None`` (see ``core/function.py`` in
+``Function.__new__`` for implementation details). See also tests in
+`sympy/functions/elementary/tests/test_interface.py
+<https://github.com/sympy/sympy/blob/master/sympy/functions/elementary/tests/test_interface.py>`_ that test this interface. You can use them to create your own new functions.
+
+The applied function ``sign(x)`` is constructed using
+::
+
+    sign(x)
+
+both inside and outside of SymPy. Unapplied functions ``sign`` is just the class itself::
+
+    sign
+
+both inside and outside of SymPy. This is the current structure of classes in SymPy::
+
+    class BasicType(type):
+        pass
+    class MetaBasicMeths(BasicType):
+        ...
+    class BasicMeths(AssumeMeths):
+        __metaclass__ = MetaBasicMeths
+        ...
+    class Basic(BasicMeths):
+        ...
+    class FunctionClass(MetaBasicMeths):
+        ...
+    class Function(Basic, RelMeths, ArithMeths):
+        __metaclass__ = FunctionClass
+        ...
+
+The exact names of the classes and the names of the methods and how they work can be
+changed in the future.
+
+This is how to create a function with two variables::
+
+    class chebyshevt_root(Function):
+        nargs = 2
+
+        @classmethod
+        def eval(cls, n, k):
+            if not 0 <= k < n:
+                raise ValueError("must have 0 <= k < n")
+            return C.cos(S.Pi*(2*k+1)/(2*n))
+
+
+.. note:: the first argument of a @classmethod should be ``cls`` (i.e. not ``self``).
+
+Here it's how to define a derivative of the function::
+
+    >>> from sympy import Function, sympify, cos
+    >>> class my_function(Function):
+    ...     nargs = 1
+    ...
+    ...     def fdiff(self, argindex = 1):
+    ...         return cos(self.args[0])
+    ...
+    ...     @classmethod
+    ...     def eval(cls, arg):
+    ...         arg = sympify(arg)
+    ...         if arg == 0:
+    ...             return sympify(0)
+
+So guess what this ``my_function`` is going to be? Well, it's derivative is
+``cos`` and the function value at 0 is 0, but let's pretend we don't know::
+
+    >>> from sympy import pprint
+    >>> pprint(my_function(x).series(x, 0, 10))
+         3     5     7       9
+        x     x     x       x       / 10\
+    x - -- + --- - ---- + ------ + O\x  /
+        6    120   5040   362880
+
+Looks familiar indeed::
+
+    >>> from sympy import sin
+    >>> pprint(sin(x).series(x, 0, 10))
+         3     5     7       9
+        x     x     x       x       / 10\
+    x - -- + --- - ---- + ------ + O\x  /
+        6    120   5040   362880
+
+Let's try a more complicated example. Let's define the derivative in terms of the
+function itself::
+
+    >>> class what_am_i(Function):
+    ...     nargs = 1
+    ...
+    ...     def fdiff(self, argindex = 1):
+    ...         return 1-what_am_i(self.args[0])**2
+    ...
+    ...     @classmethod
+    ...     def eval(cls, arg):
+    ...         arg = sympify(arg)
+    ...         if arg == 0:
+    ...             return sympify(0)
+
+So what is ``what_am_i``?  Let's try it::
+
+    >>> pprint(what_am_i(x).series(x, 0, 10))
+         3      5       7       9
+        x    2*x    17*x    62*x     / 10\
+    x - -- + ---- - ----- + ----- + O\x  /
+        3     15     315     2835
+
+Well, it's ``tanh``::
+
+    >>> from sympy import tanh
+    >>> pprint(tanh(x).series(x, 0, 10))
+         3      5       7       9
+        x    2*x    17*x    62*x     / 10\
+    x - -- + ---- - ----- + ----- + O\x  /
+        3     15     315     2835
+
+The new functions we just defined are regular SymPy objects, you
+can use them all over SymPy, e.g.::
+
+    >>> from sympy import limit
+    >>> limit(what_am_i(x)/x, x, 0)
+    1
+
+
+common tasks
+------------
+
+Please use the same way as is shown below all across SymPy.
+
+**accessing parameters**::
+
+    >>> from sympy import sign, sin
+    >>> from sympy.abc import x, y, z
+
+    >>> e = sign(x**2)
+    >>> e.args
+    (x**2,)
+
+    >>> e.args[0]
+    x**2
+
+    >>> (x+y*z).args
+    (y*z, x)
+
+    >>> (x+y*z).args[0]
+    y*z
+
+    >>> (x+y*z).args[1]
+    x
+
+    >>> (y*z).args
+    (y, z)
+
+    >>> sin(y*z).args
+    (y*z,)
+
+Never use internal methods or variables, prefixed with "``_``" (example: don't
+use ``_args``, use ``.args`` instead).
+
+**testing the structure of a SymPy expression**
+
+Applied functions::
+
+    >>> from sympy import sign, exp, Function
+    >>> e = sign(x**2)
+
+    >>> isinstance(e, sign)
+    True
+
+    >>> isinstance(e, exp)
+    False
+
+    >>> isinstance(e, Function)
+    True
+
+So ``e`` is a ``sign(z)`` function, but not ``exp(z)`` function.
+
+Unapplied functions::
+
+    >>> from sympy import sign, exp, FunctionClass
+    >>> e = sign
+
+    >>> f = exp
+
+    >>> g = Add
+
+    >>> isinstance(e, FunctionClass)
+    True
+
+    >>> isinstance(f, FunctionClass)
+    True
+
+    >>> isinstance(g, FunctionClass)
+    False
+
+    >>> g is Add
+    True
+
+So ``e`` and ``f`` are functions, ``g`` is not a function.
+
+Contributing
+============
+
+We welcome every SymPy user to participate in it's development. Don't worry if
+you've never contributed to any open source project, we'll help you learn
+anything necessary, just ask on our mailinglist_.
+
+Don't be afraid to ask anything and don't worry that you are wasting our time
+if you are new to SymPy and ask questions that maybe most of the people know
+the answer to -- you are not, because that's exactly what the mailinglist_ is
+for and people answer your emails because they want to. Also we try hard to
+answer every email, so you'll always get some feedback and pointers what to do
+next.
+
+Improving the code
+------------------
+
+Go to issues_ that are sorted by priority and simply find something that you
+would like to get fixed and fix it. If you find something odd, please report it
+into issues_ first before fixing it. Feel free to consult with us on the
+mailinglist_.  Then send your patch either to the issues_ or the mailinglist_. See
+the SympyDevelopment_ wiki, but don't worry about it too much if you find it
+too formal - simply get in touch with us on the mailinglist_ and we'll help you
+get your patch accepted.
+
+.. _issues:             http://code.google.com/p/sympy/issues/list
+.. _mailinglist:        http://groups.google.com/group/sympy
+.. _SympyDevelopment:   http://code.google.com/p/sympy/wiki/SympyDevelopment
+
+Please read our excellent `SymPy Patches Tutorial
+<https://github.com/sympy/sympy/wiki/Development-workflow>`_ at our
+wiki for a guide on how to write patches to SymPy, how to work with Git,
+and how to make your life easier as you get started with SymPy.
+
+
+Improving the docs
+------------------
+
+Please see :ref:`the documentation <module-docs>` how to fix and improve
+SymPy's documentation. All contribution is very welcome.
+
diff --git a/lib/sympy/doc/src/index.txt b/lib/sympy/doc/src/index.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/index.txt
@@ -0,0 +1,34 @@
+.. SymPy documentation master file, created by sphinx-quickstart.py on Sat Mar 22 19:34:32 2008.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to SymPy's documentation!
+=================================
+
+`SymPy <http://sympy.org>`_ is a Python library for symbolic mathematics.
+If you are new to SymPy, start with the Tutorial.
+
+This is the central page for all of SymPy's documentation.
+
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   install.txt
+   tutorial.txt
+   gotchas.txt
+   guide.txt
+   modules/index.txt
+   python-comparisons.txt
+   wiki.txt
+   outreach.txt
+   aboutus.txt
+
+If something cannot be easily accessed from this page, it's a bug (`please
+report it`_).
+
+This documentation is maintained with docutils, so you might see some comments in the form #doctest:... . You can safely ignore them.
+
+.. _please report it: http://code.google.com/p/sympy/issues/list
diff --git a/lib/sympy/doc/src/install.txt b/lib/sympy/doc/src/install.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/install.txt
@@ -0,0 +1,9 @@
+Installation
+------------
+
+Go to the `Downloads`_ tab on SymPy's webpage for thourough instructions.
+
+You'll find there detailed explanation how to install SymPy using source,
+Git repository, Debian, Ubuntu, Gentoo, Windows and Sage.
+
+.. _Downloads: http://code.google.com/p/sympy/wiki/DownloadInstallation?tm=2
diff --git a/lib/sympy/doc/src/modules/assumptions.txt b/lib/sympy/doc/src/modules/assumptions.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/assumptions.txt
@@ -0,0 +1,388 @@
+Assumptions module
+******************
+
+.. module:: sympy.assumptions
+
+Queries are used to ask information about expressions. Main method for this
+is ask():
+
+.. automethod:: sympy.assumptions.ask
+
+Querying
+========
+
+ask's optional second argument should be a boolean expression involving
+assumptions about objects in expr. Valid values include:
+
+    * Q.integer(x)
+    * Q.positive(x)
+    * Q.integer(x) & Q.positive(x)
+    * etc.
+
+Q is a class in sympy.assumptions holding known predicates.
+
+See documentation for the logic module for a complete list of valid boolean
+expressions.
+
+You can also define global assumptions so you don't have to pass that argument
+each time to function ask(). This is done by using the global_assumptions
+object from module sympy.assumptions. You can then clear global assumptions
+with global_assumptions.clear()::
+
+     >>> from sympy import *
+     >>> x = Symbol('x')
+     >>> global_assumptions.add(Q.positive(x))
+     >>> ask(Q.positive(x))
+     True
+     >>> global_assumptions.clear()
+
+
+Supported predicates
+====================
+
+bounded
+-------
+
+Test that a function is bounded with respect to its variables. For example,
+sin(x) is a bounded functions, but exp(x) is not.
+
+Examples::
+
+    >>> from sympy import *
+    >>> x = Symbol('x')
+    >>> ask(Q.bounded(exp(x)), ~Q.bounded(x))
+    False
+    >>> ask(Q.bounded(exp(x)) , Q.bounded(x))
+    True
+    >>> ask(Q.bounded(sin(x)), ~Q.bounded(x))
+    True
+
+
+commutative
+-----------
+
+Test that objects are commutative. By default, symbols in SymPy are considered
+commutative except otherwise stated.
+
+Examples::
+
+    >>> from sympy import *
+    >>> x, y = symbols('x,y')
+    >>> ask(Q.commutative(x))
+    True
+    >>> ask(Q.commutative(x), ~Q.commutative(x))
+    False
+    >>> ask(Q.commutative(x*y), ~Q.commutative(x))
+    False
+
+
+complex
+-------
+
+Test that expression belongs to the field of complex numbers.
+
+Examples::
+
+    >>> from sympy import *
+    >>> ask(Q.complex(2))
+    True
+    >>> ask(Q.complex(I))
+    True
+    >>> x, y = symbols('x,y')
+    >>> ask(Q.complex(x+I*y), Q.real(x) & Q.real(y))
+    True
+
+
+even
+----
+
+Test that expression represents an even number, that is, an number that
+can be written in the form 2*n, n integer.
+
+Examples::
+
+    >>> from sympy import *
+    >>> ask(Q.even(2))
+    True
+    >>> n = Symbol('n')
+    >>> ask(Q.even(2*n), Q.integer(n))
+    True
+
+
+extended_real
+-------------
+
+Test that an expression belongs to the field of extended real numbers, that is, real
+numbers union {Infinity, -Infinity}.
+
+Examples::
+
+    >>> from sympy import *
+    >>> ask(Q.extended_real(oo))
+    True
+    >>> ask(Q.extended_real(2))
+    True
+    >>> ask(Q.extended_real(x), Q.real(x))
+    True
+
+
+imaginary
+---------
+
+Test that an expression belongs to the set of imaginary numbers, that is,
+ it can be written as x*I, where x is real and I is the imaginary unit.
+
+Examples::
+
+    >>> from sympy import *
+    >>> ask(Q.imaginary(2*I))
+    True
+    >>> x = Symbol('x')
+    >>> ask(Q.imaginary(x*I), Q.real(x))
+    True
+
+
+infinitesimal
+-------------
+
+Test that an expression is equivalent to an infinitesimal number.
+
+Examples::
+
+    >>> from sympy import *
+    >>> ask(Q.infinitesimal(1/oo))
+    True
+    >>> x, y = symbols('x,y')
+    >>> ask(Q.infinitesimal(2*x), Q.infinitesimal(x))
+    True
+    >>> ask(Q.infinitesimal(x*y), Q.infinitesimal(x) & Q.bounded(y))
+    True
+
+
+integer
+-------
+
+Test that an expression belongs to the set of integer numbers.
+
+Examples::
+
+    >>> from sympy import *
+    >>> ask(Q.integer(2))
+    True
+    >>> ask(Q.integer(sqrt(2)))
+    False
+    >>> x = Symbol('x')
+    >>> ask(Q.integer(x/2), Q.even(x))
+    True
+
+
+irrational
+----------
+
+Test that an expression represents an irrational number.
+
+Examples::
+
+     >>> from sympy import *
+     >>> ask(Q.irrational(pi))
+     True
+     >>> ask(Q.irrational(sqrt(2)))
+     True
+     >>> ask(Q.irrational(x*sqrt(2)), Q.rational(x))
+     True
+
+
+rational
+--------
+
+Test that an expression represents a rational number.
+
+Examples::
+
+     >>> from sympy import *
+     >>> ask(Q.rational(Rational(3, 4)))
+     True
+     >>> x, y = symbols('x,y')
+     >>> ask(Q.rational(x/2), Q.integer(x))
+     True
+     >>> ask(Q.rational(x/y), Q.integer(x) & Q.integer(y))
+     True
+
+
+negative
+--------
+
+Test that an expression is less (strict) than zero.
+
+Examples::
+
+     >>> from sympy import *
+     >>> ask(Q.negative(0.3))
+     False
+     >>> x = Symbol('x')
+     >>> ask(Q.negative(-x), Q.positive(x))
+     True
+
+Remarks
+^^^^^^^
+negative numbers are defined as real numbers that are not zero nor positive, so
+complex numbers (with nontrivial imaginary coefficients) will return False
+for this predicate. The same applies to Q.positive.
+
+
+positive
+--------
+
+Test that a given expression is greater (strict) than zero.
+
+Examples::
+
+     >>> from sympy import *
+     >>> ask(Q.positive(0.3))
+     True
+     >>> x = Symbol('x')
+     >>> ask(Q.positive(-x), Q.negative(x))
+     True
+
+Remarks
+^^^^^^^
+see Remarks for negative
+
+
+prime
+-----
+
+Test that an expression represents a prime number.
+
+Examples::
+
+    >>> from sympy import *
+    >>> ask(Q.prime(13))
+    True
+
+Remarks: Use sympy.ntheory.isprime to test numeric values efficiently.
+
+
+real
+----
+
+Test that an expression belongs to the field of real numbers.
+
+Examples::
+
+    >>> from sympy import *
+    >>> ask(Q.real(sqrt(2)))
+    True
+    >>> x, y = symbols('x,y')
+    >>> ask(Q.real(x*y), Q.real(x) & Q.real(y))
+    True
+
+
+odd
+---
+
+Test that an expression represents an odd number.
+
+Examples::
+
+    >>> from sympy import *
+    >>> ask(Q.odd(3))
+    True
+    >>> n = Symbol('n')
+    >>> ask(Q.odd(2*n + 1), Q.integer(n))
+    True
+
+
+nonzero
+-------
+
+Test that an expression is not zero.
+
+Examples::
+
+     >>> from sympy import *
+     >>> x = Symbol('x')
+     >>> ask(Q.nonzero(x), Q.positive(x) | Q.negative(x))
+     True
+
+
+Design
+======
+
+Each time ask is called, the appropriate Handler for the current key is called. This is
+always a subclass of sympy.assumptions.AskHandler. It's classmethods have the name's of the classes
+it supports. For example, a (simplified) AskHandler for the ask 'positive' would
+look like this::
+
+    class AskPositiveHandler(CommonHandler):
+
+        def Mul(self):
+            # return True if all argument's in self.expr.args are positive
+            ...
+
+        def Add(self):
+            for arg in self.expr.args:
+                if not ask(arg, positive, self.assumptions):
+                    break
+            else:
+                # if all argument's are positive
+                return True
+        ...
+
+The .Mul() method is called when self.expr is an instance of Mul, the Add method
+would be called when self.expr is an instance of Add and so on.
+
+
+Extensibility
+=============
+
+You can define new queries or support new types by subclassing sympy.assumptions.AskHandler
+ and registering that handler for a particular key by calling register_handler:
+
+.. automethod:: sympy.assumptions.register_handler
+
+You can undo this operation by calling remove_handler.
+
+.. automethod:: sympy.assumptions.remove_handler
+
+You can support new types [1]_ by adding a handler to an existing key. In the
+following example, we will create a new type MyType and extend the key 'prime'
+to accept this type (and return True)
+
+.. parsed-literal::
+
+    >>> from sympy.core import Basic
+    >>> from sympy.assumptions import register_handler
+    >>> from sympy.assumptions.handlers import AskHandler
+    >>> class MyType(Basic):
+    ...     pass
+    >>> class MyAskHandler(AskHandler):
+    ...     @staticmethod
+    ...     def MyType(expr, assumptions):
+    ...         return True
+    >>> a = MyType()
+    >>> register_handler('prime', MyAskHandler)
+    >>> ask(Q.prime(a))
+    True
+
+
+Performance improvements
+========================
+
+On queries that involve symbolic coefficients, logical inference is used. Work on
+improving satisfiable function (sympy.logic.inference.satisfiable) should result
+in notable speed improvements.
+
+Logic inference used in one ask could be used to speed up further queries, and
+current system does not take advantage of this. For example, a truth maintenance
+system (http://en.wikipedia.org/wiki/Truth_maintenance_system) could be implemented.
+
+Misc
+====
+
+You can find more examples in the in the form of test under directory
+sympy/assumptions/tests/
+
+.. [1] New type must inherit from Basic, otherwise an exception will be raised.
+   This is a bug and should be fixed.
+
diff --git a/lib/sympy/doc/src/modules/concrete.txt b/lib/sympy/doc/src/modules/concrete.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/concrete.txt
@@ -0,0 +1,80 @@
+Concrete Mathematics
+====================
+
+Hypergeometric terms
+--------------------
+
+The center stage, in recurrence solving and summations, play hypergeometric
+terms. Formally these are sequences annihilated by first order linear
+recurrence operators. In simple words if we are given term `a(n)` then it is
+hypergeometric if its consecutive term ratio is a rational function in `n`.
+
+To check if a sequence is of this type you can use the ``is_hypergeometric`` method
+which is  available in Basic class. Here is simple example involving a
+polynomial:
+
+    >>> from sympy import *
+    >>> n, k = symbols('n,k')
+    >>> (n**2 + 1).is_hypergeometric(n)
+    True
+
+Of course polynomials are hypergeometric but are there any more complicated
+sequences of this type? Here are some trivial examples:
+
+    >>> factorial(n).is_hypergeometric(n)
+    True
+    >>> binomial(n, k).is_hypergeometric(n)
+    True
+    >>> rf(n, k).is_hypergeometric(n)
+    True
+    >>> ff(n, k).is_hypergeometric(n)
+    True
+    >>> gamma(n).is_hypergeometric(n)
+    True
+    >>> (2**n).is_hypergeometric(n)
+    True
+
+We see that all species used in summations and other parts of concrete
+mathematics are hypergeometric. Note also that binomial coefficients and both
+rising and falling factorials are hypergeometric in both their arguments:
+
+    >>> binomial(n, k).is_hypergeometric(k)
+    True
+    >>> rf(n, k).is_hypergeometric(k)
+    True
+    >>> ff(n, k).is_hypergeometric(k)
+    True
+
+To say more, all previously shown examples are valid for integer linear
+arguments:
+
+    >>> factorial(2*n).is_hypergeometric(n)
+    True
+    >>> binomial(3*n+1, k).is_hypergeometric(n)
+    True
+    >>> rf(n+1, k-1).is_hypergeometric(n)
+    True
+    >>> ff(n-1, k+1).is_hypergeometric(n)
+    True
+    >>> gamma(5*n).is_hypergeometric(n)
+    True
+    >>> (2**(n-7)).is_hypergeometric(n)
+    True
+
+However nonlinear arguments make those sequences fail to be hypergeometric:
+
+    >>> factorial(n**2).is_hypergeometric(n)
+    False
+    >>> (2**(n**3 + 1)).is_hypergeometric(n)
+    False
+
+If not only the knowledge of being hypergeometric or not is needed, you can use
+``hypersimp()`` function. It will try to simplify combinatorial expression and
+if the term given is hypergeometric it will return a quotient of polynomials of
+minimal degree. Otherwise is will return `None` to say that sequence is not
+hypergeometric:
+
+    >>> hypersimp(factorial(2*n), n)
+    4*n**2 + 6*n + 2
+    >>> hypersimp(factorial(n**2), n)
+
diff --git a/lib/sympy/doc/src/modules/core.txt b/lib/sympy/doc/src/modules/core.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/core.txt
@@ -0,0 +1,351 @@
+SymPy Core
+==========
+
+sympify
+-------
+.. module:: sympy.core.sympify
+.. autofunction:: sympify
+
+cacheit
+-------
+.. module:: sympy.core.cache
+.. autofunction:: cacheit
+
+.. module:: sympy.core.basic
+
+Basic
+-----
+.. autoclass:: Basic
+   :members:
+
+Atom
+----
+.. autoclass:: Atom
+   :members:
+
+C
+-
+.. autoclass:: C
+   :members:
+
+S
+-
+.. module:: sympy.core.singleton
+.. autoclass:: S
+   :members:
+
+.. module:: sympy.core.expr
+
+Expr
+----
+.. autoclass:: Expr
+   :members:
+
+AtomicExpr
+----------
+.. autoclass:: AtomicExpr
+   :members:
+
+.. module:: sympy.core.symbol
+
+Symbol
+------
+.. autoclass:: Symbol
+   :members:
+
+Wild
+----
+.. autoclass:: Wild
+   :members:
+
+Dummy
+-----
+.. autoclass:: Dummy
+   :members:
+
+symbols
+-------
+.. autofunction:: symbols
+
+var
+---
+.. autofunction:: var
+
+.. module:: sympy.core.numbers
+
+Number
+------
+.. autoclass:: Number
+   :members:
+
+Float
+-----
+.. autoclass:: Float
+   :members:
+
+Rational
+--------
+.. autoclass:: Rational
+   :members:
+
+Integer
+-------
+.. autoclass:: Integer
+   :members:
+
+NumberSymbol
+------------
+.. autoclass:: NumberSymbol
+   :members:
+
+RealNumber
+----------
+.. autoclass:: RealNumber
+   :members:
+
+Real
+----
+.. autoclass:: Real
+   :members:
+
+igcd
+----
+.. autofunction:: igcd
+
+ilcm
+----
+.. autofunction:: ilcm
+
+seterr
+------
+.. autofunction:: seterr
+
+E
+-
+.. autoclass:: E
+   :members:
+
+I
+-
+.. autoclass:: I
+   :members:
+
+nan
+---
+.. autofunction:: nan
+
+oo
+--
+.. autofunction:: oo
+
+pi
+--
+.. autofunction:: pi
+
+zoo
+---
+.. autofunction:: zoo
+
+.. module:: sympy.core.power
+
+Pow
+---
+.. autoclass:: Pow
+   :members:
+
+integer_nthroot
+---------------
+.. autofunction:: integer_nthroot
+
+Mul
+---
+.. module:: sympy.core.mul
+.. autoclass:: Mul
+   :members:
+
+Add
+---
+.. module:: sympy.core.add
+.. autoclass:: Add
+   :members:
+
+.. module:: sympy.core.relational
+
+Rel
+---
+.. autoclass:: Rel
+   :members:
+
+Eq
+--
+.. autoclass:: Eq
+   :members:
+
+Ne
+--
+.. autoclass:: Ne
+   :members:
+
+Lt
+--
+.. autoclass:: Lt
+   :members:
+
+Le
+--
+.. autoclass:: Le
+   :members:
+
+Gt
+--
+.. autoclass:: Gt
+   :members:
+
+Ge
+--
+.. autoclass:: Ge
+   :members:
+
+Equality
+--------
+.. autoclass:: Equality
+   :members:
+
+Inequality
+----------
+.. autoclass:: Inequality
+   :members:
+
+Unequality
+----------
+.. autoclass:: Unequality
+   :members:
+
+StrictInequality
+----------------
+.. autoclass:: StrictInequality
+   :members:
+
+vectorize
+---------
+.. module:: sympy.core.multidimensional
+.. autoclass:: vectorize
+   :members:
+
+.. module:: sympy.core.function
+
+Lambda
+------
+.. autoclass:: Lambda
+   :members:
+
+WildFunction
+------------
+.. autoclass:: WildFunction
+   :members:
+
+Derivative
+----------
+.. autoclass:: Derivative
+   :members:
+
+diff
+----
+.. autofunction:: diff
+
+FunctionClass
+-------------
+.. autoclass:: FunctionClass
+   :members:
+
+Function
+--------
+.. autoclass:: Function
+   :members:
+
+Subs
+----
+.. autoclass:: Subs
+   :members:
+
+expand
+------
+.. autofunction:: expand
+
+PoleError
+---------
+.. autoclass:: PoleError
+   :members:
+
+count_ops
+---------
+.. autofunction:: count_ops
+
+expand_mul
+----------
+.. autofunction:: expand_mul
+
+expand_log
+----------
+.. autofunction:: expand_log
+
+expand_func
+-----------
+.. autofunction:: expand_func
+
+expand_trig
+-----------
+.. autofunction:: expand_trig
+
+expand_complex
+--------------
+.. autofunction:: expand_complex
+
+expand_multinomial
+------------------
+.. autofunction:: expand_multinomial
+
+.. module:: sympy.core.sets
+
+Set
+---
+.. autoclass:: Set
+   :members:
+
+Interval
+--------
+.. autoclass:: Interval
+   :members:
+
+Union
+-----
+.. autoclass:: Union
+   :members:
+
+EmptySet
+--------
+.. autoclass:: EmptySet
+   :members:
+
+.. module:: sympy.core.evalf
+
+PrecisionExhausted
+------------------
+.. autoclass:: PrecisionExhausted
+   :members:
+
+N
+-
+.. autoclass:: N
+   :members:
+
+Tuple
+-----
+.. module:: sympy.core.containers
+.. autoclass:: Tuple
+   :members:
+
+gcd_terms
+---------
+.. module:: sympy.core.exprtools
+.. autofunction:: gcd_terms
diff --git a/lib/sympy/doc/src/modules/evalf.txt b/lib/sympy/doc/src/modules/evalf.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/evalf.txt
@@ -0,0 +1,397 @@
+.. _evalf-label:
+
+Numerical evaluation
+====================
+
+Basics
+------
+
+Exact SymPy expressions can be converted to floating-point approximations
+(decimal numbers) using either the ``.evalf()`` method or the ``N()`` function.
+``N(expr, <args>)`` is equivalent to ``sympify(expr).evalf(<args>)``.
+
+    >>> from sympy import *
+    >>> N(sqrt(2)*pi)
+    4.44288293815837
+    >>> (sqrt(2)*pi).evalf()
+    4.44288293815837
+
+
+By default, numerical evaluation is performed to an accuracy of 15 decimal
+digits. You can optionally pass a desired accuracy (which should be a positive
+integer) as an argument to ``evalf`` or ``N``:
+
+    >>> N(sqrt(2)*pi, 5)
+    4.4429
+    >>> N(sqrt(2)*pi, 50)
+    4.4428829381583662470158809900606936986146216893757
+
+
+Complex numbers are supported:
+
+    >>> N(1/(pi + I), 20)
+    0.28902548222223624241 - 0.091999668350375232456*I
+
+
+If the expression contains symbols or for some other reason cannot be evaluated
+numerically, calling ``.evalf()`` or ``N()`` returns the original expression, or
+ in some cases a partially evaluated expression. For example, when the
+ expression is a polynomial in expanded form, the coefficients are evaluated:
+
+    >>> x = Symbol('x')
+    >>> (pi*x**2 + x/3).evalf()
+    3.14159265358979*x**2 + 0.333333333333333*x
+
+
+You can also use the standard Python functions ``float()``, ``complex()`` to
+convert SymPy expressions to regular Python numbers:
+
+    >>> float(pi) #doctest: +SKIP
+    3.1415926535...
+    >>> complex(pi+E*I) #doctest: +SKIP
+    (3.1415926535...+2.7182818284...j)
+
+
+If these functions are used, failure to evaluate the expression to an explicit
+number (for example if the expression contains symbols) will raise an exception.
+
+There is essentially no upper precision limit. The following command, for
+example, computes the first 100,000 digits of &#960;/e:
+
+    >>> N(pi/E, 100000) #doctest: +SKIP
+    ...
+
+
+This shows digits 999,951 through 1,000,000 of pi:
+
+    >>> str(N(pi, 10**6))[-50:] #doctest: +SKIP
+    '95678796130331164628399634646042209010610577945815'
+
+
+High-precision calculations can be slow. It is recommended (but entirely
+optional) to install gmpy (http://code.google.com/p/gmpy/), which will
+significantly speed up computations such as the one above.
+
+Floating-point numbers
+----------------------
+
+Floating-point numbers in SymPy are instances of the class ``Float``. A ``Float``
+can be created with a custom precision as second argument:
+
+    >>> Float(0.1)
+    0.100000000000000
+    >>> Float(0.1, 10)
+    0.1000000000
+    >>> Float(0.1, 30)
+    0.100000000000000005551115123126
+
+
+As the last example shows, Python floats are only accurate to about 15 digits as
+inputs. To create a ``Float`` from a high-precision decimal number, it is better
+to pass a string or ``evalf`` a ``Rational``:
+
+    >>> Float('0.1', 30)
+    0.100000000000000000000000000000
+    >>> Rational(1,10).evalf(30)
+    0.100000000000000000000000000000
+
+
+The precision of a number determines 1) the precision to use when performing
+arithmetic with the number, and 2) the number of digits to display when printing
+the number. When two numbers with different precision are used together in an
+arithmetic operation, the higher of the precisions is used for the result. Note
+that precision therefore cannot be used as a model of error propagation or
+significance arithmetic; rather, this scheme is designed to ensure stability of
+numerical algorithms.
+
+``N`` and ``evalf`` can be used to change the precision of existing
+floating-point numbers:
+
+    >>> N(3.5)
+    3.50000000000000
+    >>> N(3.5, 5)
+    3.5000
+    >>> N(3.5, 30)
+    3.50000000000000000000000000000
+
+
+Accuracy and error handling
+---------------------------
+
+When the input to ``N`` or ``evalf`` is a complicated expression, numerical
+error propagation becomes a concern. As an example, consider the 100'th
+Fibonacci number and the excellent (but not exact) approximation &#966;^100 / &#8730;5
+where &#966; is the golden ratio. With ordinary floating-point arithmetic,
+subtracting these numbers from each other erroneously results in a complete
+cancellation:
+
+    >>> float(GoldenRatio**1000/sqrt(5)) #doctest: +SKIP
+    4.34665576869...e+208
+    >>> float(fibonacci(1000)) #doctest: +SKIP
+    4.34665576869...e+208
+    >>> float(fibonacci(1000)) - float(GoldenRatio**1000/sqrt(5))
+    0.0
+
+
+``N`` and ``evalf`` keep track of errors and automatically increase the
+precision used internally in order to obtain a correct result:
+
+    >>> N(fibonacci(100) - GoldenRatio**100/sqrt(5))
+    -5.64613129282185e-22
+
+
+Unfortunately, numerical evaluation cannot tell an expression that is exactly
+zero apart from one that is merely very small. The working precision is
+therefore capped, by default to around 100 digits. If we try with the 1000'th
+Fibonacci number, the following happens:
+
+    >>> N(fibonacci(1000) - (GoldenRatio)**1000/sqrt(5))
+    -.0e+84
+
+
+The lack of digits in the returned number indicates that ``N`` failed to achieve
+full accuracy. The result indicates that the magnitude of the expression is something less than 10^84, but that is not a particularly good answer. To force a higher working precision, the ``maxn`` keyword argument can be used:
+
+    >>> N(fibonacci(1000) - (GoldenRatio)**1000/sqrt(5), maxn=500)
+    -4.60123853010113e-210
+
+
+Normally, ``maxn`` can be set very high (thousands of digits), but be aware that
+this may cause significant slowdown in extreme cases. Alternatively, the
+``strict=True`` option can be set to force an exception instead of silently
+returning a value with less than the requested accuracy:
+
+    >>> N(fibonacci(1000) - (GoldenRatio)**1000/sqrt(5), strict=True)
+    Traceback (most recent call last):
+    ...
+    PrecisionExhausted: Failed to distinguish the expression:
+    <BLANKLINE>
+    -sqrt(5)*GoldenRatio**1000/5 + 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
+    <BLANKLINE>
+    from zero. Try simplifying the input, using chop=True, or providing a higher maxn for evalf
+
+
+If we add a term so that the Fibonacci approximation becomes exact (the full
+form of Binet's formula), we get an expression that is exactly zero, but ``N``
+does not know this:
+
+    >>> f = fibonacci(100) - (GoldenRatio**100 - (GoldenRatio-1)**100)/sqrt(5)
+    >>> N(f)
+    .0e-113
+    >>> N(f, maxn=1000)
+    .0e-1345
+
+
+In situations where such cancellations are known to occur, the ``chop`` options
+is useful. This basically replaces very small numbers with exact zeros:
+
+    >>> N(f, chop=True)
+    0
+
+
+The ``chop`` option is very useful for cleaning up small real or imaginary parts:
+
+    >>> N((E+pi*I)*(E-pi*I))
+    17.25866050002 - 1.30104260698261e-17*I
+    >>> N((E+pi*I)*(E-pi*I), chop=True)
+    17.2586605000200
+
+
+Sums and integrals
+------------------
+
+Sums (in particular infinite series) and integrals can be used like regular
+closed-form expressions, and support arbitrary-precision evaluation:
+
+    >>> var('n x')
+    (n, x)
+    >>> Sum(1/n**n, (n, 1, oo)).evalf()
+    1.29128599706266
+    >>> Integral(x**(-x), (x, 0, 1)).evalf()
+    1.29128599706266
+    >>> Sum(1/n**n, (n, 1, oo)).evalf(50)
+    1.2912859970626635404072825905956005414986193682745
+    >>> Integral(x**(-x), (x, 0, 1)).evalf(50)
+    1.2912859970626635404072825905956005414986193682745
+    >>> (Integral(exp(-x**2), (x, -oo, oo)) ** 2).evalf(30)
+    3.14159265358979323846264338328
+
+
+By default, the tanh-sinh quadrature algorithm is used to evaluate integrals.
+This algorithm is very efficient and robust for smooth integrands (and even
+integrals with endpoint singularities), but may struggle with integrals that
+are highly oscillatory or have mid-interval discontinuities. In many cases,
+``evalf``/``N`` will correctly estimate the error. With the following integral,
+the result is accurate but only good to four digits:
+
+    >>> f = abs(sin(x))
+    >>> Integral(abs(sin(x)), (x, 0, 4)).evalf()
+    2.346
+
+
+It is better to split this integral into two pieces:
+
+    >>> (Integral(f, (x, 0, pi)) + Integral(f, (x, pi, 4))).evalf()
+    2.34635637913639
+
+
+A similar example is the following oscillatory integral:
+
+
+    >>> Integral(sin(x)/x**2, (x, 1, oo)).evalf(maxn=20)
+    0.5
+
+
+It can be dealt with much more efficiently by telling ``evalf`` or ``N`` to
+use an oscillatory quadrature algorithm:
+
+    >>> Integral(sin(x)/x**2, (x, 1, oo)).evalf(quad='osc')
+    0.504067061906928
+    >>> Integral(sin(x)/x**2, (x, 1, oo)).evalf(20, quad='osc')
+    0.50406706190692837199
+
+
+Oscillatory quadrature requires an integrand containing a factor cos(ax+b) or
+sin(ax+b). Note that many other oscillatory integrals can be transformed to
+this form with a change of variables:
+
+    >>> init_printing(use_unicode=False, wrap_line=False, no_global=True)
+    >>> intgrl = Integral(sin(1/x), (x, 0, 1)).transform(x, 1/x)
+    >>> intgrl
+     oo
+      /
+     |
+     |  sin(x)
+     |  ------ dx
+     |     2
+     |    x
+     |
+    /
+    1
+    >>> N(intgrl, quad='osc')
+    0.504067061906928
+
+
+Infinite series use direct summation if the series converges quickly enough.
+Otherwise, extrapolation methods (generally the Euler-Maclaurin formula but
+also Richardson extrapolation) are used to speed up convergence. This allows
+high-precision evaluation of slowly convergent series:
+
+    >>> var('k')
+    k
+    >>> Sum(1/k**2, (k, 1, oo)).evalf()
+    1.64493406684823
+    >>> zeta(2).evalf()
+    1.64493406684823
+    >>> Sum(1/k-log(1+1/k), (k, 1, oo)).evalf()
+    0.577215664901533
+    >>> Sum(1/k-log(1+1/k), (k, 1, oo)).evalf(50)
+    0.57721566490153286060651209008240243104215933593992
+    >>> EulerGamma.evalf(50)
+    0.57721566490153286060651209008240243104215933593992
+
+
+The Euler-Maclaurin formula is also used for finite series, allowing them to
+be approximated quickly without evaluating all terms:
+
+    >>> Sum(1/k, (k, 10000000, 20000000)).evalf()
+    0.693147255559946
+
+
+Note that ``evalf`` makes some assumptions that are not always optimal. For
+fine-tuned control over numerical summation, it might be worthwhile to manually
+use the method ``Sum.euler_maclaurin``.
+
+Special optimizations are used for rational hypergeometric series (where the
+term is a product of polynomials, powers, factorials, binomial coefficients and
+the like). ``N``/``evalf`` sum series of this type very rapidly to high
+precision. For example, this Ramanujan formula for pi can be summed to 10,000
+digits in a fraction of a second with a simple command:
+
+    >>> f = factorial
+    >>> n = Symbol('n', integer=True)
+    >>> R = 9801/sqrt(8)/Sum(f(4*n)*(1103+26390*n)/f(n)**4/396**(4*n), (n, 0, oo)) #doctest: +SKIP
+    >>> N(R, 10000) #doctest: +SKIP
+    3.141592653589793238462643383279502884197169399375105820974944592307816406286208
+    99862803482534211706798214808651328230664709384460955058223172535940812848111745
+    02841027019385211055596446229489549303819644288109756659334461284756482337867831
+    ...
+
+
+Numerical simplification
+------------------------
+
+The function ``nsimplify`` attempts to find a formula that is numerically equal
+to the given input. This feature can be used to guess an exact formula for an
+approximate floating-point input, or to guess a simpler formula for a
+complicated symbolic input. The algorithm used by ``nsimplify`` is capable of
+identifying simple fractions, simple algebraic expressions, linear combinations
+of given constants, and certain elementary functional transformations of any of
+the preceding.
+
+Optionally, ``nsimplify`` can be passed a list of constants to include (e.g. pi)
+and a minimum numerical tolerance. Here are some elementary examples:
+
+    >>> nsimplify(0.1)
+    1/10
+    >>> nsimplify(6.28, [pi], tolerance=0.01)
+    2*pi
+    >>> nsimplify(pi, tolerance=0.01)
+    22/7
+    >>> nsimplify(pi, tolerance=0.001)
+    355
+    ---
+    113
+    >>> nsimplify(0.33333, tolerance=1e-4)
+    1/3
+    >>> nsimplify(2.0**(1/3.), tolerance=0.001)
+    635
+    ---
+    504
+    >>> nsimplify(2.0**(1/3.), tolerance=0.001, full=True)
+    3 ___
+    \/ 2
+
+
+Here are several more advanced examples:
+
+    >>> nsimplify(Float('0.130198866629986772369127970337',30), [pi, E])
+        1
+    ----------
+    5*pi
+    ---- + 2*E
+     7
+    >>> nsimplify(cos(atan('1/3')))
+        ____
+    3*\/ 10
+    --------
+       10
+    >>> nsimplify(4/(1+sqrt(5)), [GoldenRatio])
+    -2 + 2*GoldenRatio
+    >>> nsimplify(2 + exp(2*atan('1/4')*I))
+    49   8*I
+    -- + ---
+    17    17
+    >>> nsimplify((1/(exp(3*pi*I/5)+1)))
+               ___________
+              /   ___
+    1        /  \/ 5    1
+    - - I*  /   ----- + -
+    2     \/      10    4
+    >>> nsimplify(I**I, [pi])
+     -pi
+     ---
+      2
+    e
+    >>> n = Symbol('n')
+    >>> nsimplify(Sum(1/n**2, (n, 1, oo)), [pi])
+      2
+    pi
+    ---
+     6
+    >>> nsimplify(gamma('1/4')*gamma('3/4'), [pi])
+      ___
+    \/ 2 *pi
+
+
+
diff --git a/lib/sympy/doc/src/modules/functions.txt b/lib/sympy/doc/src/modules/functions.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/functions.txt
@@ -0,0 +1,220 @@
+Functions Module
+****************
+
+.. module:: sympy.functions
+
+Elementary
+==========
+
+This module implements elementary functions, as well as functions like Abs, Max, etc.
+
+
+Abs
+---
+
+Returns the absolute value of the argument.
+
+Examples::
+    >>> from sympy.functions import Abs
+    >>> Abs(-1)
+    1
+
+.. autoclass:: sympy.functions.elementary.complexes.Abs
+
+
+arg
+---
+
+Returns the argument (in radians) of a complex number. For a real
+number, the argument is always 0.
+
+Examples::
+    >>> from sympy.functions import arg
+    >>> from sympy import I, sqrt
+    >>> arg(2.0)
+    0
+    >>> arg(I)
+    pi/2
+    >>> arg(sqrt(2) + I*sqrt(2))
+    pi/4
+
+.. autoclass:: sympy.functions.elementary.complexes.arg
+
+conjugate
+---------
+
+Returns the 'complex conjugate <http://en.wikipedia.org/wiki/Complex_conjugation>'_
+of an argument. In mathematics, the complex conjugate of a complex number is given
+by changing the sign of the imaginary part. Thus, the conjugate of the complex number
+
+    a + ib
+
+(where a and b are real numbers) is
+
+    a - ib
+
+Examples::
+    >>> from sympy.functions import conjugate
+    >>> from sympy import I
+    >>> conjugate(2)
+    2
+    >>> conjugate(I)
+    -I
+
+.. autoclass:: sympy.functions.elementary.complexes.conjugate
+
+
+Min
+---
+
+Returns the minimum of two (comparable) expressions.
+
+Examples::
+    >>> from sympy.functions import Min
+    >>> Min(1,2)
+    1
+    >>> from sympy.abc import x
+    >>> Min(1, x)
+    Min(1, x)
+
+It is named Min and not min to avoid conflicts with the built-in function min.
+
+.. autoclass:: sympy.functions.elementary.miscellaneous.Min
+
+
+Max
+---
+
+Returns the maximum of two (comparable) expressions
+
+It is named Max and not max to avoid conflicts with the built-in function max.
+
+.. autoclass:: sympy.functions.elementary.miscellaneous.Max
+
+
+re
+--
+
+Return the real part of an expression
+
+Examples::
+    >>> from sympy.functions import re
+    >>> from sympy import I
+    >>> re(2+3*I)
+    2
+
+.. autoclass:: sympy.functions.elementary.complexes.re
+
+
+sqrt
+----
+
+Returns the square root of an expression. It is equivalent to raise to Rational(1,2)
+
+    >>> from sympy.functions import sqrt
+    >>> from sympy import Rational
+    >>> sqrt(2) == 2**Rational(1,2)
+    True
+
+.. autoclass:: sympy.functions.elementary.miscellaneous.sqrt
+
+
+sign
+----
+
+Returns the sign of an expression, that is:
+    -1 if expr is negative
+     0 if expr is zero
+     1 if expr is positive
+
+     >>> from sympy.functions import sign
+     >>> sign(-1)
+     -1
+     >>> sign(0)
+     0
+
+.. autoclass:: sympy.functions.elementary.complexes.sign
+
+
+Combinatorial
+=============
+
+This module implements various combinatorial functions.
+
+
+Binomial
+--------
+
+.. autoclass:: sympy.functions.combinatorial.factorials.binomial
+
+
+Factorial
+---------
+
+.. autoclass:: sympy.functions.combinatorial.factorials.factorial
+
+
+FallingFactorial
+----------------
+
+.. autoclass:: sympy.functions.combinatorial.factorials.FallingFactorial
+
+
+MultiFactorial
+--------------
+
+.. autoclass:: sympy.functions.combinatorial.factorials.MultiFactorial
+
+
+RisingFactorial
+---------------
+
+.. autoclass:: sympy.functions.combinatorial.factorials.RisingFactorial
+
+
+Special
+=======
+
+DiracDelta
+----------
+.. autoclass:: sympy.functions.special.delta_functions.DiracDelta
+
+Heaviside
+---------
+.. autoclass:: sympy.functions.special.delta_functions.Heaviside
+
+gamma
+-----
+.. autoclass:: sympy.functions.special.gamma_functions.gamma
+
+loggamma
+--------
+.. autoclass:: sympy.functions.special.gamma_functions.loggamma
+
+polygamma
+---------
+.. autoclass:: sympy.functions.special.gamma_functions.polygamma
+
+uppergamma
+----------
+.. autoclass:: sympy.functions.special.gamma_functions.uppergamma
+
+lowergamma
+----------
+.. autoclass:: sympy.functions.special.gamma_functions.lowergamma
+
+Bessel Type Functions
+---------------------
+.. autoclass:: sympy.functions.special.bessel.besselj
+.. autoclass:: sympy.functions.special.bessel.bessely
+.. autoclass:: sympy.functions.special.bessel.besseli
+.. autoclass:: sympy.functions.special.bessel.besselk
+.. autoclass:: sympy.functions.special.bessel.hankel1
+.. autoclass:: sympy.functions.special.bessel.hankel2
+.. autoclass:: sympy.functions.special.bessel.jn
+.. autoclass:: sympy.functions.special.bessel.yn
+
+Hypergeometric Functions
+------------------------
+.. autoclass:: sympy.functions.special.hyper.hyper
+.. autoclass:: sympy.functions.special.hyper.meijerg
diff --git a/lib/sympy/doc/src/modules/galgebra/GA/BasicGAtest.py b/lib/sympy/doc/src/modules/galgebra/GA/BasicGAtest.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/GA/BasicGAtest.py
@@ -0,0 +1,28 @@
+        MV.setup('a b c d e')
+        MV.set_str_format(1)
+
+        print 'e|(a^b) =',e|(a^b)
+        print 'e|(a^b^c) =',e|(a^b^c)
+        print 'a*(b^c)-b*(a^c)+c*(a^b) =',a*(b^c)-b*(a^c)+c*(a^b)
+        print 'e|(a^b^c^d) =',e|(a^b^c^d)
+        print -d*(a^b^c)+c*(a^b^d)-b*(a^c^d)+a*(b^c^d)
+
+        print (a^b)|(c^d)
+
+e|(a^b) = {-(b.e)}a
++{(a.e)}b
+
+e|(a^b^c) = {(c.e)}a^b
++{-(b.e)}a^c
++{(a.e)}b^c
+
+a*(b^c)-b*(a^c)+c*(a^b) = {3}a^b^c
+
+e|(a^b^c^d) = {-(d.e)}a^b^c
++{(c.e)}a^b^d
++{-(b.e)}a^c^d
++{(a.e)}b^c^d
+
+{4}a^b^c^d
+
+{(a.d)*(b.c) - (a.c)*(b.d)}1
diff --git a/lib/sympy/doc/src/modules/galgebra/GA/Dirac.py b/lib/sympy/doc/src/modules/galgebra/GA/Dirac.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/GA/Dirac.py
@@ -0,0 +1,41 @@
+#!/usr/local/bin/python
+#Dirac.py
+
+from sympy.galgebra.GA import *
+from sympy.galgebra.latex_ex import *
+from sympy import *
+
+set_main(sys.modules[__name__])
+
+if __name__ == '__main__':
+
+    metric = '1  0  0  0,'+\
+             '0 -1  0  0,'+\
+             '0  0 -1  0,'+\
+             '0  0  0 -1'
+
+    vars = make_symbols('t x y z')
+    MV.setup('gamma_t gamma_x gamma_y gamma_z',metric,True,vars)
+    
+    parms = make_symbols('m e')
+    Format('1 1 1 1')
+    I = MV(ONE,'pseudo')
+    nvars = len(vars)
+    psi = MV('psi','spinor',fct=True)
+    A = MV('A','vector',fct=True)    
+    sig_x = gamma_x*gamma_t
+    sig_y = gamma_y*gamma_t
+    sig_z = gamma_z*gamma_t
+    print '$A$ is 4-vector potential'
+    print A
+    print r'$\bm{\psi}$ is 8-component real spinor (even multi-vector)'
+    print psi
+    dirac_eq = psi.grad()*I*sig_z-e*A*psi-m*psi*gamma_t
+    dirac_eq.simplify()
+    print 'Dirac equation in terms of real geometric algebra/calculus '+\
+          r'$\lp\nabla \bm{\psi} I \sigma_{z}-eA\bm{\psi} = m\bm{\psi}\gamma_{t}\rp$'
+    print 'Spin measured with respect to $z$ axis'
+    Format('mv=3')
+    print r'\nabla \bm{\psi} I \sigma_{z}-eA\bm{\psi}-m\bm{\psi}\gamma_{t} = ',dirac_eq,' = 0'
+    xdvi(filename='Dirac.tex')
+    
diff --git a/lib/sympy/doc/src/modules/galgebra/GA/GAsympy.txt b/lib/sympy/doc/src/modules/galgebra/GA/GAsympy.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/GA/GAsympy.txt
@@ -0,0 +1,1776 @@
+**************************************
+  Geometric Algebra Module for Sympy
+**************************************
+
+:Author: Alan Bromborsky
+
+.. |release| replace:: 0.10
+
+.. % 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
+.. % \lstset{language=Python}
+.. % \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.
+
+.. math::
+
+    \newcommand{\bfrac}[2]{\displaystyle\frac{#1}{#2}}
+    \newcommand{\lp}{\left (}
+    \newcommand{\rp}{\right )}
+    \newcommand{\half}{\frac{1}{2}}
+    \newcommand{\llt}{\left <}
+    \newcommand{\rgt}{\right >}
+    \newcommand{\abs}[1]{\left |{#1}\right | }
+    \newcommand{\pdiff}[2]{\bfrac{\partial {#1}}{\partial {#2}}}
+    \newcommand{\lbrc}{\left \{}
+    \newcommand{\rbrc}{\right \}}
+    \newcommand{\W}{\wedge}
+    \newcommand{\R}{\dagger}
+    \newcommand{\lbrk}{\left [}
+    \newcommand{\rbrk}{\right ]}
+    \newcommand{\proj}[2]{\llt {#1} \rgt_{#2}}
+    \newcommand{\bm}{\boldsymbol}
+
+
+
+.. topic:: Abstract
+
+   This document describes the implementation of a geometric algebra module in
+   python  that utilizes the :mod:`sympy` symbolic algebra library.  The   python
+   module :mod:`GA` has been developed for coordinate free calculations using
+   the operations (geometric, outer, and inner products etc.) of geometric algebra.
+   The operations can be defined using a completely arbitrary metric defined
+   by the inner products of a set of arbitrary vectors or the metric  can be
+   restricted to enforce orthogonality and signature constraints on the set of
+   vectors.  In addition the module includes the geometric, outer (curl) and inner
+   (div) derivatives and the ability to define a curvilinear coordinate  system.
+   The module requires the numpy and the sympy modules.
+
+
+What is Geometric Algebra?
+==========================
+
+Geometric algebra is the Clifford algebra of a real finite dimensional vector
+space or the algebra that  results when a real finite dimensional vector space
+is extended with a product of vectors (geometric product) that is associative,
+left and right distributive, and yields a real number for the square (geometric
+product) of any vector [Hestenes,Lasenby].  The elements of the geometric
+algebra are called multivectors and consist of the linear combination of
+scalars, vectros, and the geometric product of two or more vectors. The
+additional axioms  for the geometric algebra are that for any vectors :math:`a`,
+:math:`b`, and :math:`c` in the base vector space:
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \begin{array}{c}
+  a\lp bc \rp = \lp ab \rp c \\
+  a\lp b+c \rp = ab+ac \\
+  \lp a + b \rp c = ac+bc \\
+  aa = a^{2} \in \Re
+  \end{array}
+  \end{equation*}
+
+
+By induction these also apply to any multivectors.
+
+Several software packages for numerical geometric algebra calculations are
+available from Doran-Lazenby group and the Dorst group. Symbolic packages for
+Clifford algebra using orthongonal bases such as
+:math:`e_{i}e_{j}+e_{j}e_{i} = 2\eta_{ij}`, where :math:`\eta_{ij}` is a numeric
+array are available in Maple and Mathematica. The symbolic algebra module,
+:mod:`GA`, developed for python does not depend on an orthogonal basis
+representation, but rather is generated from a set of :math:`n` arbitrary
+symbolic vectors,  :math:`a_{1},a_{2},\dots,a_{n}` and a symbolic metric
+tensor :math:`g_{ij} = a_{i}\cdot a_{j}`.
+
+In order not to reinvent the wheel all scalar symbolic algebra is handled by the
+python module  :mod:`sympy`.
+
+The basic geometic algebra operations will be implemented in python by defining
+a multivector  class, MV, and overloading the python operators in Table
+:ref:`1 <table1>` where ``A`` and ``B``  are any two multivectors (In the case of
+``+``, ``-``, ``*``, ``^``, ``|``, ``<<``, and ``>>`` the operation is also defined if ``A`` or
+``B`` is a sympy symbol or a sympy real number).
+
+.. _table1:
+
+.. csv-table::
+    :header: " Operation ", " Result "
+    :widths: 10, 40
+
+    " ``A+B`` ", " sum of multivectors "
+    " ``A-B`` ", " difference of multivectors "
+    " ``A*B`` ", " geometric product "
+    " ``A^B`` ", " outer product of multivectors  "
+    " ``A|B`` ", " inner product of multivectors "
+    " ``A<B`` or ``A<<B`` ", " left contraction of multivectors "
+    " ``A>B`` or ``A>>B`` ", " right contraction of multivectors "
+
+Table :ref:`1 <table1>`. Multivector operations for symbolicGA
+
+The option to use ``<`` or ``<<`` for left contraction and ``>`` or ``>>`` is given since the ``<`` and
+``>`` operators do not have r-forms (there are no *__rlt__()* and *__rlt__()* functions to overload) while
+``<<`` and ``>>`` do have r-forms so that *x << A* and *x >> A* are allowed where *x* is a scalar (symbol or integer)
+and *A* is a multivector. With ``<`` and ``>`` we can only have mixed modes (scalars and multivectors) if the
+multivector is the first operand.
+
+.. note::
+
+    Except for ``<`` and ``>`` all the multivector operators have r-forms so that as long as one of the
+    operands, left or right, is a multivector the other can be a multivector or a scalar (sympy symbol or integer).
+
+.. warning::
+
+    Note that the operator order precedence is determined by python and is not
+    neccessarily that used by  geometric algebra. It is **absolutely essential** to
+    use parenthesis in multivector
+    expressions containing ``^``, ``|``, ``<``, ``>``, ``<<`` and/or ``>>``.  As an example let
+    ``A`` and ``B`` be any two multivectors. Then ``A + A*B = A +(A*B)``, but
+    ``A+A^B = (2*A)^B`` since in python the ``^`` operator has a lower precedence
+    than the '+' operator.  In geometric algebra the outer and inner products and
+    the left and right contractions have a higher precedence than the geometric
+    product and the geometric product has a higher precedence than addition and
+    subtraction.  In python the ``^``, ``|``, ``<``, ``>``, ``<<`` and ``>>`` all have a lower
+    precedence than ``+`` and ``-`` while ``*`` has a higher precedence than
+    ``+`` and ``-``.
+
+
+.. _vbm:
+
+Vector Basis and Metric
+=======================
+
+The two structures that define the :class:`MV` (multivector) class are the
+symbolic basis vectors and the  symbolic metric.  The symbolic basis
+vectors are input as a string with the symbol name separated by spaces.  For
+example if we are calculating the geometric algebra of a system with three
+vectors that we wish to denote as ``a0``, ``a1``, and ``a2`` we would define the
+string variable:
+
+``basis = 'a0 a1 a2'``
+
+that would be input into the multivector setup function.  The next step would be
+to define the symbolic  metric for the geometric algebra of the basis we
+have defined. The default metric is the most general and is the matrix of
+the following symbols
+
+.. _eq1:
+
+
+
+.. math::
+  :label: 1
+  :nowrap:
+
+  \begin{equation*}
+  g = \lbrk
+  \begin{array}{ccc}
+    a0**2 & (a0.a1)  & (a0.a2) \\
+    (a0.a1) & a1**2  & (a1.a2) \\
+    (a0.a2) & (a1.a2) & a2**2 \\
+  \end{array}
+  \rbrk
+  \end{equation*}
+
+
+where each of the :math:`g_{ij}` is a symbol representing all of the dot
+products of the basis vectors. Note that the symbols are named so that
+:math:`g_{ij} = g_{ji}` since for the symbol function
+:math:`(a0.a1) \ne (a1.a0)`.
+
+Note that the strings shown in equation :ref:`1 <eq1>` are only used when the values
+of :math:`g_{ij}` are output (printed).   In the :mod:`GA` module (library)
+the :math:`g_{ij}` symbols are stored in a static member list of the multivector
+class :class:`MV` as the double list *MV.metric* (:math:`g_{ij}` = *MV.metric[i][j]*).
+
+The default definition of :math:`g` can be overwritten by specifying a string
+that will define :math:`g`. As an example  consider a symbolic representation
+for conformal geometry. Define for a basis
+
+``basis = 'a0 a1 a2 n nbar'``
+
+and for a metric
+
+``metric = '# # # 0 0, # # # 0 0, # # # 0 0, 0 0 0 0 2, 0 0 0 2 0'``
+
+then calling `MV.setup(basis,metric)` would initialize
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  g = \lbrk
+  \begin{array}{ccccc}
+    a0**2 & (a0.a1)  & (a0.a2) & 0 & 0\\
+    (a0.a1) & a1**2  & (a1.a2) & 0 & 0\\
+    (a0.a2) & (a1.a2) & a2**2 & 0 & 0 \\
+    0 & 0 & 0 & 0 & 2 \\
+    0 & 0 & 0 & 2 & 0
+  \end{array}
+  \rbrk
+  \end{equation*}
+
+
+Here we have specified that :math:`n` and :math:`nbar` are orthonal to all the
+:math:`a`'s, :math:`n**2 = nbar**2 = 0`, and :math:`(n.nbar) = 2`. Using
+:math:`\#` in the metric definition string just tells the program to use the
+default symbol for that value.
+
+When ``MV.setup`` is called multivector representations of the basis local to
+the program are instantiated.  For our first example that means that the
+symbolic vectors named ``a0``, ``a1``, and ``a2`` are created and made available
+to the programmer for future calculations.
+
+In addition to the basis vectors the :math:`g_{ij}` are also made available to
+the programer with the following convention. If ``a0`` and ``a1`` are basis
+vectors, then their dot products are denoted by  ``a0sq``, ``a2sq``, and
+``a0dota1`` for use as python program varibles. If you print  ``a0sq`` the
+output would be ``a0**2`` and the output for ``a0dota1`` would be ``(a0.a1)`` as
+shown in equation :ref:`1 <eq1>`.  If the default value are overridden the new
+values are output by print.  For examle if :math:`g_{00} = 0` then "``print
+a0sq``" would output "0."
+
+More generally, if ``metric`` is not a string, but a list of lists or a two
+dimension numpy array, it is assumed that each element of ``metric`` is symbolic
+variable so that the :math:`g_{ij}` could be defined as symbolic functions as
+well as variables. For example instead of letting :math:`g_{01} = (a0.a1)` we
+could have  :math:`g_{01} = cos(theta)` where we use a symbolic :math:`\cos`
+function.
+
+.. note::
+
+    Additionally ``MV.setup`` has an option for an othogonal basis where the signature
+    of the metric space is defined by a string.  For example if the signature of the
+    vector space is :math:`(1,1,1)` (Euclidian 3-space) set
+
+    ``metric = '[1,1,1]'``
+
+    Likewise if the signature is that of spacetime, :math:`(1,-1,-1,-1)` then define
+
+    ``metric = '[1,-1,-1,-1]'``.
+
+
+Representation and Reduction of Multivector Bases
+=================================================
+
+In our symbolic geometric algebra we assume that all multivectors of interest to
+us can be obtained from the symbolic basis vectors we have input, via the
+different operations available to geometric algebra. The first problem we have
+is representing the general multivector in terms terms of the basis vectors.  To
+do this we  form the ordered geometric products of the basis vectors and develop
+an internal representation of these  products in terms of python classes.  The
+ordered geometric products are all multivectors of the form
+:math:`a_{i_{1}}a_{i_{2}}\dots a_{i_{r}}` where :math:`i_{1}<i_{2}<\dots <i_{r}`
+and :math:`r \le n`. We call these multivectors bases and represent them
+internally with the list of integers
+:math:`\lbrk i_{1},i_{2},\dots,i_{r}\rbrk`. The bases are labeled, for the
+purpose of output display, with strings that are concatenations of the strings
+representing the basis vectors.  So that in our example  ``[1,2]`` would be
+labeled with the string ``'a1a2'`` and represents the geometric product
+``a1*a2``. Thus the list ``[0,1,2]`` represents ``a0*a1*a2``.For our example the
+complete set of bases and labels are shown in Table :ref:`2 <table2>`
+
+.. note::
+
+    The empty list, ``[]``, represents the scalar 1.
+
+.. _table2:
+
+::
+
+   MV.basislabel = ['1', ['a0', 'a1', 'a2'], ['a0a1', 'a0a2', 'a1a2'],
+                    ['a0a1a2']]
+   MV.basis      = [[], [[0], [1], [2]], [[0, 1], [0, 2], [1, 2]],
+                    [[0, 1, 2]]]
+
+Table :ref:`2 <table2>`. Multivector basis labels and internal basis representation.
+
+Since there are :math:`2^{n}` bases and the number of bases with equal list
+lengths is the same as for the  grade decomposition of a dimension :math:`n`
+geometric algebra we will call the collections of bases of equal length
+``psuedogrades``.
+
+The critical operation in setting up the geometric algebra module is reducing
+the geomertric product of any two bases to a linear combination of bases so that
+we can calculate a multiplication table for the bases.   First we represent the
+product as the concatenation of two base lists.  For example ``a1a2*a0a1`` is
+represented by the list ``[1,2]+[0,1] = [1,2,0,1]``. The representation of the
+product is reduced via two operations, contraction and revision. The state of
+the reduction is saved in two lists of equal length.  The first list contains
+symbolic scale factors (symbol or numeric types) for the corresponding interger
+list representing the product of  bases.  If we wish to reduce
+:math:`\lbrk i_{1},\dots,i_{r}\rbrk` the starting point is the coefficient list
+:math:`C = \lbrk 1 \rbrk` and the bases list
+:math:`B = \lbrk \lbrk i_{1},\dots,i_{r}\rbrk \rbrk`.  We now operate  on each
+element of the lists as follows:
+
+* ``contraction``: Consider a basis list :math:`B` with element
+  :math:`B[j] = \lbrk i_{1},\dots,i_{l},i_{l+1},\dots,i_{s}\rbrk` where
+  :math:`i_{l} = i_{l+1}`. Then the product of the :math:`l` and :math:`l+1` terms
+  result in a scalar and :math:`B[j]` is replaced by the new list representation
+  :math:`\lbrk i_{1},\dots,i_{l-1},i_{l+2},\dots,i_{r}\rbrk` which is of  psuedo
+  grade :math:`r-2` and :math:`C[j]` is replaced by the symbol
+  :math:`g_{i_{l}i_{l}}C[j]`.
+
+* ``revision``: Consider a basis list :math:`B` with element
+  :math:`B[j] = \lbrk i_{1},\dots,i_{l},i_{l+1},\dots,i_{s}\rbrk` where
+  :math:`i_{l} > i_{l+1}`. Then the :math:`l` and :math:`l+1` elements must be
+  reversed to be put in normal order, but we have :math:`a_{i_{l}}a_{i_{l+1}} = 2g_{i_{l}i_{l+1}}-a_{i_{l+1}}a_{i_{l}}`
+  (From the geometric  algebra definition of the dot product of two vectors). Thus
+  we append the list representing the reduced element,
+  :math:`\lbrk i_{1},\dots,i_{l-1},i_{l+2},\dots,i_{s}\rbrk`, to the pseudo bases
+  list, :math:`B`, and append :math:`2g_{i{l}i_{l+1}}C[j]` to the coefficients
+  list, then  we replace :math:`B[j]` with
+  :math:`\lbrk i_{1},\dots,i_{l+1},i_{l},\dots,i_{s}\rbrk`  and :math:`C[j]` with
+  :math:`-C[j]`. Both lists are increased by one element if
+  :math:`g_{i_{l}i_{l+1}} \ne 0`.
+
+These processes are repeated untill every basis list in :math:`B` is in normal
+(ascending) order with no repeated elements.  Then the coefficents of equivalent
+bases are summed and the bases sorted according to psuedograde and ascending
+order.  We now have a way of calculating the geometric product of any two bases
+as a symbolic linear combination of all the bases with the coefficients
+determined by :math:`g`. The base multiplication table for our simple example of
+three vectors is given by (the coefficient of each psuedo base is enclosed with
+{} for clarity):
+
+
+.. include:: multable.dat
+   :literal:
+
+
+Base Representation of Multivectors
+===================================
+
+In terms of the bases defined an arbitrary multivector can be represented as a
+list of arrays  (we use the numpy python module to implement arrays).   If we
+have :math:`n` basis vectors we initialize the list ``self.mv = [0,0,...,0]``
+with :math:`n+1` integers all zero.   Each zero is a placeholder for an array of
+python objects (in this case the objects will be sympy  symbol objects). If
+``self.mv[r] = numpy.array([list of symbol objects])`` each entry in the
+``numpy.array`` will be a coefficient of the corresponding psuedo base.
+``self.mv[r] = 0`` indicates that the coefficients of every base of psuedo grade
+:math:`r` are 0.  The length of the array ``self.mv[r]`` is :math:`n \choose r`
+the binomial coefficient. For example the psuedo basis vector ``a1`` would be
+represented as a multivector by the list:
+
+``a1.mv = [0,numpy.array([numeric(0),numeric(1),numeric(0)]),0,0]``
+
+and ``a0a1a2`` by:
+
+``a0a1a2.mv = [0,0,0,numpy.array([numeric(1)])]``
+
+The array is stuffed with sympy numeric objects instead of python integers so
+that we can perform symbolically manipulate sympy expressions that consist of
+scalar algebraic symbols and exact rational numbers which sympy can also
+represent.
+
+The ``numpy.array`` is used because operations of addition, substraction, and
+multiplication by an object are defined for the array if they are defined for
+the objects making up the array, which they are by sympy.  We call this
+representation a base type because the ``r`` index is not a grade index since
+the bases we are using are not blades. In a blade representation the structure
+would be identical, but the bases would be replaced by  blades and
+``self.mv[r]`` would represent the ``r`` grade components of the multivector.
+The first use of the base representation is to store the results of the
+multiplication tabel for the bases in the class variable ``MV.mtabel``.  This
+variable is a group of nested lists so that the geometric product of the
+``igrade`` and  ``ibase`` with the ``jgrade`` and ``jbase`` is
+``MV.mtabel[igrade][ibase][jgrade][jbase]``.  We can then use this table to
+calculate the geometric product of any two multivectors.
+
+
+Blade Representation of Multivectors
+====================================
+
+Since we can now calculate the symbolic geometric product of any two
+multivectors we can also calculate the blades corresponding to the product of
+the symbolic basis vectors using the formula
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+    A_{r}\W b = \half\lp A_{r}b-\lp -1 \rp^{r}bA_{r} \rp,
+  \end{equation*}
+
+
+where :math:`A_{r}` is a multivector of grade :math:`r` and :math:`b` is a
+vector.  For our example basis the result  is shown in Table :ref:`3 <table3>`.
+
+.. _table3:
+
+::
+
+   1 = 1
+   a0 = a0
+   a1 = a1
+   a2 = a2
+   a0^a1 = {-(a0.a1)}1+a0a1
+   a0^a2 = {-(a0.a2)}1+a0a2
+   a1^a2 = {-(a1.a2)}1+a1a2
+   a0^a1^a2 = {-(a1.a2)}a0+{(a0.a2)}a1+{-(a0.a1)}a2+a0a1a2
+
+Table :ref:`3 <table3>`. Bases blades in terms of bases.
+
+The important thing to notice about Table :ref:`3 <table3>` is that it is a
+triagonal (lower triangular) system of equations so that using a simple back
+substitution algorithym we can solve for the psuedo bases in terms of the blades
+giving Table :ref:`4 <table4>`.
+
+.. _table4:
+
+::
+
+   1 = 1
+   a0 = a0
+   a1 = a1
+   a2 = a2
+   a0a1 = {(a0.a1)}1+a0^a1
+   a0a2 = {(a0.a2)}1+a0^a2
+   a1a2 = {(a1.a2)}1+a1^a2
+   a0a1a2 = {(a1.a2)}a0+{-(a0.a2)}a1+{(a0.a1)}a2+a0^a1^a2
+
+Table :ref:`4 <table4>`. Bases in terms of basis blades.
+
+Using Table :ref:`4 <table4>` and simple substitution we can convert from a base
+multivector representation to a blade representation.  Likewise, using Table
+:ref:`3 <table3>` we can convert from  blades to bases.
+
+Using the blade representation it becomes simple to program functions that will
+calculate the grade projection, reverse, even, and odd multivector functions.
+
+Note that in the multivector class ``MV`` there is a class variable for each
+instantiation, ``self.bladeflg``, that is set to zero for a base representation
+and 1 for a blade representation.  One needs to keep track of which
+representation is in use since various multivector operations require conversion
+from one representation to the other.
+
+.. warning::
+
+    When the geometric product of two multivectors is calculated the module looks to
+    see if either multivector is in blade representation.  If either is the result of
+    the geometric product is converted to a blade representation.  One result of this
+    is that if either of the multivectors is a simple vector (which is automatically a
+    blade) the result will be in a blade representation.  If ``a`` and ``b`` are vectors
+    then the result ``a*b`` will be ``(a.b)+a^b`` or simply ``a^b`` if ``(a.b) = 0``.
+
+
+Outer and Inner Products, Left and Right Contractions
+=====================================================
+
+In geometric algebra any general multivector :math:`A` can be decomposed into
+pure grade  multivectors (a linear combination of blades of all the same order)
+so that in a :math:`n`-dimensional vector space
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A = \sum_{r = 0}^{n}A_{r}
+  \end{equation*}
+
+
+The geometric product of two pure grade multivectors :math:`A_{r}` and
+:math:`B_{s}` has the form
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A_{r}B_{s} = \proj{A_{r}B_{s}}{\abs{r-s}}+\proj{A_{r}B_{s}}{\abs{r-s}+2}+\cdots+\proj{A_{r}B_{s}}{r+s}
+  \end{equation*}
+
+
+where :math:`\proj{}{t}` projects the :math:`t` grade components of the
+multivector argument.  The   inner and outer products of :math:`A_{r}` and
+:math:`B_{s}` are then defined to be
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A_{r}\cdot B_{s} = \proj{A_{r}B_{s}}{\abs{r-s}}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A_{r}\wedge B_{s} = \proj{A_{r}B_{s}}{r+s}
+  \end{equation*}
+
+
+and
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A\cdot B = \sum_{r,s}A_{r}\cdot B_{s}
+  \end{equation*}
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A\wedge B = \sum_{r,s}A_{r}\wedge B_{s}
+  \end{equation*}
+
+
+Likewise the right (:math:`\lfloor`) and left (:math:`\rfloor`) contractions are defined as
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A_{r}\lfloor B_{s} = \left \{ \begin{array}{cc}
+     \proj{A_{r}B_{s}}{r-s} &  r \ge s \\
+               0            &  r < s \end{array} \right \}
+  \end{equation*}
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A_{r}\rfloor B_{s} = \left \{ \begin{array}{cc}
+     \proj{A_{r}B_{s}}{s-r} &  s \ge r \\
+               0            &  s < r \end{array} \right \}
+  \end{equation*}
+
+
+and
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A\lfloor B = \sum_{r,s}A_{r}\lfloor B_{s}
+  \end{equation*}
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A\rfloor B = \sum_{r,s}A_{r}\rfloor B_{s}
+  \end{equation*}
+
+
+The ``MV`` class function for the outer product of the multivectors ``mv1`` and
+``mv2`` is ::
+
+   @staticmethod
+   def outer_product(mv1,mv2):
+        product = MV()
+        product.bladeflg = 1
+        mv1.convert_to_blades()
+        mv2.convert_to_blades()
+        for igrade1 in MV.n1rg:
+            if not isint(mv1.mv[igrade1]):
+                pg1 = mv1.project(igrade1)
+                for igrade2 in MV.n1rg:
+                    igrade = igrade1+igrade2
+                    if igrade <= MV.n:
+                        if not isint(mv2.mv[igrade2]):
+                            pg2 = mv2.project(igrade2)
+                            pg1pg2 = pg1*pg2
+                            product.add_in_place(pg1pg2.project(igrade))
+        return(product)
+
+
+The steps for calculating the outer product are:
+
+#. Convert ``mv1`` and ``mv2`` to blade representation if they are not already
+   in that form.
+
+#. Project and loop through each grade ``mv1.mv[i1]`` and ``mv2.mv[i2]``.
+
+#. Calculate the geometric product ``pg1*pg2``.
+
+#. Project the ``i1+i2`` grade from ``pg1*pg2``.
+
+#. Accumulate the results for each pair of grades in the input multivectors.
+
+.. warning::
+
+    In the  ``MV`` class we have overloaded the ``^`` operator to represent the outer
+    product so that instead of calling the outer product function we can write ``mv1^ mv2``.
+    Due to the precedence rules for python it is **absolutely essential** to enclose outer products
+    in parenthesis.
+
+For the inner product of the multivectors ``mv1`` and ``mv2`` the ``MV`` class
+function is  ::
+
+    @staticmethod
+    def inner_product(mv1,mv2,mode='s'):
+        """
+        MV.inner_product(mv1,mv2) calculates the inner
+
+        mode = 's' - symmetic (Doran & Lasenby)
+        mode = 'l' - left contraction (Dorst)
+        mode = 'r' - right contraction (Dorst)
+        """
+        if isinstance(mv1,MV) and isinstance(mv2,MV):
+            product = MV()
+            product.bladeflg = 1
+            mv1.convert_to_blades()
+            mv2.convert_to_blades()
+            for igrade1 in range(MV.n1):
+                if isinstance(mv1.mv[igrade1],numpy.ndarray):
+                    pg1 = mv1.project(igrade1)
+                    for igrade2 in range(MV.n1):
+                        igrade = igrade1-igrade2
+                        if mode == 's':
+                            igrade = igrade.__abs__()
+                        else:
+                            if mode == 'l':
+                                igrade = -igrade
+                        if igrade >= 0:
+                            if isinstance(mv2.mv[igrade2],numpy.ndarray):
+                                pg2 = mv2.project(igrade2)
+                                pg1pg2 = pg1*pg2
+                                product.add_in_place(pg1pg2.project(igrade))
+            return(product)
+        else:
+            if mode == 's':
+                if isinstance(mv1,MV):
+                    product = mv1.scalar_mul(mv2)
+                if isinstance(mv2,MV):
+                    product = mv2.scalar_mul(mv1)
+            else:
+                product = None
+        return(product)
+
+
+The inner product is calculated the same way as the outer product except that in
+step 4, ``i1+i2`` is replaced by ``abs(i1-i2)`` or ``i1-i2`` for the right contraction or
+``i2-i1`` for the left contraction.  If ``i1-i2`` is less than zero there is no contribution
+to the right contraction.  If ``i2-i1`` is less than zero there is no contribution to the
+left contraction.
+
+.. warning::
+
+    In the ``MV`` class we have overloaded the ``|`` operator for the inner product,
+    ``>`` operator for the right contraction, and ``<`` operator for the left contraction.
+    Instead of calling the inner product function we can write ``mv1|mv2``, ``mv1>mv2``, or
+    ``mv1<mv2`` respectively for the inner product, right contraction, or left contraction.
+    Again, due to the precedence rules for python it is **absolutely essential** to enclose inner
+    products and/or contractions in parenthesis.
+
+
+.. _reverse:
+
+Reverse of Multivector
+======================
+
+If :math:`A` is the geometric product of :math:`r` vectors
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+    A = a_{1}\dots a_{r}
+  \end{equation*}
+
+
+then the reverse of :math:`A` designated :math:`A^{\R}` is defined by
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+    A^{\R} \equiv a_{r}\dots a_{1}.
+  \end{equation*}
+
+
+The reverse is simply the product with the order of terms reversed.  The reverse
+of a sum of products is defined as the sum of the reverses so that for a general
+multivector A we have
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+    A^{\R} = \sum_{i=0}^{N} \proj{A}{i}^{\R}
+  \end{equation*}
+
+
+but
+
+.. _eq14:
+
+
+
+.. math::
+  :label: 2
+  :nowrap:
+
+  \begin{equation*}
+    \proj{A}{i}^{\R} = \lp -1\rp^{\frac{i\lp i-1\rp}{2}}\proj{A}{i}
+  \end{equation*}
+
+
+which is proved by expanding the blade bases in terms of orthogonal vectors and
+showing that equation :ref:`2 <eq14>` holds for the geometric product of orthogonal
+vectors.
+
+The reverse is important in the theory of rotations in :math:`n`-dimensions.  If
+:math:`R` is the product of an even number of vectors and :math:`RR^{\R} = 1`
+then :math:`RaR^{\R}` is a composition of rotations of the  vector :math:`a`.
+If :math:`R` is the product of two vectors then the plane that :math:`R` defines
+is the plane of the rotation.  That is to say that :math:`RaR^{\R}` rotates the
+component of :math:`a` that is projected into the plane defined by :math:`a` and
+:math:`b` where :math:`R=ab`.  :math:`R` may be written
+:math:`R = e^{\frac{\theta}{2}U}`, where :math:`\theta` is the angle of rotation
+and :math:`u` is a unit blade :math:`\lp u^{2} = \pm 1\rp` that defines the
+plane of rotation.
+
+
+.. _recframe:
+
+Reciprocal Frames
+=================
+
+If we have :math:`M` linearly independent vectors (a frame),
+:math:`a_{1},\dots,a_{M}`, then the reciprocal frame is
+:math:`a^{1},\dots,a^{M}` where :math:`a_{i}\cdot a^{j} = \delta_{i}^{j}`,
+:math:`\delta_{i}^{j}` is the Kronecker delta (zero if :math:`i \ne j` and one
+if :math:`i = j`). The reciprocal frame is constructed as follows:
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+    E_{M} = a_{1}\W\dots\W a_{M}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+    E_{M}^{-1} = \bfrac{E_{M}}{E_{M}^{2}}
+  \end{equation*}
+
+
+Then
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+    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}
+  \end{equation*}
+
+
+where :math:`\breve{a}_{i}` indicates that :math:`a_{i}` is to be deleted from
+the product.  In the standard notation if a vector is denoted with a subscript
+the reciprocal vector is denoted with a superscript. The multivector setup
+function ``MV.setup(basis,metric,rframe)`` has the argument ``rframe`` with a
+default value of ``False``.  If it is set to ``True`` the reciprocal frame of
+the basis vectors is  calculated. Additionaly there is the function
+``reciprocal_frame(vlst,names='')`` external to the ``MV`` class that will
+calculate the reciprocal frame of a list, ``vlst``, of vectors.  If the argument
+``names`` is set to a space delimited string of names for the vectors the
+reciprocal vectors will be given these names.
+
+
+.. _deriv:
+
+Geometric Derivative
+====================
+
+If :math:`F` is a multivector field that is a function of a vector
+:math:`x = x^{i}\bm{\gamma}_{i}` (we are using the summation convention that
+pairs of subscripts and superscripts are summed over the dimension of the vector
+space) then the geometric derivative :math:`\nabla F` is given by (in this
+section the summation convention is used):
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+    \nabla F = \bm{\gamma}^{i}\bfrac{\partial F}{\partial x^{i}}
+  \end{equation*}
+
+
+If :math:`F_{R}` is a grade-:math:`R` multivector and
+:math:`F_{R} = F_{R}^{i_{1}\dots i_{R}}\bm{\gamma}_{i_{1}}\W\dots\W \bm{\gamma}_{i_{R}}`
+then
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+    \nabla F_{R} = \bfrac{\partial F_{R}^{i_{1}\dots i_{R}}}{\partial x^{j}}\bm{\gamma}^{j}\lp\bm{\gamma}_{i_{1}}\W
+                 \dots\W \bm{\gamma}_{i_{R}} \rp
+  \end{equation*}
+
+
+Note that
+:math:`\bm{\gamma}^{j}\lp\bm{\gamma}_{i_{1}}\W\dots\W \bm{\gamma}_{i_{R}} \rp`
+can only contain grades :math:`R-1` and :math:`R+1` so that :math:`\nabla F_{R}`
+also can only contain those grades. For a grade-:math:`R` multivector
+:math:`F_{R}` the inner (div) and  outer (curl) derivatives are defined as
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \nabla\cdot F_{R} = \left < \nabla F_{R}\right >_{R-1}
+  \end{equation*}
+
+
+and
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \nabla\W F_{R} = \left < \nabla F_{R}\right >_{R+1}
+  \end{equation*}
+
+
+For a general multivector function :math:`F` the inner and outer derivatives are
+just the sum of the inner and outer  dervatives of each grade of the multivector
+function.
+
+Curvilinear coordinates are derived from a vector function
+:math:`x(\bm{\theta})` where
+:math:`\bm{\theta} = \lp\theta_{1},\dots,\theta_{N}\rp` where the number of
+coordinates is equal to the dimension of the  vector space.  In the case of
+3-dimensional spherical coordinates :math:`\bm{\theta} = \lp r,\theta,\phi \rp`
+and the coordinate generating function :math:`x(\bm{\theta})` is
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  x =  r \cos\left({\phi}\right) \sin\left({\theta}\right){\bm{{\gamma}_{x}}}+ r \sin\left({\phi}\right) \sin\left({\theta}\right){\bm{{\gamma}_{y}}}+ r \cos\left({\theta}\right){\bm{{\gamma}_{z}}}
+  \end{equation*}
+
+
+A coordinate frame is derived from :math:`x` by
+:math:`\bm{e}_{i} = \pdiff{x}{\theta^{i}}`.  The following show the frame for
+spherical coordinates.
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \bm{e}_{r} = \cos\left({\phi}\right) \sin\left({\theta}\right){\bm{{\gamma}_{x}}}+\sin\left({\phi}\right) \sin\left({\theta}\right){\bm{{\gamma}_{y}}}+\cos\left({\theta}\right){\bm{{\gamma}_{z}}}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \bm{e}_{{\theta}} = \cos\left({\phi}\right) \cos\left({\theta}\right){\bm{{\gamma}_{x}}}+r \cos\left({\theta}\right) \sin\left({\phi}\right){\bm{{\gamma}_{y}}} - r \sin\left({\theta}\right){\bm{{\gamma}_{z}}}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \bm{e}_{{\phi}} =  - r \sin\left({\phi}\right) \sin\left({\theta}\right){\bm{{\gamma}_{x}}}+r \cos\left({\phi}\right) \sin\left({\theta}\right){\bm{{\gamma}_{y}}}
+  \end{equation*}
+
+
+The coordinate frame generated in this manner is not necessarily normalized so
+define a normalized frame by
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \bm{\hat{e}}_{i} = \bfrac{\bm{e}_{i}}{\sqrt{\abs{\bm{e}_{i}^{2}}}} = \bfrac{\bm{e}_{i}}{\abs{\bm{e}_{i}}}
+  \end{equation*}
+
+
+This works for all :math:`\bm{e}_{i}^{2} \neq 0` since we have defined
+:math:`\abs{\bm{e}_{i}} = \sqrt{\abs{\bm{e}_{i}^{2}}}`.   For spherical
+coordinates the normalized frame vectors are
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \bm{\hat{e}}_{r} =  \cos\left({\phi}\right) \sin\left({\theta}\right){\bm{{\gamma}_{x}}}+\sin\left({\phi}\right) \sin\left({\theta}\right){\bm{{\gamma}_{y}}}+\cos\left({\theta}\right){\bm{{\gamma}_{z}}}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \bm{\hat{e}}_{{\theta}} = \cos\left({\phi}\right) \cos\left({\theta}\right){\bm{{\gamma}_{x}}}+\cos\left({\theta}\right) \sin\left({\phi}\right){\bm{{\gamma}_{y}}}- \sin\left({\theta}\right){\bm{{\gamma}_{z}}}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \bm{\hat{e}}_{{\phi}} = - \sin\left({\phi}\right){\bm{{\gamma}_{x}}}+\cos\left({\phi}\right){\bm{{\gamma}_{y}}}
+  \end{equation*}
+
+
+The geometric derivative in curvilinear coordinates is given by
+
+.. math::
+  :nowrap:
+
+  \begin{align*}
+    \nabla F_{R} & =  \bm{\gamma}^{i}\pdiff{}{x^{i}}\lp F_{R}^{i_{1}\dots i_{R}}
+                     \bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{R}}\rp  \\
+                   & =  \bm{e^{j}}\pdiff{}{\theta^{j}}\lp F_{R}^{i_{1}\dots i_{R}}
+                     \bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{R}}\rp  \\
+                   & =   \lp\pdiff{}{\theta^{j}} F_{R}^{i_{1}\dots i_{R}}\rp
+                     \bm{e^{j}}\lp\bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{R}}\rp+
+                     F_{R}^{i_{1}\dots i_{R}}\bm{e^{j}}
+                     \pdiff{}{\theta^{j}}\lp\bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{R}}\rp \\
+                   & =   \lp\pdiff{}{\theta^{j}} F_{R}^{i_{1}\dots i_{R}}\rp
+                     \bm{e^{j}}\lp\bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{R}}\rp+
+                     F_{R}^{i_{1}\dots i_{R}}C\lbrc \bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{R}}\rbrc
+  \end{align*}
+
+
+where
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  C\lbrc \bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{R}}\rbrc  = \bm{e^{j}}\pdiff{}{\theta^{j}}
+                                                              \lp\bm{\hat{e}}_{i_{1}}\W\dots\W\bm{\hat{e}}_{i_{R}}\rp
+  \end{equation*}
+
+
+are the connection multivectors for the curvilinear coordinate system. For a
+spherical coordinate system they are
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  C\lbrc\bm{\hat{e}}_{r}\rbrc =  \frac{2}{r}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  C\lbrc\bm{\hat{e}}_{\theta}\rbrc =  \frac{\cos\left({\theta}\right)}{r \sin\left({\theta}\right)}
+                                +\frac{1}{r}\bm{\hat{e}}_{r}\W\bm{\hat{e}}_{\theta}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  C\lbrc\bm{\hat{e}}_{\phi}\rbrc = \frac{1}{r}{\bm{\bm{\hat{e}}_{r}}}\W\bm{\hat{e}}_{{\phi}}+ \frac{\cos\left({\theta}\right)}{r \sin\left({\theta}\right)}\bm{\hat{e}}_{{\theta}}\W\bm{\hat{e}}_{{\phi}}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  C\lbrc\hat{e}_{r}\W\hat{e}_{\theta}\rbrc =  - \frac{\cos\left({\theta}\right)}{r \sin\left({\theta}\right)}
+                                        \bm{\hat{e}}_{r}+\frac{1}{r}\bm{\hat{e}}_{{\theta}}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  C\lbrc\bm{\hat{e}}_{r}\W\bm{\hat{e}}_{\phi}\rbrc = \frac{1}{r}\bm{\hat{e}}_{{\phi}}
+                      - \frac{\cos\left({\theta}\right)}{r \sin\left({\theta}\right)}\bm{\hat{e}}_{r}\W\bm{\hat{e}}_{{\theta}}\W\bm{\hat{e}}_{{\phi}}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  C\lbrc\bm{\hat{e}}_{\theta}\W\bm{\hat{e}}_{\phi}\rbrc =  \frac{2}{r}\bm{\hat{e}}_{r}\W
+                                                \bm{\hat{e}}_{\theta}\W\bm{\hat{e}}_{\phi}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  C\lbrc\bm{\hat{e}}_r\W\bm{\hat{e}}_{\theta}\W\bm{\hat{e}}_{\phi}\rbrc = 0
+  \end{equation*}
+
+
+
+Module Components
+=================
+
+
+Initializing Multivector Class
+------------------------------
+
+The multivector class is initialized with:
+
+
+.. function:: MV.setup(basis,metric='',rframe=False,coords=None,debug=False,offset=0)
+
+   The *basis* and *metric* parameters were described in section :ref:`vbm`. If
+   *rframe=True* the  reciprocal frame of the symbolic bases vectors is calculated.
+   If *debug=True* the data structure required to initialize the :class:`MV` class
+   are printer out. *coords* is a list of :class:`sympy` symbols equal in length to
+   the number of basis vectors.  These symbols are used as the arguments of a
+   multivector field as a function of position and for calculating the derivatives
+   of a multivector field (if *coords* is defined then *rframe* is automatically
+   set equal to *True*). *offset* is an integer that is added to the multivector
+   coefficient index. For example if one wishes to start labeling vector coefficient
+   indexes at one instead of zero then set *offset=1*.  Additionally, :func:`MV.setup`
+   calculates the pseudo scalar, :math:`I` and its inverse, :math:`I^{-1}` and makes
+   them available to the programmer as *MV.I* and *MV.Iinv*.
+
+After :func:`MV.setup` is run one can reinialize the :class:`MV` class with
+curvilinear coordinates using:
+
+
+.. function:: MV.rebase(x,coords,base_name,debug=False,debug_level=0)
+
+   A typical usage of ``MV.rebase`` for generating spherical curvilinear coordinate
+   is::
+
+      metric = '1 0 0,0 1 0,0 0 1'
+      MV.setup('gamma_x gamma_y gamma_z',metric,True)
+      coords = make_symbols('r theta phi')
+      x = r*(sympy.cos(theta)*gamma_z+sympy.sin(theta)*\
+          (sympy.cos(phi)*gamma_x+sympy.sin(phi)*gamma_y))
+      x.set_name('x')
+      MV.rebase(x,coords,'e',True)
+
+   The input parameters for ``MV.rebase`` are
+
+*  ``x``: Vector function of coordinates (derivatives define curvilinear basis)
+
+*  ``coords``: List of sympy symbols for curvilinear coordinates
+
+*  ``debug``: If ``True`` printout (LaTeX) all quantities required for derivative calculation
+
+*  ``debug_level``: Set to 0,1,2, or 3 to stop curvilinear calculation before all quatities are
+   calculated.  This is done when debugging new curvilinear coordinate systems since simplification
+   of expressions is not sufficiently automated to insure success of process of any coordinate system
+   defined by vector function ``x``
+
+
+
+   To date ``MV.rebase`` works for cylindrical and spherical coordinate systems in
+   any number of dimensions  (until the execution time becomes too long).  To make
+   it work for these systems required creating some hacks for expression
+   simplification since both trigsimp and simplify were not general enough to
+   perform the required simplification.
+
+
+.. function:: MV.set_str_format(str_mode=0)
+
+   If ``str_mode=0`` the string representation of the multivector contains no
+   newline characters (prints on one line).   If ``str_mode=1`` the string
+   representation of the multivector places a newline after each grade of the
+   multivector  (prints one grade per line).  If ``str_mode=2`` the string
+   representation of the multivector places a newline after each base of the
+   multivector  (prints one base per line). In both cases bases with zero
+   coefficients are not printed.
+
+    .. note::
+
+        This function directly affects the way multivectors are printed with the
+        print command since it interacts with the :func:`__str__` function for the
+        multivector class which is used by the ``print`` command.
+
+
+        .. csv-table::
+            :header: " ``str_mode`` ", " Effect on print "
+            :widths: 10, 50
+
+            " 0 ","One multivector per line"
+            " 1 ","One grade per line"
+            " 2 ","One base per line"
+
+Instantiating a Multivector
+---------------------------
+
+Now that grades and bases have been described we can show all the ways that a
+multivector can be instantiated. As an example assume that the multivector space
+is initialized with ``MV.setup('e1 e2 e3')``. Then the vectors ``e1``, ``e2``,
+and ``e3`` are made available (broadcast) for use in the program .
+
+.. warning::
+
+    This is only true if the statement  ``set_main(sys.modules[__name__])`` appears
+    immediately after the ``from sympy.galgebra.GA import *`` statement.
+
+So that  multivectors
+could be instantiated with statements such as (``a1``, ``a2``, and ``a3`` are
+``sympy`` symbols)::
+
+   x = a1*e1+a2*e2+a3*e3
+   y = x*e1*e2
+   z = x|y
+   w = x^y
+
+or with the multivector class constructor:
+
+
+.. class:: MV(value='',mvtype='',mvname='',fct=False)
+
+   *mvname* is a  string that defines the name of the multivector for output
+   purposes. *value* and  *type* are defined by the following table and *fct* is a
+   switch that will convert the symbolic coefficients of a multivector to functions
+   if coordinate variables have been defined when :func:`MV.setup` is called:
+
+    .. csv-table::
+        :header: " mvtype ", " value ", " result "
+        :widths: 10, 30, 30
+
+        " default ", " default ", " Zero multivector "
+        " 'basisvector' ", " int i ", " :math:`\mbox{i}^{th}` basis vector "
+        " 'basisbivector' ", " int i ", " :math:`\mbox{i}^{th}` basis bivector "
+        " 'scalar' ", " symbol x ", " symbolic scalar of value x"
+        "   ", " string s ", " symbolic scalar of value Symbol(s) "
+        "  ", " int i ", " sympy integer of value i"
+        " 'grade' ", " [int r, 1-D symbol array A] ", " X.grade(r) = A "
+        "   ", " [int r, string s] ", " symbolic grade r multivector "
+        " 'vector' ", " 1-D symbol array A ", " X.grade(1) = A "
+        "   ", " string s ", " symbolic vector "
+        " 'grade2' ", " 1-D symbol array A ", " X.grade(2) = A "
+        " 'pseudo' ", " symbol x ", " X.grade(n) = x "
+        " 'spinor' ", " string s ", " symbolic even multivector "
+
+
+        " default "," string s ", " symbolic general multivector "
+
+
+   If the *value* argument has the option of being a string s then a general symbolic
+   multivector will be constructed constrained by the value of *mvtype*.  The string
+   s will be the base name of the multivector symbolic coefficients.  If *coords* is
+   not defined in :func:`MV.setup` the indices of the multivector bases are appended to
+   the base name with a double underscore (superscript notation).  If *coords* is defined
+   the coordinate names will replace the indices in the coefficient names.  For example if
+   the base string is *A* and the  coordinates *(x,y,z)* then the
+   coefficients of a spinor in 3d space would be *A*, *A__xy*, *A__xz*, and *A__yz*.  If
+   the :mod:`latex_ex` is used to print the multivector the coefficients would print as
+   :math:`A`, :math:`A^{xy}`, :math:`A^{xz}`, and :math:`A^{yz}`.
+
+   If the *fct* argrument of :func:`MV` is set to *True* and the *coords* argument in
+   :func:`MV.setup` is defined the symbolic coefficients of the multivector are functions
+   of the coordinates.
+
+
+Basic Multivector Class Functions
+---------------------------------
+
+
+.. function:: __call__(self,igrade=0,ibase=0)
+
+   ``__call__`` returns the the ``igrade``, ``ibase`` coefficient of the
+   multivector.  The defaults return the scalar component of the multivector.
+
+
+.. function:: convert_to_blades(self)
+
+   Convert multivector from the base representation to the blade representation.
+   If multivector is already in blade representation nothing is done.
+
+
+.. function:: convert_from_blades(self)
+
+   Convert multivector from the blade representation to the base representation.
+   If multivector is already in base representation nothing is done.
+
+
+.. function:: project(self,r)
+
+   If r is a integer return the grade-:math:`r` components of the multivector. If
+   r is a multivector return the grades of the multivector that correspond to the
+   non-zero grades of r. For example if one is projecting a general multivector and
+   r is a spinor, ``A.project(r)`` will return only the even grades of the multivector
+   A since a spinor only has even grades that are non-zero.
+
+
+.. function:: even(self)
+
+   Return the even grade components of the multivector.
+
+
+.. function:: odd(self)
+
+   Return the odd grade components of the multivector.
+
+
+.. function:: rev(self)
+
+   Return the reverse of the multivector.  See section :ref:`reverse`.
+
+
+.. function:: is_pure(self)
+
+   Return true if multivector is pure grade (all grades but one are zero).
+
+
+.. function:: diff(self,x)
+
+   Return the partial derivative of the multivector function with respect to
+   variable :math:`x`.
+
+
+.. function:: grad(self)
+
+   Return the geometric derivative of the multivector function.
+
+
+.. function:: grad_ext(self)
+
+   Return the outer (curl) derivative of the multivector function. Equivalent to
+   :func:`curl`.
+
+
+.. function:: grad_int(self)
+
+   Return the inner (div) derivative of the multivector function. Equivalent to
+   :func:`div`.
+
+.. warning::
+
+    If *A* is a vector field in three dimensions :math:`\nabla\cdot {\bf A}` = A.grad_int() = A.div(), but
+    :math:`\nabla\times {\bf A}` = -MV.I*A.grad_ext() = -MV.I*A.curl(). Note that grad_int() lowers the grade
+    of all blades by one grade and grad_ext() raises the grade of all blades by one.
+
+.. function:: set_coef(self,grade,base,value)
+
+   Set the multivector coefficient of index *(grade,base)* to *value*.
+
+
+Sympy Functions Applied Inplace to Multivector Coefficients
+-----------------------------------------------------------
+
+All the following fuctions belong to the :class:`MV` class and apply the
+corresponding :mod:`sympy` function to each component of a multivector.   All
+these functions perform the operations inplace (``None`` is returned)  on each
+coefficient.  For example if you wished to simplify all the components of the
+multivector ``A`` you would invoke ``A.simplify()``.  The argument list for each
+function is the same as for the corresponding :mod:`sympy` function.   The only
+function that differs in its action from the :mod:`sympy` version is
+:func:`trigsimp` in its case the function ``TrigSimp is applied`` (see
+documentation on :func:`TrigSimp`).
+
+
+.. function:: collect(self,lst)
+
+
+.. function:: sqrfree(self,lst)
+
+
+.. function:: subs(self,*args)
+
+
+.. function:: simplify(self)
+
+
+.. function:: trigsimp(self)
+
+
+.. function:: cancel(self)
+
+
+.. function:: expand(self)
+
+
+Helper Functions
+----------------
+
+These are functions in :mod:`GA`, but not in the multivector (:class:`MV`)
+class.
+
+
+.. function:: set_main(main_program)
+
+   :func:`set_main` passes the argument *main_program* from the main program to the
+   :mod:`GA` module.  The argument must be *sys.modules[__name__]* and the
+   call should be placed immediately after :mod:`sys` and :mod:`GA` are
+   imported.  The purpose of this call is to allow :mod:`GA` to broadcast to
+   the main program :mod:`sympy`  variables and multivectors created by calls to
+   :mod:`GA`. It is used by :func:`MV.setup` and :func:`make_symbols`.
+
+
+.. function:: make_symbols(symnamelst)
+
+   :func:`make_symbols` creates a list of :mod:`sympy` symbols with names defined
+   by the space delimited string *symnamelst*. In addition to returning the symbol
+   list the function broadcasts the named symbols to the main program.  For example
+   if you make the call::
+
+      syms = make_symbols('x y ab')
+
+   Not only will *syms* contain the symbols, but you can also directly use *x*,
+   *y*, and *ab* as symbols in your program.
+
+    .. warning::
+
+        You can only directly use *x*, *y*, and *ab* as symbols in your program if
+        the statement  ``set_main(sys.modules[__name__])`` appears immediately after
+        the ``from sympy.galgebra.GA import *`` statement.
+
+.. function:: set_names(var_lst,var_str)
+
+   :func:`set_names` allows one to name a list, *var_lst*, of multivectors enmass.
+   The names are in *var_str*, a blank separated string of names.  An error is
+   generated if the number of name is not equal to the length of *var_lst*.
+
+
+.. function:: reciprocal_frame(vlst,names='')
+
+   :func:`reciprocal_frame` implements the proceedure described in section
+   :ref:`recframe`.  *vlst* is a list of independent vectors that you wish the
+   reciprocal frame calculated for. *names* is a blank separated string of names
+   for the reciprocal vectors if names are required by you application.  The
+   function returns a list containing the reciprocal vectors.
+
+
+.. function:: TrigSimp(f)
+
+   In general :func:`sympy.trigsimp` will not catch all the trigonometric
+   simplifications in an :mod:`sympy` expression.  Neither will :func:`TrigSimp`,
+   but it will catch a lot more of them. :func:`TrigSimp` is so simple it is show
+   below in its entirety.  All it does is apply  :func:`sympy.trigsimp` to the
+   expressions generated by :func:`sympy.cse`.  ::
+
+      def TrigSimp(f):
+          (w,g) = sympy.cse(f)
+          g = sympy.trigsimp(g[0])
+          for sub in reversed(w):
+              g = g.subs(sub[0],sub[1])
+              g = sympy.trigsimp(g)
+          return(g)
+
+.. function:: S(x)
+
+    :func:`S` instanciates a scaler multivector of value *x*, where *x* can be a
+    :mod:`sympy` variable or integer.  This is just a shorthand method for
+    constructing scalar multivectors and can be used when there is any ambiguity
+    in a multivector expression as to whether a symbol or constant should be
+    treated as a scalar multivector or not.
+
+Examples
+========
+
+
+Algebra
+-------
+
+The following examples of geometric algebra (not calculus) are all in the file
+:program:`testsymbolicGA.py` which is included in the sympy distribution
+examples  under the galbebra directory.  The section of code in the program for
+each example  is show with the respective output following the code section.
+
+
+Example Header
+^^^^^^^^^^^^^^
+
+This is the header of :program:`testsymbolicGA.py` that allows access to the
+required modules and also allow variables and certain multivectors to be
+broadcast from the :mod:`GA` module to the main program.
+
+
+.. include:: headerGAtest.py
+   :literal:
+
+
+Basic Geometric Algebra Operations
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Example of basic geometric algebra operation of geometric, outer, and inner
+products.
+
+
+.. include:: BasicGAtest.py
+   :literal:
+
+
+Examples of Conformal Geometry
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Examples of comformal geometry [Lasenby,Chapter 10]. The examples show that
+basic geometric entities (lines, circles, planes, and spheres) in three
+dimensions can be represented by blades in a five dimensional (conformal) space.
+
+
+.. include:: conformalgeometryGAtest.py
+   :literal:
+
+
+Calculation of Reciprocal Frame
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Example shows the calculation of the reciprocal frame for three arbitrary
+vectors and  verifies that the calculated reciprocal vectors have the correct
+properties.
+
+
+.. include:: reciprocalframeGAtest.py
+   :literal:
+
+
+Hyperbolic Geometry
+^^^^^^^^^^^^^^^^^^^
+
+Examples of calculation of distance in hyperbolic geometry [Lasenby,pp373-375].
+This is a good example of the utility of not restricting the basis vector to be
+orthogonal. Note that most of the calculation is simplifying a scalar
+expression.
+
+
+.. include:: hyperbolicGAtest.py
+   :literal:
+
+
+Calculus
+--------
+
+The calculus examples all use the extened LaTeXoutput module, ``latex_ex``, for
+clarity.
+
+
+Maxwell's Equations
+^^^^^^^^^^^^^^^^^^^
+
+In geometric calculus the equivalent of the electromagnetic tensor is
+:math:`F = E\gamma_{0}+IB\gamma_{0}` where a spacetime vector is given by
+:math:`x = x^{0}\gamma_{0}+x^{1}\gamma_{1}+x^{2}\gamma_{2}+x^{3}\gamma_{3}`
+where :math:`x^{0} = ct`, the pseudoscalar
+:math:`I = \gamma_{0}\gamma_{1}\gamma_{2}\gamma_{3}`, :math:`E` and :math:`B`
+are four vectors where the time component is zero and the spatial components
+equal to the electric and magnetic field  components.  Then Maxwell's equations
+can be all written as :math:`\nabla F = J` with :math:`J` the four current.
+This example shows that this equations generates all of Maxwell's equations
+correctly  (in our units:math:`c=1`) [Lasenby,pp229-231].
+
+``Begin Program Maxwell.py``
+
+
+.. include:: Maxwell.py
+   :literal:
+
+``End Program Maxwell.py``
+
+``Begin 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 Program Output``
+
+
+Dirac's Equation
+^^^^^^^^^^^^^^^^
+
+The geometric algebra/calculus allows one to formulate the Dirac equation in
+real terms (no :math:`\sqrt{-1}`).  Spinors  :math:`\lp\Psi\rp` are even
+multivectors in space time (Minkowski space with signature (1,-1,-1,-1)) and the
+Dirac equation becomes
+:math:`\nabla \Psi I \sigma_{z}-eA\Psi = m\Psi\gamma_{t}`.  All the terms in the
+real equation are explined  in Doran and Lasenby [Lasenby,pp281-283].
+
+``Begin Program Dirac.py``
+
+
+.. include:: Dirac.py
+   :literal:
+
+``End Program Dirac.py``
+
+``Begin Program Output``
+
+:math:`A` is 4-vector potential
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A =  {A^{t}}{\gamma}_{t}+ {A^{x}}{\gamma}_{x}+ {A^{y}}{\gamma}_{y}+ {A^{z}}{\gamma}_{z}
+  \end{equation*}
+
+
+:math:`\bm{\psi}` is 8-component real spinor (even multi-vector)
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  {}\bm{{\psi}} =  {{\psi}}+ {{\psi}^{tx}}{\gamma}_{t}{\gamma}_{x}+ {{\psi}^{ty}}{\gamma}_{t}{\gamma}_{y}+ {{\psi}^{xy}}{\gamma}_{x}{\gamma}_{y}+ {{\psi}^{tz}}{\gamma}_{t}{\gamma}_{z}+ {{\psi}^{xz}}{\gamma}_{x}{\gamma}_{z}+ {{\psi}^{yz}}{\gamma}_{y}{\gamma}_{z}+ {{\psi}^{txyz}}{\gamma}_{t}{\gamma}_{x}{\gamma}_{y}{\gamma}_{z}
+  \end{equation*}
+
+
+Dirac equation in terms of real geometric algebra/calculus
+:math:`\lp\nabla \bm{\psi} I \sigma_{z}-eA\bm{\psi} = m\bm{\psi}\gamma_{t}\rp`
+Spin measured with respect to :math:`z` axis
+
+.. math::
+  :nowrap:
+
+  \begin{align*}
+  \nabla \bm{\psi} I \sigma_{z}-eA\bm{\psi}-m\bm{\psi}\gamma_{t} & =    \left(-e {A^{y}} {{\psi}^{ty}} -m {{\psi}} -\partial_{z} {{\psi}^{txyz}} -\partial_{y} {{\psi}^{tx}} -e {A^{z}} {{\psi}^{tz}} -e {A^{x}} {{\psi}^{tx}} + \partial_{x} {{\psi}^{ty}} -e {A^{t}} {{\psi}} + \partial_{t} {{\psi}^{xy}}\right){\gamma}_{t} \\ & + \left(-e {A^{y}} {{\psi}^{xy}} + \partial_{z} {{\psi}^{yz}} -e {A^{z}} {{\psi}^{xz}} -e {A^{t}} {{\psi}^{tx}} + m {{\psi}^{tx}} -\partial_{x} {{\psi}^{xy}} + \partial_{y} {{\psi}} -e {A^{x}} {{\psi}} -\partial_{t} {{\psi}^{ty}}\right){\gamma}_{x} \\ & + \left(-e {A^{y}} {{\psi}} + e {A^{x}} {{\psi}^{xy}} -e {A^{t}} {{\psi}^{ty}} -\partial_{x} {{\psi}} + \partial_{t} {{\psi}^{tx}} -\partial_{z} {{\psi}^{xz}} -e {A^{z}} {{\psi}^{yz}} + m {{\psi}^{ty}} -\partial_{y} {{\psi}^{xy}}\right){\gamma}_{y} \\ & + \left(-\partial_{z} {{\psi}^{xy}} + e {A^{x}} {{\psi}^{xz}} -e {A^{t}} {{\psi}^{tz}} -\partial_{x} {{\psi}^{yz}} + \partial_{y} {{\psi}^{xz}} + e {A^{y}} {{\psi}^{yz}} + \partial_{t} {{\psi}^{txyz}} + m {{\psi}^{tz}} -e {A^{z}} {{\psi}}\right){\gamma}_{z} \\ & + \left(\partial_{y} {{\psi}^{ty}} -e {A^{y}} {{\psi}^{tx}} + e {A^{x}} {{\psi}^{ty}} + \partial_{z} {{\psi}^{tz}} -e {A^{z}} {{\psi}^{txyz}} + \partial_{x} {{\psi}^{tx}} -e {A^{t}} {{\psi}^{xy}} -\partial_{t} {{\psi}} -m {{\psi}^{xy}}\right){\gamma}_{t}{\gamma}_{x}{\gamma}_{y} \\ & + \left(-\partial_{y} {{\psi}^{tz}} + \partial_{x} {{\psi}^{txyz}} -e {A^{t}} {{\psi}^{xz}} + e {A^{x}} {{\psi}^{tz}} + e {A^{y}} {{\psi}^{txyz}} + \partial_{z} {{\psi}^{ty}} -m {{\psi}^{xz}} -e {A^{z}} {{\psi}^{tx}} -\partial_{t} {{\psi}^{yz}}\right){\gamma}_{t}{\gamma}_{x}{\gamma}_{z} \\ & + \left(-e {A^{t}} {{\psi}^{yz}} -\partial_{z} {{\psi}^{tx}} + \partial_{x} {{\psi}^{tz}} -m {{\psi}^{yz}} + \partial_{y} {{\psi}^{txyz}} + \partial_{t} {{\psi}^{xz}} -e {A^{z}} {{\psi}^{ty}} -e {A^{x}} {{\psi}^{txyz}} + e {A^{y}} {{\psi}^{tz}}\right){\gamma}_{t}{\gamma}_{y}{\gamma}_{z} \\ & + \left(\partial_{z} {{\psi}} + e {A^{y}} {{\psi}^{xz}} + m {{\psi}^{txyz}} -\partial_{t} {{\psi}^{tz}} -\partial_{x} {{\psi}^{xz}} -e {A^{x}} {{\psi}^{yz}} -e {A^{t}} {{\psi}^{txyz}} -\partial_{y} {{\psi}^{yz}} -e {A^{z}} {{\psi}^{xy}}\right){\gamma}_{x}{\gamma}_{y}{\gamma}_{z}\end{align*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+    = 0
+  \end{equation*}
+
+
+``End Program Output``
+
+
+Spherical Coordinates
+^^^^^^^^^^^^^^^^^^^^^
+
+Curvilinear coodinates are implemented as shown in section :ref:`deriv`.  The
+gradient of a scalar function and the divergence and curl of a vector function
+(:math:`-I\lp\nabla\W A\rp` is the curl in three dimensions in the notation of
+geometric algebra) to demonstrate the formulas derived in section :ref:`deriv`.
+
+``Begin Program coords.py``
+
+
+.. include:: coords.py
+   :literal:
+
+``End Program coords.py``
+
+``Begin Program Output``
+
+Gradient of Scalar Function :math:`\psi`
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \nabla\psi =  \partial_{r} {{\psi}}{}\bm{e}_{r}+\frac{1 \partial_{{\theta}} {{\psi}}}{r}{}\bm{e}_{{\theta}}+\frac{1 \partial_{{\phi}} {{\psi}}}{r \operatorname{sin}\left({\theta}\right)}{}\bm{e}_{{\phi}}
+  \end{equation*}
+
+
+Div and Curl of Vector Function :math:`A`
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  A =  {A^{r}}{}\bm{e}_{r}+ {A^{{\theta}}}{}\bm{e}_{{\theta}}+ {A^{{\phi}}}{}\bm{e}_{{\phi}}
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{equation*}
+  \nabla \cdot A =  \left(\frac{{A^{{\theta}}} \operatorname{cos}\left({\theta}\right)}{r \operatorname{sin}\left({\theta}\right)} + 2 \frac{{A^{r}}}{r} + \partial_{r} {A^{r}} + \frac{\partial_{{\theta}} {A^{{\theta}}}}{r} + \frac{\partial_{{\phi}} {A^{{\phi}}}}{r \operatorname{sin}\left({\theta}\right)}\right)
+  \end{equation*}
+
+
+
+
+.. math::
+  :nowrap:
+
+  \begin{align*}
+  -I\lp\nabla \W A\rp & =   \left(\frac{\partial_{{\theta}} {A^{{\phi}}}}{r} + \frac{{A^{{\phi}}} \operatorname{cos}\left({\theta}\right)}{r \operatorname{sin}\left({\theta}\right)} -\frac{\partial_{{\phi}} {A^{{\theta}}}}{r \operatorname{sin}\left({\theta}\right)}\right){}\bm{e}_{r} \\ & - \left(\frac{{A^{{\phi}}}}{r} + \partial_{r} {A^{{\phi}}} -\frac{\partial_{{\phi}} {A^{r}}}{r \operatorname{sin}\left({\theta}\right)}\right){}\bm{e}_{{\theta}} \\ & + \left(\frac{{A^{{\theta}}}}{r} + \partial_{r} {A^{{\theta}}} -\frac{\partial_{{\theta}} {A^{r}}}{r}\right){}\bm{e}_{{\phi}}\end{align*}
+
+
+``End Program Output``
+
+
+.. seealso::
+
+   `Hestenes <http://geocalc.clas.asu.edu/html/CA_to_GC.html>`_
+      ``Clifford Algebra to Geometric Calculus`` by  D.Hestenes and G. Sobczyk, Kluwer
+      Academic Publishers, 1984.
+
+   `Lasenby <http://www.mrao.cam.ac.uk/~cjld1/pages/book.htm>`_
+      ``Geometric Algebra for Physicists`` by  C. Doran and A. Lasenby, Cambridge
+      University Press, 2003.
+
+
diff --git a/lib/sympy/doc/src/modules/galgebra/GA/Maxwell.py b/lib/sympy/doc/src/modules/galgebra/GA/Maxwell.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/GA/Maxwell.py
@@ -0,0 +1,57 @@
+
+from sympy import *
+from sympy.galgebra.GA import *
+from sympy.galgebra.latex_ex import *
+
+set_main(sys.modules[__name__])
+
+if __name__ == '__main__':
+    
+    metric = '1  0  0  0,'+\
+             '0 -1  0  0,'+\
+             '0  0 -1  0,'+\
+             '0  0  0 -1'
+
+    vars = make_symbols('t x y z')
+    MV.setup('gamma_t gamma_x gamma_y gamma_z',metric,True,vars)
+    LatexPrinter.format(1,1,1,1)
+    I = MV(1,'pseudo')
+    print '$I$ Pseudo-Scalar'
+    print 'I =',I
+    B = MV('B','vector',fct=True)
+    E = MV('E','vector',fct=True)
+    B.set_coef(1,0,0)
+    E.set_coef(1,0,0)
+    B *= gamma_t
+    E *= gamma_t
+    J = MV('J','vector',fct=True)
+    F = E+I*B
+    print ' '
+    print '$B$ Magnetic Field Bi-Vector'
+    print 'B = Bvec gamma_0 =',B
+    print '$F$ Electric Field Bi-Vector'
+    print 'E = Evec gamma_0 =',E
+    print '$E+IB$ Electo-Magnetic Field Bi-Vector'
+    print 'F = E+IB =',F
+    print '$J$ Four Current'
+    print 'J =',J
+    gradF = F.grad()
+    print 'Geometric Derivative of Electo-Magnetic Field Bi-Vector'
+    MV_format(3)
+    print '\\nabla F =',gradF
+    print 'All Maxwell Equations are'
+    print '\\nabla F = J'
+    print 'Div $E$ and Curl $H$ Equations'
+    print '<\\nabla F>_1 -J =',gradF.project(1)-J,' = 0'
+    print 'Curl $E$ and Div $B$ equations'
+    print '<\\nabla F>_3 =',gradF.project(3),' = 0'
+    xdvi(filename='Maxwell.tex')
+
+
+
+
+
+
+
+
+
diff --git a/lib/sympy/doc/src/modules/galgebra/GA/conformalgeometryGAtest.py b/lib/sympy/doc/src/modules/galgebra/GA/conformalgeometryGAtest.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/GA/conformalgeometryGAtest.py
@@ -0,0 +1,46 @@
+        print '\nExample: Conformal representations of circles, lines, spheres, and planes'
+
+        metric = '1 0 0 0 0,0 1 0 0 0,0 0 1 0 0,0 0 0 0 2,0 0 0 2 0'
+
+        MV.setup('e0 e1 e2 n nbar',metric,debug=0)
+        MV.set_str_format(1)
+        e = n+nbar
+        #conformal representation of points
+
+        A = make_vector(e0)    # point a = (1,0,0)  A = F(a)
+        B = make_vector(e1)    # point b = (0,1,0)  B = F(b)
+        C = make_vector(-1*e0) # point c = (-1,0,0) C = F(c)
+        D = make_vector(e2)    # point d = (0,0,1)  D = F(d)
+        X = make_vector('x',3)
+
+        print 'a = e0, b = e1, c = -e0, and d = e2'
+        print 'A = F(a) = 1/2*(a*a*n+2*a-nbar), etc.'
+        print 'Circle through a, b, and c'
+        print 'Circle: A^B^C^X = 0 =',(A^B^C^X)
+        print 'Line through a and b'
+        print 'Line  : A^B^n^X = 0 =',(A^B^n^X)
+        print 'Sphere through a, b, c, and d'
+        print 'Sphere: A^B^C^D^X = 0 =',(A^B^C^D^X)
+        print 'Plane through a, b, and d'
+        print 'Plane : A^B^n^D^X = 0 =',(A^B^n^D^X)
+
+Example: Conformal representations of circles, lines, spheres, and planes
+a = e0, b = e1, c = -e0, and d = e2
+A = F(a) = 1/2*(a*a*n+2*a-nbar), etc.
+Circle through a, b, and c
+Circle: A^B^C^X = 0 = {-x2}e0^e1^e2^n
++{x2}e0^e1^e2^nbar
++{-1/2 + 1/2*x0**2 + 1/2*x1**2 + 1/2*x2**2}e0^e1^n^nbar
+
+Line through a and b
+Line  : A^B^n^X = 0 = {-x2}e0^e1^e2^n
++{-1/2 + x0/2 + x1/2}e0^e1^n^nbar
++{x2/2}e0^e2^n^nbar
++{-x2/2}e1^e2^n^nbar
+
+Sphere through a, b, c, and d
+Sphere: A^B^C^D^X = 0 = {1/2 - 1/2*x0**2 - 1/2*x1**2 - 1/2*x2**2}e0^e1^e2^n^nbar
+
+Plane through a, b, and d
+Plane : A^B^n^D^X = 0 = {1/2 - x0/2 - x1/2 - x2/2}e0^e1^e2^n^nbar
+
diff --git a/lib/sympy/doc/src/modules/galgebra/GA/coords.py b/lib/sympy/doc/src/modules/galgebra/GA/coords.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/GA/coords.py
@@ -0,0 +1,48 @@
+#!/usrlocal/bin/python
+#EandM.py
+
+from sympy.galgebra.GA import *
+from sympy.galgebra.latex_ex import *
+from sympy import *
+
+import sympy,numpy,sys
+
+set_main(sys.modules[__name__])
+
+if __name__ == '__main__':
+    metric = '1 0 0,'+\
+             '0 1 0,'+\
+             '0 0 1'
+
+    MV.setup('gamma_x gamma_y gamma_z',metric,True)
+    Format('1 1 1 1')
+
+    coords = make_symbols('r theta phi')
+    x = r*(sympy.cos(theta)*gamma_z+sympy.sin(theta)*\
+        (sympy.cos(phi)*gamma_x+sympy.sin(phi)*gamma_y))
+    x.set_name('x')
+
+    MV.rebase(x,coords,'e',False)
+
+    #psi = MV.scalar_fct('psi')
+    psi = MV('psi','scalar',fct=True)
+    #psi.name = 'psi'
+    dpsi = psi.grad()
+    print 'Gradient of Scalar Function $\\psi$'
+    print '\\nabla\\psi =',dpsi
+    
+    #A = MV.vector_fct('A')
+    A = MV('A','vector',fct=True)
+    #A.name = 'A'
+    print 'Div and Curl of Vector Function $A$'
+    print A
+        
+    gradA = A.grad()
+    I = MV(ONE,'pseudo')
+    divA = A.grad_int()
+    curlA = -I*A.grad_ext()
+    print '\\nabla \\cdot A =',divA
+    Format('mv=3')
+    print '-I\\lp\\nabla \\W A\\rp =',curlA
+    
+    xdvi(filename='coords.tex')
diff --git a/lib/sympy/doc/src/modules/galgebra/GA/headerGAtest.py b/lib/sympy/doc/src/modules/galgebra/GA/headerGAtest.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/GA/headerGAtest.py
@@ -0,0 +1,24 @@
+import os,sys,sympy
+from sympy.galgebra.GA import set_main, make_symbols, types, MV, ZERO, ONE, HALF
+from sympy import collect
+set_main(sys.modules[__name__])
+
+def F(x):
+        """
+        Conformal Mapping Function
+        """
+        Fx = HALF*((x*x)*n+2*x-nbar)
+        return(Fx)
+
+def make_vector(a,n = 3):
+        if type(a) == types.StringType:
+                sym_str = ''
+                for i in range(n):
+                        sym_str += a+str(i)+' '
+                sym_lst = make_symbols(sym_str)
+                sym_lst.append(ZERO)
+                sym_lst.append(ZERO)
+                a = MV(sym_lst,'vector')
+        return(F(a))
+
+if __name__ == '__main__':
diff --git a/lib/sympy/doc/src/modules/galgebra/GA/hyperbolicGAtest.py b/lib/sympy/doc/src/modules/galgebra/GA/hyperbolicGAtest.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/GA/hyperbolicGAtest.py
@@ -0,0 +1,141 @@
+        print 'Example: non-euclidian distance calculation'
+
+        metric = '0 # #,# 0 #,# # 1'
+        MV.setup('X Y e',metric)
+        MV.set_str_format(1)
+        L = X^Y^e
+        B = L*e
+        Bsq = (B*B)()
+        print 'L = X^Y^e is a non-euclidian line'
+        print 'B = L*e =',B
+        BeBr =B*e*B.rev()
+        print 'B*e*B.rev() =',BeBr
+        print 'B^2 =',Bsq
+        print 'L^2 =',(L*L)()
+        make_symbols('s c Binv M S C alpha')
+        Bhat = Binv*B # Normalize translation generator
+        R = c+s*Bhat # Rotor R = exp(alpha*Bhat/2)
+        print 's = sinh(alpha/2) and c = cosh(alpha/2)'
+        print 'R = exp(alpha*B/(2*|B|)) =',R
+        Z = R*X*R.rev()
+        Z.expand()
+        Z.collect([Binv,s,c,XdotY])
+        print 'R*X*R.rev() =',Z
+        W = Z|Y
+        W.expand()
+        W.collect([s*Binv])
+        print '(R*X*rev(R)).Y =',W
+        M = 1/Bsq
+        W.subs(Binv**2,M)
+        W.simplify()
+        Bmag = sympy.sqrt(XdotY**2-2*XdotY*Xdote*Ydote)
+        W.collect([Binv*c*s,XdotY])
+
+        W.subs(2*XdotY**2-4*XdotY*Xdote*Ydote,2/(Binv**2))
+        W.subs(2*c*s,S)
+        W.subs(c**2,(C+1)/2)
+        W.subs(s**2,(C-1)/2)
+        W.simplify()
+        W.subs(1/Binv,Bmag)
+        W = W().expand()
+        print '(R*X*R.rev()).Y =',W
+        nl = '\n'
+
+        Wd = collect(W,[C,S],exact=True,evaluate=False)
+        print 'Wd =',Wd
+        Wd_1 = Wd[ONE]
+        Wd_C = Wd[C]
+        Wd_S = Wd[S]
+        print '|B| =',Bmag
+        Wd_1 = Wd_1.subs(Bmag,1/Binv)
+        Wd_C = Wd_C.subs(Bmag,1/Binv)
+        Wd_S = Wd_S.subs(Bmag,1/Binv)
+        print 'Wd[ONE] =',Wd_1
+        print 'Wd[C] =',Wd_C
+        print 'Wd[S] =',Wd_S
+
+
+        lhs = Wd_1+Wd_C*C
+        rhs = -Wd_S*S
+        lhs = lhs**2
+        rhs = rhs**2
+        W = (lhs-rhs).expand()
+        W = (W.subs(1/Binv**2,Bmag**2)).expand()
+        print 'W =',W
+        W = (W.subs(S**2,C**2-1)).expand()
+        print 'W =',W
+        W = collect(W,[C,C**2],evaluate=False)
+        print 'W =',W
+        
+        a = W[C**2]
+        b = W[C]
+        c = W[ONE]
+
+        print 'a =',a
+        print 'b =',b
+        print 'c =',c
+
+        D = (b**2-4*a*c).expand()
+        print 'Setting to 0 and solving for C gives:'
+        print 'Descriminant D = b^2-4*a*c =',D
+        C = (-b/(2*a)).expand()
+        print 'C = cosh(alpha) = -b/(2*a) =',C
+
+Example: non-euclidian distance calculation
+L = X^Y^e is a non-euclidian line
+B = L*e = X^Y
++{-(Y.e)}X^e
++{(X.e)}Y^e
+
+B*e*B.rev() = {2*(X.Y)*(X.e)*(Y.e) - (X.Y)**2}e
+
+B^2 = -2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2
+L^2 = -2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2
+s = sinh(alpha/2) and c = cosh(alpha/2)
+R = exp(alpha*B/(2*|B|)) = {c}1
++{Binv*s}X^Y
++{-(Y.e)*Binv*s}X^e
++{(X.e)*Binv*s}Y^e
+
+R*X*R.rev() = {Binv*(2*(X.Y)*c*s - 2*(X.e)*(Y.e)*c*s) + Binv**2*((X.Y)**2*s**2 
+               - 2*(X.Y)*(X.e)*(Y.e)*s**2) + c**2}X
+             +{2*Binv*c*s*(X.e)**2}Y
+             +{Binv**2*(-2*(X.e)*(X.Y)**2*s**2 + 4*(X.Y)*(Y.e)*(X.e)**2*s**2)
+               - 2*(X.Y)*(X.e)*Binv*c*s}e
+
+(R*X*rev(R)).Y = {Binv*s*(-4*(X.Y)*(X.e)*(Y.e)*c + 2*c*(X.Y)**2) 
+                 + Binv**2*s**2*(-4*(X.e)*(Y.e)*(X.Y)**2 +
+                 4*(X.Y)*(X.e)**2*(Y.e)**2 + (X.Y)**3) + (X.Y)*c**2}1
+
+(R*X*R.rev()).Y = S*(-2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2)**(1/2) 
+                  + (X.Y)*Binv*C*(-2*(X.Y)*(X.e)*(Y.e) + 
+                  (X.Y)**2)**(1/2) + (X.e)*(Y.e)*Binv*(-2*(X.Y)*(X.e)*(Y.e) 
+                  + (X.Y)**2)**(1/2) - 
+                  (X.e)*(Y.e)*Binv*C*(-2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2)**(1/2)
+Wd = {1: (X.e)*(Y.e)*Binv*(-2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2)**(1/2),
+      S: (-2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2)**(1/2),
+      C: (X.Y)*Binv*(-2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2)**(1/2) - 
+         (X.e)*(Y.e)*Binv*(-2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2)**(1/2)}
+|B| = (-2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2)**(1/2)
+
+Wd[ONE] = (X.e)*(Y.e)
+Wd[C] = (X.Y) - (X.e)*(Y.e)
+Wd[S] = 1/Binv
+
+W = 2*(X.Y)*(X.e)*(Y.e)*C + (X.Y)**2*C**2 + (X.e)**2*(Y.e)**2 
+    - (X.Y)**2*S**2 + (X.e)**2*(Y.e)**2*C**2 - 2*C*(X.e)**2*(Y.e)**2 
+    - 2*(X.Y)*(X.e)*(Y.e)*C**2 + 2*(X.Y)*(X.e)*(Y.e)*S**2
+W = -2*(X.Y)*(X.e)*(Y.e) + 2*(X.Y)*(X.e)*(Y.e)*C + (X.Y)**2 
+    + (X.e)**2*(Y.e)**2 + (X.e)**2*(Y.e)**2*C**2 -
+     2*C*(X.e)**2*(Y.e)**2
+W = {1: -2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2 + (X.e)**2*(Y.e)**2,
+     C**2: (X.e)**2*(Y.e)**2,
+     C: 2*(X.Y)*(X.e)*(Y.e) - 2*(X.e)**2*(Y.e)**2}
+
+a = (X.e)**2*(Y.e)**2
+b = 2*(X.Y)*(X.e)*(Y.e) - 2*(X.e)**2*(Y.e)**2
+c = -2*(X.Y)*(X.e)*(Y.e) + (X.Y)**2 + (X.e)**2*(Y.e)**2
+
+Setting to 0 and solving for C gives:
+Descriminant D = b^2-4*a*c = 0
+C = cosh(alpha) = -b/(2*a) = 1 - (X.Y)/((X.e)*(Y.e))
diff --git a/lib/sympy/doc/src/modules/galgebra/GA/multable.dat b/lib/sympy/doc/src/modules/galgebra/GA/multable.dat
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/GA/multable.dat
@@ -0,0 +1,75 @@
+(1)(1) = 1
+(1)(a0) = a0
+(1)(a1) = a1
+(1)(a2) = a2
+(1)(a0a1) = a0a1
+(1)(a0a2) = a0a2
+(1)(a1a2) = a1a2
+(1)(a0a1a2) = a0a1a2
+
+(a0)(1) = a0
+(a0)(a0) = {a0**2}1
+(a0)(a1) = a0a1
+(a0)(a2) = a0a2
+(a0)(a0a1) = {a0**2}a1
+(a0)(a0a2) = {a0**2}a2
+(a0)(a1a2) = a0a1a2
+(a0)(a0a1a2) = {a0**2}a1a2
+
+(a1)(1) = a1
+(a1)(a0) = {2*(a0.a1)}1-a0a1
+(a1)(a1) = {a1**2}1
+(a1)(a2) = a1a2
+(a1)(a0a1) = {-a1**2}a0+{2*(a0.a1)}a1
+(a1)(a0a2) = {2*(a0.a1)}a2-a0a1a2
+(a1)(a1a2) = {a1**2}a2
+(a1)(a0a1a2) = {-a1**2}a0a2+{2*(a0.a1)}a1a2
+
+(a2)(1) = a2
+(a2)(a0) = {2*(a0.a2)}1-a0a2
+(a2)(a1) = {2*(a1.a2)}1-a1a2
+(a2)(a2) = {a2**2}1
+(a2)(a0a1) = {-2*(a1.a2)}a0+{2*(a0.a2)}a1+a0a1a2
+(a2)(a0a2) = {-a2**2}a0+{2*(a0.a2)}a2
+(a2)(a1a2) = {-a2**2}a1+{2*(a1.a2)}a2
+(a2)(a0a1a2) = {a2**2}a0a1+{-2*(a1.a2)}a0a2+{2*(a0.a2)}a1a2
+
+(a0a1)(1) = a0a1
+(a0a1)(a0) = {2*(a0.a1)}a0+{-a0**2}a1
+(a0a1)(a1) = {a1**2}a0
+(a0a1)(a2) = a0a1a2
+(a0a1)(a0a1) = {-a0**2*a1**2}1+{2*(a0.a1)}a0a1
+(a0a1)(a0a2) = {2*(a0.a1)}a0a2+{-a0**2}a1a2
+(a0a1)(a1a2) = {a1**2}a0a2
+(a0a1)(a0a1a2) = {-a0**2*a1**2}a2+{2*(a0.a1)}a0a1a2
+
+(a0a2)(1) = a0a2
+(a0a2)(a0) = {2*(a0.a2)}a0+{-a0**2}a2
+(a0a2)(a1) = {2*(a1.a2)}a0-a0a1a2
+(a0a2)(a2) = {a2**2}a0
+(a0a2)(a0a1) = {-2*a0**2*(a1.a2)}1+{2*(a0.a2)}a0a1+{a0**2}a1a2
+(a0a2)(a0a2) = {-a0**2*a2**2}1+{2*(a0.a2)}a0a2
+(a0a2)(a1a2) = {-a2**2}a0a1+{2*(a1.a2)}a0a2
+(a0a2)(a0a1a2) = {a0**2*a2**2}a1+{-2*a0**2*(a1.a2)}a2+{2*(a0.a2)}a0a1a2
+
+(a1a2)(1) = a1a2
+(a1a2)(a0) = {2*(a0.a2)}a1+{-2*(a0.a1)}a2+a0a1a2
+(a1a2)(a1) = {2*(a1.a2)}a1+{-a1**2}a2
+(a1a2)(a2) = {a2**2}a1
+(a1a2)(a0a1) = {2*a1**2*(a0.a2)-4*(a0.a1)*(a1.a2)}1+{2*(a1.a2)}a0a1+{-a1**2}a0a2
+              +{2*(a0.a1)}a1a2
+(a1a2)(a0a2) = {-2*a2**2*(a0.a1)}1+{a2**2}a0a1+{2*(a0.a2)}a1a2
+(a1a2)(a1a2) = {-a1**2*a2**2}1+{2*(a1.a2)}a1a2
+(a1a2)(a0a1a2) = {-a1**2*a2**2}a0+{2*a2**2*(a0.a1)}a1+{2*a1**2*(a0.a2)
+                -4*(a0.a1)*(a1.a2)}a2+{2*(a1.a2)}a0a1a2
+
+(a0a1a2)(1) = a0a1a2
+(a0a1a2)(a0) = {2*(a0.a2)}a0a1+{-2*(a0.a1)}a0a2+{a0**2}a1a2
+(a0a1a2)(a1) = {2*(a1.a2)}a0a1+{-a1**2}a0a2
+(a0a1a2)(a2) = {a2**2}a0a1
+(a0a1a2)(a0a1) = {2*a1**2*(a0.a2)-4*(a0.a1)*(a1.a2)}a0+{2*a0**2*(a1.a2)}a1
+                +{-a0**2*a1**2}a2+{2*(a0.a1)}a0a1a2
+(a0a1a2)(a0a2) = {-2*a2**2*(a0.a1)}a0+{a0**2*a2**2}a1+{2*(a0.a2)}a0a1a2
+(a0a1a2)(a1a2) = {-a1**2*a2**2}a0+{2*(a1.a2)}a0a1a2
+(a0a1a2)(a0a1a2) = {-a0**2*a1**2*a2**2}1+{2*a2**2*(a0.a1)}a0a1+{2*a1**2*(a0.a2)
+                  -4*(a0.a1)*(a1.a2)}a0a2+{2*a0**2*(a1.a2)}a1a2
\ No newline at end of file
diff --git a/lib/sympy/doc/src/modules/galgebra/GA/reciprocalframeGAtest.py b/lib/sympy/doc/src/modules/galgebra/GA/reciprocalframeGAtest.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/GA/reciprocalframeGAtest.py
@@ -0,0 +1,79 @@
+        MV.setup('e1 e2 e3',metric)
+
+        print 'Example: Reciprocal Frames e1, e2, and e3 unit vectors.\n\n'
+
+        E = e1^e2^e3
+        Esq = (E*E)()
+        print 'E =',E
+        print 'E^2 =',Esq
+        Esq_inv = 1/Esq
+
+        E1 = (e2^e3)*E
+        E2 = (-1)*(e1^e3)*E
+        E3 = (e1^e2)*E
+
+        print 'E1 = (e2^e3)*E =',E1
+        print 'E2 =-(e1^e3)*E =',E2
+        print 'E3 = (e1^e2)*E =',E3
+
+        w = (E1|e2)
+        w.collect(MV.g)
+        w = w().expand()
+        print 'E1|e2 =',w
+
+        w = (E1|e3)
+        w.collect(MV.g)
+        w = w().expand()
+        print 'E1|e3 =',w
+
+        w = (E2|e1)
+        w.collect(MV.g)
+        w = w().expand()
+        print 'E2|e1 =',w
+
+        w = (E2|e3)
+        w.collect(MV.g)
+        w = w().expand()
+        print 'E2|e3 =',w
+
+        w = (E3|e1)
+        w.collect(MV.g)
+        w = w().expand()
+        print 'E3|e1 =',w
+
+        w = (E3|e2)
+        w.collect(MV.g)
+        w = w().expand()
+        print 'E3|e2 =',w
+
+        w = (E1|e1)
+        w = w().expand()
+        Esq = Esq.expand()
+        print '(E1|e1)/E^2 =',w/Esq
+
+        w = (E2|e2)
+        w = w().expand()
+        print '(E2|e2)/E^2 =',w/Esq
+
+        w = (E3|e3)
+        w = w().expand()
+        print '(E3|e3)/E^2 =',w/Esq
+
+Example: Reciprocal Frames e1, e2, and e3 unit vectors.
+
+
+E = e1^e2^e3
+E^2 = -1 - 2*(e1.e2)*(e1.e3)*(e2.e3) + (e1.e2)**2 + (e1.e3)**2 + (e2.e3)**2
+E1 = (e2^e3)*E = {-1 + (e2.e3)**2}e1+{(e1.e2) - (e1.e3)*(e2.e3)}e2+{(e1.e3) - (e1.e2)*(e2.e3)}e3
+E2 =-(e1^e3)*E = {(e1.e2) - (e1.e3)*(e2.e3)}e1+{-1 + (e1.e3)**2}e2+{(e2.e3) - (e1.e2)*(e1.e3)}e3
+E3 = (e1^e2)*E = {(e1.e3) - (e1.e2)*(e2.e3)}e1+{(e2.e3) - (e1.e2)*(e1.e3)}e2+{-1 + (e1.e2)**2}e3
+E1|e2 = 0
+E1|e3 = 0
+E2|e1 = 0
+E2|e3 = 0
+E3|e1 = 0
+E3|e2 = 0
+(E1|e1)/E^2 = 1
+(E2|e2)/E^2 = 1
+(E3|e3)/E^2 = 1
+
diff --git a/lib/sympy/doc/src/modules/galgebra/latex_ex/Maxwell.py b/lib/sympy/doc/src/modules/galgebra/latex_ex/Maxwell.py
new file mode 100755
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/latex_ex/Maxwell.py
@@ -0,0 +1,50 @@
+import sys
+import sympy.galgebra.GAsympy as GA
+import sympy.galgebra.latex_ex as tex
+
+GA.set_main(sys.modules[__name__])
+
+if __name__ == '__main__':
+
+    metric = '1  0  0  0,'+\
+             '0 -1  0  0,'+\
+             '0  0 -1  0,'+\
+             '0  0  0 -1'
+
+    vars = GA.make_symbols('t x y z')
+    GA.MV.setup('gamma_t gamma_x gamma_y gamma_z',metric,True,vars)
+    tex.Format()
+    I = GA.MV(1,'pseudo')
+    I.convert_to_blades()
+    print '$I$ Pseudo-Scalar'
+    print 'I =',I
+    B = GA.MV('B','vector',fct=True)
+    E = GA.MV('E','vector',fct=True)
+    B.set_coef(1,0,0)
+    E.set_coef(1,0,0)
+    B *= gamma_t
+    E *= gamma_t
+    B.convert_to_blades()
+    E.convert_to_blades()
+    J = GA.MV('J','vector',fct=True)
+    print '$B$ Magnetic Field Bi-Vector'
+    print 'B = Bvec gamma_0 =',B
+    print '$E$ Electric Field Bi-Vector'
+    print 'E = Evec gamma_0 =',E
+    F = E+I*B
+    print '$E+IB$ Electo-Magnetic Field Bi-Vector'
+    print 'F = E+IB =',F
+    print '$J$ Four Current'
+    print 'J =',J
+    gradF = F.grad()
+    gradF.convert_to_blades()
+    print 'Geometric Derivative of Electo-Magnetic Field Bi-Vector'
+    tex.MV_format(3)
+    print '\\nabla F =',gradF
+    print 'All Maxwell Equations are'
+    print '\\nabla F = J'
+    print 'Div $E$ and Curl $H$ Equations'
+    print '<\\nabla F>_1 -J =',gradF.project(1)-J,' = 0'
+    print 'Curl $E$ and Div $B$ equations'
+    print '<\\nabla F>_3 =',gradF.project(3),' = 0'
+    tex.xdvi(filename='Maxwell.tex')
diff --git a/lib/sympy/doc/src/modules/galgebra/latex_ex/latex_ex.txt b/lib/sympy/doc/src/modules/galgebra/latex_ex/latex_ex.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/latex_ex/latex_ex.txt
@@ -0,0 +1,425 @@
+.. _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.
+
+.. math ::
+
+    \newcommand{\W}{\wedge}
+    \newcommand{\bm}{\boldsymbol}
+
+.. 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.
+
diff --git a/lib/sympy/doc/src/modules/galgebra/latex_ex/latexdemo.py b/lib/sympy/doc/src/modules/galgebra/latex_ex/latexdemo.py
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/galgebra/latex_ex/latexdemo.py
@@ -0,0 +1,16 @@
+import sys
+import sympy.galgebra.GA as GA
+import sympy.galgebra.latex_ex as tex
+
+GA.set_main(sys.modules[__name__])
+
+if __name__ == '__main__':
+
+    tex.Format()
+    GA.make_symbols('xbm alpha_1 delta__nugamma_r')
+    
+    x = alpha_1*xbm/delta__nugamma_r
+    
+    print 'x =',x
+    
+    tex.xdvi()
diff --git a/lib/sympy/doc/src/modules/geometry.txt b/lib/sympy/doc/src/modules/geometry.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/geometry.txt
@@ -0,0 +1,190 @@
+Geometry Module
+===============
+
+.. module:: sympy.geometry
+
+Introduction
+------------
+
+The geometry module for SymPy allows one to create two-dimensional geometrical
+entities, such as lines and circles, and query information about these
+entities. This could include asking the area of an ellipse, checking for
+collinearity of a set of points, or finding the intersection between two lines.
+The primary use case of the module involves entities with numerical values, but
+it is possible to also use symbolic representations.
+
+Available Entities
+------------------
+
+The following entities are currently available in the geometry module:
+
+* Point
+* Line, Ray, Segment
+* Ellipse, Circle
+* Polygon, RegularPolygon, Triangle
+
+Most of the work one will do will be through the properties and methods of
+these entities, but several global methods exist for one's usage:
+
+* intersection(entity1, entity2)
+* are_similar(entity1, entity2)
+* convex_hull(points)
+
+For a full API listing and an explanation of the methods and their return
+values please see the list of classes at the end of this document.
+
+Example Usage
+-------------
+
+The following Python session gives one an idea of how to work with some of the
+geometry module.
+
+    >>> from sympy import *
+    >>> from sympy.geometry import *
+    >>> x = Point(0, 0)
+    >>> y = Point(1, 1)
+    >>> z = Point(2, 2)
+    >>> zp = Point(1, 0)
+    >>> Point.is_collinear(x, y, z)
+    True
+    >>> Point.is_collinear(x, y, zp)
+    False
+    >>> t = Triangle(zp, y, x)
+    >>> t.area
+    1/2
+    >>> t.medians[x]
+    Segment(Point(0, 0), Point(1, 1/2))
+    >>> Segment(Point(1, S(1)/2), Point(0, 0))
+    Segment(Point(0, 0), Point(1, 1/2))
+    >>> m = t.medians
+    >>> intersection(m[x], m[y], m[zp])
+    [Point(2/3, 1/3)]
+    >>> c = Circle(x, 5)
+    >>> l = Line(Point(5, -5), Point(5, 5))
+    >>> c.is_tangent(l) # is l tangent to c?
+    True
+    >>> l = Line(x, y)
+    >>> c.is_tangent(l) # is l tangent to c?
+    False
+    >>> intersection(c, l)
+    [Point(-5*sqrt(2)/2, -5*sqrt(2)/2), Point(5*sqrt(2)/2, 5*sqrt(2)/2)]
+
+Intersection of medians
+-----------------------
+::
+
+    >>> from sympy import Symbol
+    >>> from sympy.geometry import Point, Triangle, intersection
+
+    >>> a = Symbol("a")
+    >>> b = Symbol("b")
+    >>> c = Symbol("c")
+
+    >>> x = Point(0,0)
+    >>> y = Point(c,0)
+    >>> z = Point(a,b)
+    >>> t = Triangle(x,y,z)
+
+    >>> t.area
+    b*c/2
+
+    >>> t.medians #doctest: +NORMALIZE_WHITESPACE
+    {Point(a, b): Segment(Point(a, b), Point(c/2, 0)),
+    Point(c, 0): Segment(Point(c, 0), Point(a/2, b/2)),
+    Point(0, 0): Segment(Point(0, 0), Point(a/2 + c/2, b/2))}
+
+    >>> intersection(t.medians[x], t.medians[y], t.medians[z])
+    [Point(a/3 + c/3, b/3)]
+
+An in-depth example: Pappus' Theorem
+------------------------------------
+::
+
+    >>> from sympy import *
+    >>> from sympy.geometry import *
+    >>>
+    >>> l1 = Line(Point(0, 0), Point(5, 6))
+    >>> l2 = Line(Point(0, 0), Point(2, -2))
+    >>>
+    >>> def subs_point(l, val):
+    ...    """Take an arbitrary point and make it a fixed point."""
+    ...    t = Symbol('t', real=True)
+    ...    ap = l.arbitrary_point()
+    ...    return Point(ap[0].subs(t, val), ap[1].subs(t, val))
+    ...
+    >>> p11 = subs_point(l1, 5)
+    >>> p12 = subs_point(l1, 6)
+    >>> p13 = subs_point(l1, 11)
+    >>>
+    >>> p21 = subs_point(l2, -1)
+    >>> p22 = subs_point(l2, 2)
+    >>> p23 = subs_point(l2, 13)
+    >>>
+    >>> ll1 = Line(p11, p22)
+    >>> ll2 = Line(p11, p23)
+    >>> ll3 = Line(p12, p21)
+    >>> ll4 = Line(p12, p23)
+    >>> ll5 = Line(p13, p21)
+    >>> ll6 = Line(p13, p22)
+    >>>
+    >>> pp1 = intersection(ll1, ll3)[0]
+    >>> pp2 = intersection(ll2, ll5)[0]
+    >>> pp3 = intersection(ll4, ll6)[0]
+    >>>
+    >>> print Point.is_collinear(pp1, pp2, pp3)
+    True
+
+Miscellaneous Notes
+-------------------
+
+* The area property of Polygon and Triangle may return a positive or
+  negative value, depending on whether or not the points are oriented
+  counter-clockwise or clockwise, respectively. If you always want a
+  positive value be sure to use the ``abs`` function.
+* Although Polygon can refer to any type of polygon, the code has been
+  written for simple polygons. Hence, expect potential problems if dealing
+  with complex polygons (overlapping sides).
+* Since !SymPy is still in its infancy some things may not simplify
+  properly and hence some things that should return True (e.g.,
+  Point.is_collinear) may not actually do so. Similarly, attempting to find
+  the intersection of entities that do intersect may result in an empty
+  result.
+
+Future Work
+-----------
+
+Truth Setting Expressions
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When one deals with symbolic entities, it often happens that an assertion
+cannot be guaranteed. For example, consider the following code:
+
+    >>> from sympy import *
+    >>> from sympy.geometry import *
+    >>> x,y,z = map(Symbol, 'xyz')
+    >>> p1,p2,p3 = Point(x, y), Point(y, z), Point(2*x*y, y)
+    >>> Point.is_collinear(p1, p2, p3)
+    False
+
+Even though the result is currently ``False``, this is not *always* true. If the
+quantity `z - y - 2*y*z + 2*y**2 == 0` then the points will be collinear. It
+would be really nice to inform the user of this because such a quantity may be
+useful to a user for further calculation and, at the very least, being nice to
+know. This could be potentially done by returning an object (e.g.,
+GeometryResult) that the user could use. This actually would not involve an
+extensive amount of work.
+
+Three Dimensions and Beyond
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Currently there are no plans for extending the module to three dimensions, but
+it certainly would be a good addition. This would probably involve a fair
+amount of work since many of the algorithms used are specific to two
+dimensions.
+
+Geometry Visualization
+~~~~~~~~~~~~~~~~~~~~~~
+
+The plotting module is capable of plotting geometric entities. See
+`Plotting Geometric Entities <https://github.com/sympy/sympy/wiki/Plotting-Module>`_ in
+the plotting module entry.
diff --git a/lib/sympy/doc/src/modules/index.txt b/lib/sympy/doc/src/modules/index.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/index.txt
@@ -0,0 +1,51 @@
+.. _module-docs:
+
+SymPy Modules Reference
+=======================
+
+Because every feature of SymPy must have a test case, when you are not sure how
+to use something, just look into the ``tests/`` directories, find that feature
+and read the tests for it, that will tell you everything you need to know.
+
+Most of the things are already documented though in this document, that is
+automatically generated using SymPy's docstrings.
+
+Click the  "modules" (:ref:`modindex`) link in the top right corner to easily
+access any SymPy module, or use this contens:
+
+.. toctree::
+   :maxdepth: 2
+
+   core.txt
+   concrete.txt
+   evalf.txt
+   functions.txt
+   geometry.txt
+   galgebra/GA/GAsympy.txt
+   galgebra/latex_ex/latex_ex.txt
+   integrals.txt
+   logic.txt
+   matrices.txt
+   mpmath/index.txt
+   polys/index.txt
+   printing.txt
+   plotting.txt
+   assumptions.txt
+   rewriting.txt
+   series.txt
+   simplify/simplify.txt
+   simplify/hyperexpand.txt
+   statistics.txt
+   solvers/ode.txt
+   solvers/solvers.txt
+   tensor.txt
+   utilities/index.txt
+
+Contributions to docs
+---------------------
+
+All contributions are welcome. If you'd like to improve something, look into
+the sources if they contain the information you need (if not, please fix them),
+otherwise the documentation generation needs to be improved (look in the
+``doc/`` directory).
+
diff --git a/lib/sympy/doc/src/modules/integrals.txt b/lib/sympy/doc/src/modules/integrals.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/integrals.txt
@@ -0,0 +1,75 @@
+Integrals
+==========
+
+.. module:: sympy.integrals
+
+The *integrals* module in SymPy implements methdos calculating definite un undefinite integrals of expressions.
+
+Principal method in this module is integrate()
+
+  - integrate(f, x) returns the indefinite integral :math:`\int f\,dx`
+  - integrate(f, (x, a, b)) returns the definite integral :math:`\int_{a}^{b} f\,dx`
+
+Examples
+--------
+SymPy can integrate a vast array of functions. It can integrate polynomial functions::
+
+    >>> from sympy import *
+    >>> init_printing(use_unicode=False, wrap_line=False, no_global=True)
+    >>> x = Symbol('x')
+    >>> integrate(x**2 + x + 1, x)
+     3    2
+    x    x
+    -- + -- + x
+    3    2
+
+Rational functions::
+
+	>>> integrate(x/(x**2+2*x+1), x)
+	               1
+	log(x + 1) + -----
+	             x + 1
+
+
+Exponential-polynomial functions. Multiplicative combinations of polynomials and the functions exp, cos and sin can be integrated by hand using repeated integration by parts, which is an extremely tedious process. Happily, SymPy will deal with these integrals.
+
+::
+
+    >>> integrate(x**2 * exp(x) * cos(x), x)
+     2  x           2  x                         x           x
+    x *e *sin(x)   x *e *cos(x)      x          e *sin(x)   e *cos(x)
+    ------------ + ------------ - x*e *sin(x) + --------- - ---------
+         2              2                           2           2
+
+
+
+even a few nonelementary integrals (in particular, some integrals involving the error function) can be evaluated::
+
+	>>> integrate(exp(-x**2)*erf(x), x)
+	  ____    2
+	\/ pi *erf (x)
+	--------------
+	      4
+
+
+Internals
+---------
+
+There is a general method for calculating antiderivatives of elementary functions, called the Risch algorithm. The Risch algorithm is a decision procedure that can determine whether an elementary solution exists, and in that case calculate it. It can be extended to handle many nonelementary functions in addition to the elementary ones.
+
+SymPy currently uses a simplified version of the Risch algorithm, called the Risch-Norman algorithm. This algorithm is much faster, but may fail to find an antiderivative, although it is still very powerful. SymPy also uses pattern matching and heuristics to speed up evaluation of some types of integrals, e.g. polynomials.
+
+API reference
+-------------
+
+.. automethod:: sympy.integrals.integrate
+
+Class Integral represents an unevaluated integral and has some methods that help in the integration of an expression.
+
+.. autoclass:: sympy.integrals.Integral
+   :members:
+
+
+TODO and Bugs
+-------------
+There are still lots of functions that sympy does not know how to integrate. For bugs related to this module, see http://code.google.com/p/sympy/issues/list?q=label:Integration
diff --git a/lib/sympy/doc/src/modules/logic.txt b/lib/sympy/doc/src/modules/logic.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/logic.txt
@@ -0,0 +1,80 @@
+Logic Module
+===============
+
+.. module:: sympy.logic
+
+Introduction
+------------
+
+The logic module for SymPy allows to form and manipulate logic expressions using
+symbolic and boolean values
+
+Forming logical expressions
+---------------------------
+
+You can build boolean expressions with the standard python operators & (And),
+|(Or), ~ (Not):
+
+    >>> from sympy import *
+    >>> x, y = symbols('x,y')
+    >>> y | (x & y)
+    Or(And(x, y), y)
+    >>> x | y
+    Or(x, y)
+    >>> ~x
+    Not(x)
+
+You can also form implications with >> and <<:
+
+    >>> x >> y
+    Implies(x, y)
+    >>> x << y
+    Implies(y, x)
+
+Like most types in SymPy, Boolean expressions inherit from sympy.core.Basic:
+
+    >>> (y & x).subs({x: True, y: True})
+    True
+    >>> (x | y).atoms()
+    set([x, y])
+
+Other boolean functions
+-----------------------
+
+.. automethod:: sympy.logic.boolalg.Xor
+
+.. automethod:: sympy.logic.boolalg.Nand
+
+.. automethod:: sympy.logic.boolalg.Nor
+
+.. automethod:: sympy.logic.boolalg.Equivalent
+
+Inference
+---------
+
+.. module: sympy.logic.inference
+
+This module implements some inference routines in propositional logic.
+
+The function satisfiable will test that a given boolean expression is satisfiable,
+that is, you can assign values to the variables to make the sentence True.
+
+For example, the expression x & ~x is not satisfiable, since there are no values
+for x that make this sentence True. On the other hand, (x | y) & (x | ~y) & (~x | y)
+is satisfiable with both x and y being True.
+
+    >>> from sympy.logic.inference import satisfiable
+    >>> from sympy import Symbol
+    >>> x = Symbol('x')
+    >>> y = Symbol('y')
+    >>> satisfiable(x & ~x)
+    False
+    >>> satisfiable((x | y) & (x | ~y) & (~x | y))
+    {x: True, y: True}
+
+As you see, when a sentence is satisfiable, it returns a model that makes that
+sentence True. If it is not satisfiable it will return False
+
+.. automethod:: sympy.logic.inference.satisfiable
+
+.. TODO: write about CNF file format
diff --git a/lib/sympy/doc/src/modules/matrices.txt b/lib/sympy/doc/src/modules/matrices.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/matrices.txt
@@ -0,0 +1,491 @@
+Matrices (linear algebra)
+=========================
+
+.. module:: sympy.matrices.matrices
+
+Creating Matrices
+-----------------
+
+The linear algebra module is designed to be as simple as possible. First, we
+import and declare our first Matrix object:
+
+    >>> from sympy.interactive.printing import init_printing
+    >>> init_printing(use_unicode=False, wrap_line=False, no_global=True)
+    >>> from sympy.matrices import *
+    >>> Matrix([[1,0], [0,1]])
+    [1  0]
+    [    ]
+    [0  1]
+    >>> Matrix((
+    ...   Matrix((
+    ...     (1, 0, 0),
+    ...     (0, 0, 0)
+    ...   )),
+    ...   (0, 0, -1)
+    ... ))
+    [1  0  0 ]
+    [        ]
+    [0  0  0 ]
+    [        ]
+    [0  0  -1]
+    >>> Matrix([[1, 2, 3]])
+    [1 2 3]
+    >>> Matrix([1, 2, 3])
+    [1]
+    [ ]
+    [2]
+    [ ]
+    [3]
+
+This is the standard manner one creates a matrix, i.e. with a list of
+appropriately-sizes lists and/or matrices. SymPy also supports more advanced
+methods of matrix creation including a single list of values and dimension
+inputs:
+
+    >>> Matrix(2, 3, [1, 2, 3, 4, 5, 6])
+    [1  2  3]
+    [       ]
+    [4  5  6]
+
+More interestingly (and usefully), we can use a 2-variable function (or lambda)
+to make one. Here we create an indicator function which is 1 on the diagonal
+and then use it to make the identity matrix:
+
+    >>> def f(i,j):
+    ...     if i == j:
+    ...             return 1
+    ...     else:
+    ...             return 0
+    ...
+    >>> Matrix(4, 4, f)
+    [1  0  0  0]
+    [          ]
+    [0  1  0  0]
+    [          ]
+    [0  0  1  0]
+    [          ]
+    [0  0  0  1]
+
+Finally let's use lambda to create a 1-line matrix with 1's in the even
+permutation entries:
+
+    >>> Matrix(3, 4, lambda i,j: 1 - (i+j) % 2)
+    [1  0  1  0]
+    [          ]
+    [0  1  0  1]
+    [          ]
+    [1  0  1  0]
+
+There are also a couple of special constructors for quick matrix construction -
+``eye`` is the identity matrix, ``zeros`` and ``ones`` for matrices of all
+zeros and ones, respectively:
+
+    >>> eye(4)
+    [1  0  0  0]
+    [          ]
+    [0  1  0  0]
+    [          ]
+    [0  0  1  0]
+    [          ]
+    [0  0  0  1]
+    >>> zeros(2)
+    [0  0]
+    [    ]
+    [0  0]
+    >>> zeros(2, 5)
+    [0  0  0  0  0]
+    [             ]
+    [0  0  0  0  0]
+    >>> ones(3)
+    [1  1  1]
+    [       ]
+    [1  1  1]
+    [       ]
+    [1  1  1]
+    >>> ones(1, 3)
+    [1  1  1]
+
+
+Basic Manipulation
+------------------
+
+While learning to work with matrices, let's choose one where the entries are
+readily identifiable. One useful thing to know is that while matrices are
+2-dimensional, the storage is not and so it is allowable - though one should be
+careful - to access the entries as if they were a 1-d list.
+
+    >>> M = Matrix(2, 3, [1, 2, 3, 4, 5, 6])
+    >>> M[4]
+    5
+
+Now, the more standard entry access is a pair of indices:
+
+    >>> M[1,2]
+    6
+    >>> M[0,0]
+    1
+    >>> M[1,1]
+    5
+
+Since this is Python we're also able to slice submatrices::
+
+    >>> M[0:2,0:2]
+    [1  2]
+    [    ]
+    [4  5]
+    >>> M[1:2,2]
+    [6]
+    >>> M[:,2]
+    [3]
+    [ ]
+    [6]
+
+Remember in the 2nd example above that slicing 2:2 gives an empty range and
+that, as in python, a 4 column list is indexed from 0 to 3. In particular, this
+mean a quick way to create a copy of the matrix is:
+
+    >>> M2 = M[:,:]
+    >>> M2[0,0] = 100
+    >>> M
+    [1  2  3]
+    [       ]
+    [4  5  6]
+
+See? Changing M2 didn't change M. Since we can slice, we can also assign
+entries:
+
+    >>> M = Matrix(([1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]))
+    >>> M
+    [1   2   3   4 ]
+    [              ]
+    [5   6   7   8 ]
+    [              ]
+    [9   10  11  12]
+    [              ]
+    [13  14  15  16]
+    >>> M[2,2] = M[0,3] = 0
+    >>> M
+    [1   2   3   0 ]
+    [              ]
+    [5   6   7   8 ]
+    [              ]
+    [9   10  0   12]
+    [              ]
+    [13  14  15  16]
+
+as well as assign slices:
+
+    >>> M = Matrix(([1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]))
+    >>> M[2:,2:] = Matrix(2,2,lambda i,j: 0)
+    >>> M
+    [1   2   3  4]
+    [            ]
+    [5   6   7  8]
+    [            ]
+    [9   10  0  0]
+    [            ]
+    [13  14  0  0]
+
+All the standard arithmetic operations are supported:
+
+    >>> M = Matrix(([1,2,3],[4,5,6],[7,8,9]))
+    >>> M - M
+    [0  0  0]
+    [       ]
+    [0  0  0]
+    [       ]
+    [0  0  0]
+    >>> M + M
+    [2   4   6 ]
+    [          ]
+    [8   10  12]
+    [          ]
+    [14  16  18]
+    >>> M * M
+    [30   36   42 ]
+    [             ]
+    [66   81   96 ]
+    [             ]
+    [102  126  150]
+    >>> M2 = Matrix(3,1,[1,5,0])
+    >>> M*M2
+    [11]
+    [  ]
+    [29]
+    [  ]
+    [47]
+    >>> M**2
+    [30   36   42 ]
+    [             ]
+    [66   81   96 ]
+    [             ]
+    [102  126  150]
+
+As well as some useful vector operations:
+
+    >>> M.row_del(0)
+    >>> M
+    [4  5  6]
+    [       ]
+    [7  8  9]
+    >>> M.col_del(1)
+    >>> M
+    [4  6]
+    [    ]
+    [7  9]
+    >>> v1 = Matrix([1,2,3])
+    >>> v2 = Matrix([4,5,6])
+    >>> v3 = v1.cross(v2)
+    >>> v1.dot(v2)
+    32
+    >>> v2.dot(v3)
+    0
+    >>> v1.dot(v3)
+    0
+
+Recall that the row_del() and col_del() operations don't return a value - they
+simply change the matrix object. We can also ''glue'' together matrices of the
+appropriate size:
+
+    >>> M1 = eye(3)
+    >>> M2 = zeros(3, 4)
+    >>> M1.row_join(M2)
+    [1  0  0  0  0  0  0]
+    [                   ]
+    [0  1  0  0  0  0  0]
+    [                   ]
+    [0  0  1  0  0  0  0]
+    >>> M3 = zeros(4, 3)
+    >>> M1.col_join(M3)
+    [1  0  0]
+    [       ]
+    [0  1  0]
+    [       ]
+    [0  0  1]
+    [       ]
+    [0  0  0]
+    [       ]
+    [0  0  0]
+    [       ]
+    [0  0  0]
+    [       ]
+    [0  0  0]
+
+
+Operations on entries
+---------------------
+
+We are not restricted to having multiplication between two matrices:
+
+    >>> M = eye(3)
+    >>> 2*M
+    [2  0  0]
+    [       ]
+    [0  2  0]
+    [       ]
+    [0  0  2]
+    >>> 3*M
+    [3  0  0]
+    [       ]
+    [0  3  0]
+    [       ]
+    [0  0  3]
+
+but we can also apply functions to our matrix entries using applyfunc(). Here we'll declare a function that double any input number. Then we apply it to the 3x3 identity matrix:
+
+    >>> f = lambda x: 2*x
+    >>> eye(3).applyfunc(f)
+    [2  0  0]
+    [       ]
+    [0  2  0]
+    [       ]
+    [0  0  2]
+
+One more useful matrix-wide entry application function is the substitution function. Let's declare a matrix with symbolic entries then substitute a value. Remember we can substitute anything - even another symbol!:
+
+    >>> from sympy import Symbol
+    >>> x = Symbol('x')
+    >>> M = eye(3) * x
+    >>> M
+    [x  0  0]
+    [       ]
+    [0  x  0]
+    [       ]
+    [0  0  x]
+    >>> M.subs(x, 4)
+    [4  0  0]
+    [       ]
+    [0  4  0]
+    [       ]
+    [0  0  4]
+    >>> y = Symbol('y')
+    >>> M.subs(x, y)
+    [y  0  0]
+    [       ]
+    [0  y  0]
+    [       ]
+    [0  0  y]
+
+
+Linear algebra
+--------------
+
+Now that we have the basics out of the way, let's see what we can do with the
+actual matrices. Of course the first things that come to mind are the basics
+like the determinant:
+
+    >>> M = Matrix(( [1, 2, 3], [3, 6, 2], [2, 0, 1] ))
+    >>> M.det()
+    -28
+    >>> M2 = eye(3)
+    >>> M2.det()
+    1
+    >>> M3 = Matrix(( [1, 0, 0], [1, 0, 0], [1, 0, 0] ))
+    >>> M3.det()
+    0
+
+and the inverse. In SymPy the inverse is computed by Gaussian elimination by
+default but we can specify it be done by LU decomposition as well:
+
+    >>> M2.inv()
+    [1  0  0]
+    [       ]
+    [0  1  0]
+    [       ]
+    [0  0  1]
+    >>> M2.inv("LU")
+    [1  0  0]
+    [       ]
+    [0  1  0]
+    [       ]
+    [0  0  1]
+    >>> M.inv("LU")
+    [-3/14  1/14  1/2 ]
+    [                 ]
+    [-1/28  5/28  -1/4]
+    [                 ]
+    [ 3/7   -1/7   0  ]
+    >>> M * M.inv("LU")
+    [1  0  0]
+    [       ]
+    [0  1  0]
+    [       ]
+    [0  0  1]
+
+We can perform a QR factorization which is handy for solving systems:
+
+    >>> A = Matrix([[1,1,1],[1,1,3],[2,3,4]])
+    >>> Q, R = A.QRdecomposition()
+    >>> Q
+    [  ___     ___     ___]
+    [\/ 6   -\/ 3   -\/ 2 ]
+    [-----  ------  ------]
+    [  6      3       2   ]
+    [                     ]
+    [  ___     ___    ___ ]
+    [\/ 6   -\/ 3   \/ 2  ]
+    [-----  ------  ----- ]
+    [  6      3       2   ]
+    [                     ]
+    [  ___    ___         ]
+    [\/ 6   \/ 3          ]
+    [-----  -----     0   ]
+    [  3      3           ]
+    >>> R
+    [           ___         ]
+    [  ___  4*\/ 6       ___]
+    [\/ 6   -------  2*\/ 6 ]
+    [          3            ]
+    [                       ]
+    [          ___          ]
+    [        \/ 3           ]
+    [  0     -----      0   ]
+    [          3            ]
+    [                       ]
+    [                   ___ ]
+    [  0       0      \/ 2  ]
+    >>> Q*R
+    [1  1  1]
+    [       ]
+    [1  1  3]
+    [       ]
+    [2  3  4]
+
+
+In addition to the solvers in the solver.py file, we can solve the system Ax=b
+by passing the b vector to the matrix A's LUsolve function. Here we'll cheat a
+little choose A and x then multiply to get b. Then we can solve for x and check
+that it's correct:
+
+    >>> A = Matrix([ [2, 3, 5], [3, 6, 2], [8, 3, 6] ])
+    >>> x = Matrix(3,1,[3,7,5])
+    >>> b = A*x
+    >>> soln = A.LUsolve(b)
+    >>> soln
+    [3]
+    [ ]
+    [7]
+    [ ]
+    [5]
+
+There's also a nice Gram-Schmidt orthogonalizer which will take a set of
+vectors and orthogonalize then with respect to another another. There is an
+optional argument which specifies whether or not the output should also be
+normalized, it defaults to False. Let's take some vectors and orthogonalize
+them - one normalized and one not:
+
+    >>> L = [Matrix([2,3,5]), Matrix([3,6,2]), Matrix([8,3,6])]
+    >>> out1 = GramSchmidt(L)
+    >>> out2 = GramSchmidt(L, True)
+
+Let's take a look at the vectors:
+
+    >>> for i in out1:
+    ...     print i
+    ...
+    [2]
+    [3]
+    [5]
+    [ 23/19]
+    [ 63/19]
+    [-47/19]
+    [ 1692/353]
+    [-1551/706]
+    [ -423/706]
+    >>> for i in out2:
+    ...      print i
+    ...
+    [  sqrt(38)/19]
+    [3*sqrt(38)/38]
+    [5*sqrt(38)/38]
+    [ 23*sqrt(6707)/6707]
+    [ 63*sqrt(6707)/6707]
+    [-47*sqrt(6707)/6707]
+    [ 12*sqrt(706)/353]
+    [-11*sqrt(706)/706]
+    [ -3*sqrt(706)/706]
+
+We can spot-check their orthogonality with dot() and their normality with
+norm():
+
+    >>> out1[0].dot(out1[1])
+    0
+    >>> out1[0].dot(out1[2])
+    0
+    >>> out1[1].dot(out1[2])
+    0
+    >>> out2[0].norm()
+    1
+    >>> out2[1].norm()
+    1
+    >>> out2[2].norm()
+    1
+
+So there is quite a bit that can be done with the module including eigenvalues,
+eigenvectors, nullspace calculation, cofactor expansion tools, and so on. From
+here one might want to look over the matrices.py file for all functionality.
+
+Matrix Class Reference
+----------------------
+.. autoclass:: Matrix
+   :members:
diff --git a/lib/sympy/doc/src/modules/mpmath/basics.txt b/lib/sympy/doc/src/modules/mpmath/basics.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/mpmath/basics.txt
@@ -0,0 +1,227 @@
+Basic usage
+===========================
+
+In interactive code examples that follow, it will be assumed that
+all items in the ``mpmath`` namespace have been imported::
+
+    >>> from mpmath import *
+
+Importing everything can be convenient, especially when using mpmath interactively, but be
+careful when mixing mpmath with other libraries! To avoid inadvertently overriding
+other functions or objects, explicitly import only the needed objects, or use
+the ``mpmath.`` or ``mp.`` namespaces::
+
+    from mpmath import sin, cos
+    sin(1), cos(1)
+
+    import mpmath
+    mpmath.sin(1), mpmath.cos(1)
+
+    from mpmath import mp    # mp context object -- to be explained
+    mp.sin(1), mp.cos(1)
+
+
+Number types
+------------
+
+Mpmath provides the following numerical types:
+
+    +------------+----------------+
+    | Class      | Description    |
+    +============+================+
+    | ``mpf``    | Real float     |
+    +------------+----------------+
+    | ``mpc``    | Complex float  |
+    +------------+----------------+
+    | ``matrix`` | Matrix         |
+    +------------+----------------+
+
+The following section will provide a very short introduction to the types ``mpf`` and ``mpc``. Intervals and matrices are described further in the documentation chapters on interval arithmetic and matrices / linear algebra.
+
+The ``mpf`` type is analogous to Python's built-in ``float``. It holds a real number or one of the special values ``inf`` (positive infinity), ``-inf`` (negative infinity) and ``nan`` (not-a-number, indicating an indeterminate result). You can create ``mpf`` instances from strings, integers, floats, and other ``mpf`` instances:
+
+    >>> mpf(4)
+    mpf('4.0')
+    >>> mpf(2.5)
+    mpf('2.5')
+    >>> mpf("1.25e6")
+    mpf('1250000.0')
+    >>> mpf(mpf(2))
+    mpf('2.0')
+    >>> mpf("inf")
+    mpf('+inf')
+
+The ``mpc`` type represents a complex number in rectangular form as a pair of ``mpf`` instances. It can be constructed from a Python ``complex``, a real number, or a pair of real numbers:
+
+    >>> mpc(2,3)
+    mpc(real='2.0', imag='3.0')
+    >>> mpc(complex(2,3)).imag
+    mpf('3.0')
+
+You can mix ``mpf`` and ``mpc`` instances with each other and with Python numbers:
+
+    >>> mpf(3) + 2*mpf('2.5') + 1.0
+    mpf('9.0')
+    >>> mp.dps = 15      # Set precision (see below)
+    >>> mpc(1j)**0.5
+    mpc(real='0.70710678118654757', imag='0.70710678118654757')
+
+
+Setting the precision
+---------------------
+
+Mpmath uses a global working precision; it does not keep track of the precision or accuracy of individual numbers. Performing an arithmetic operation or calling ``mpf()`` rounds the result to the current working precision. The working precision is controlled by a context object called ``mp``, which has the following default state:
+
+    >>> print mp
+    Mpmath settings:
+      mp.prec = 53                [default: 53]
+      mp.dps = 15                 [default: 15]
+      mp.trap_complex = False     [default: False]
+
+The term **prec** denotes the binary precision (measured in bits) while **dps** (short for *decimal places*) is the decimal precision. Binary and decimal precision are related roughly according to the formula ``prec = 3.33*dps``. For example, it takes a precision of roughly 333 bits to hold an approximation of pi that is accurate to 100 decimal places (actually slightly more than 333 bits is used).
+
+Changing either precision property of the ``mp`` object automatically updates the other; usually you just want to change the ``dps`` value:
+
+    >>> mp.dps = 100
+    >>> mp.dps
+    100
+    >>> mp.prec
+    336
+
+When the precision has been set, all ``mpf`` operations are carried out at that precision::
+
+    >>> mp.dps = 50
+    >>> mpf(1) / 6
+    mpf('0.16666666666666666666666666666666666666666666666666656')
+    >>> mp.dps = 25
+    >>> mpf(2) ** mpf('0.5')
+    mpf('1.414213562373095048801688713')
+
+The precision of complex arithmetic is also controlled by the ``mp`` object:
+
+    >>> mp.dps = 10
+    >>> mpc(1,2) / 3
+    mpc(real='0.3333333333321', imag='0.6666666666642')
+
+There is no restriction on the magnitude of numbers. An ``mpf`` can for example hold an approximation of a large Mersenne prime:
+
+    >>> mp.dps = 15
+    >>> print mpf(2)**32582657 - 1
+    1.24575026015369e+9808357
+
+Or why not 1 googolplex:
+
+    >>> print mpf(10) ** (10**100)  # doctest:+ELLIPSIS
+    1.0e+100000000000000000000000000000000000000000000000000...
+
+The (binary) exponent is stored exactly and is independent of the precision.
+
+Temporarily changing the precision
+..................................
+
+It is often useful to change the precision during only part of a calculation. A way to temporarily increase the precision and then restore it is as follows:
+
+    >>> mp.prec += 2
+    >>> # do_something()
+    >>> mp.prec -= 2
+
+In Python 2.5, the ``with`` statement along with the mpmath functions ``workprec``, ``workdps``, ``extraprec`` and ``extradps`` can be used to temporarily change precision in a more safe manner:
+
+    >>> from __future__ import with_statement
+    >>> with workdps(20):  # doctest: +SKIP
+    ...     print mpf(1)/7
+    ...     with extradps(10):
+    ...         print mpf(1)/7
+    ...
+    0.14285714285714285714
+    0.142857142857142857142857142857
+    >>> mp.dps
+    15
+
+The ``with`` statement ensures that the precision gets reset when exiting the block, even in the case that an exception is raised. (The effect of the ``with`` statement can be emulated in Python 2.4 by using a ``try/finally`` block.)
+
+The ``workprec`` family of functions can also be used as function decorators:
+
+    >>> @workdps(6)
+    ... def f():
+    ...     return mpf(1)/3
+    ...
+    >>> f()
+    mpf('0.33333331346511841')
+
+
+Some functions accept the ``prec`` and ``dps`` keyword arguments and this will override the global working precision. Note that this will not affect the precision at which the result is printed, so to get all digits, you must either use increase precision afterward when printing or use ``nstr``/``nprint``:
+
+    >>> mp.dps = 15
+    >>> print exp(1)
+    2.71828182845905
+    >>> print exp(1, dps=50)      # Extra digits won't be printed
+    2.71828182845905
+    >>> nprint(exp(1, dps=50), 50)
+    2.7182818284590452353602874713526624977572470937
+
+Finally, instead of using the global context object ``mp``, you can create custom contexts and work with methods of those instances instead of global functions. The working precision will be local to each context object:
+
+    >>> mp2 = mp.clone()
+    >>> mp.dps = 10
+    >>> mp2.dps = 20
+    >>> print mp.mpf(1) / 3
+    0.3333333333
+    >>> print mp2.mpf(1) / 3
+    0.33333333333333333333
+
+**Note**: the ability to create multiple contexts is a new feature that is only partially implemented. Not all mpmath functions are yet available as context-local methods. In the present version, you are likely to encounter bugs if you try mixing different contexts.
+
+Providing correct input
+-----------------------
+
+Note that when creating a new ``mpf``, the value will at most be as accurate as the input. *Be careful when mixing mpmath numbers with Python floats*. When working at high precision, fractional ``mpf`` values should be created from strings or integers:
+
+    >>> mp.dps = 30
+    >>> mpf(10.9)   # bad
+    mpf('10.9000000000000003552713678800501')
+    >>> mpf('10.9')  # good
+    mpf('10.8999999999999999999999999999997')
+    >>> mpf(109) / mpf(10)   # also good
+    mpf('10.8999999999999999999999999999997')
+    >>> mp.dps = 15
+
+(Binary fractions such as 0.5, 1.5, 0.75, 0.125, etc, are generally safe as input, however, since those can be represented exactly by Python floats.)
+
+Printing
+--------
+
+By default, the ``repr()`` of a number includes its type signature. This way ``eval`` can be used to recreate a number from its string representation:
+
+    >>> eval(repr(mpf(2.5)))
+    mpf('2.5')
+
+Prettier output can be obtained by using ``str()`` or ``print``, which hide the ``mpf`` and ``mpc`` signatures and also suppress rounding artifacts in the last few digits:
+
+    >>> mpf("3.14159")
+    mpf('3.1415899999999999')
+    >>> print mpf("3.14159")
+    3.14159
+    >>> print mpc(1j)**0.5
+    (0.707106781186548 + 0.707106781186548j)
+
+Setting the ``mp.pretty`` option will use the ``str()``-style output for ``repr()`` as well:
+
+    >>> mp.pretty = True
+    >>> mpf(0.6)
+    0.6
+    >>> mp.pretty = False
+    >>> mpf(0.6)
+    mpf('0.59999999999999998')
+
+The number of digits with which numbers are printed by default is determined by the working precision. To specify the number of digits to show without changing the working precision, use :func:`mpmath.nstr` and :func:`mpmath.nprint`:
+
+    >>> a = mpf(1) / 6
+    >>> a
+    mpf('0.16666666666666666')
+    >>> nstr(a, 8)
+    '0.16666667'
+    >>> nprint(a, 8)
+    0.16666667
+    >>> nstr(a, 50)
+    '0.16666666666666665741480812812369549646973609924316'
diff --git a/lib/sympy/doc/src/modules/mpmath/calculus/approximation.txt b/lib/sympy/doc/src/modules/mpmath/calculus/approximation.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/mpmath/calculus/approximation.txt
@@ -0,0 +1,23 @@
+Function approximation
+----------------------
+
+Taylor series (``taylor``)
+..........................
+
+.. autofunction:: mpmath.taylor
+
+Pade approximation (``pade``)
+.............................
+
+.. autofunction:: mpmath.pade
+
+Chebyshev approximation (``chebyfit``)
+......................................
+
+.. autofunction:: mpmath.chebyfit
+
+Fourier series (``fourier``, ``fourierval``)
+............................................
+
+.. autofunction:: mpmath.fourier
+.. autofunction:: mpmath.fourierval
diff --git a/lib/sympy/doc/src/modules/mpmath/calculus/differentiation.txt b/lib/sympy/doc/src/modules/mpmath/calculus/differentiation.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/mpmath/calculus/differentiation.txt
@@ -0,0 +1,19 @@
+Differentiation
+---------------
+
+Numerical derivatives (``diff``, ``diffs``)
+...........................................
+
+.. autofunction:: mpmath.diff
+.. autofunction:: mpmath.diffs
+
+Composition of derivatives (``diffs_prod``, ``diffs_exp``)
+..........................................................
+
+.. autofunction:: mpmath.diffs_prod
+.. autofunction:: mpmath.diffs_exp
+
+Fractional derivatives / differintegration (``differint``)
+............................................................
+
+.. autofunction:: mpmath.differint
diff --git a/lib/sympy/doc/src/modules/mpmath/calculus/index.txt b/lib/sympy/doc/src/modules/mpmath/calculus/index.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/mpmath/calculus/index.txt
@@ -0,0 +1,13 @@
+Numerical calculus
+==================
+
+.. toctree::
+   :maxdepth: 2
+
+   polynomials.txt
+   optimization.txt
+   sums_limits.txt
+   differentiation.txt
+   integration.txt
+   odes.txt
+   approximation.txt
diff --git a/lib/sympy/doc/src/modules/mpmath/calculus/integration.txt b/lib/sympy/doc/src/modules/mpmath/calculus/integration.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/mpmath/calculus/integration.txt
@@ -0,0 +1,31 @@
+Numerical integration (quadrature)
+----------------------------------
+
+Standard quadrature (``quad``)
+..............................
+
+.. autofunction:: mpmath.quad
+
+Oscillatory quadrature (``quadosc``)
+....................................
+
+.. autofunction:: mpmath.quadosc
+
+Quadrature rules
+................
+
+.. autoclass:: mpmath.calculus.quadrature.QuadratureRule
+   :members:
+
+Tanh-sinh rule
+~~~~~~~~~~~~~~
+
+.. autoclass:: mpmath.calculus.quadrature.TanhSinh
+   :members:
+
+
+Gauss-Legendre rule
+~~~~~~~~~~~~~~~~~~~
+
+.. autoclass:: mpmath.calculus.quadrature.GaussLegendre
+   :members:
diff --git a/lib/sympy/doc/src/modules/mpmath/calculus/odes.txt b/lib/sympy/doc/src/modules/mpmath/calculus/odes.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/mpmath/calculus/odes.txt
@@ -0,0 +1,7 @@
+Ordinary differential equations
+-------------------------------
+
+Solving the ODE initial value problem (``odefun``)
+..................................................
+
+.. autofunction:: mpmath.odefun
diff --git a/lib/sympy/doc/src/modules/mpmath/calculus/optimization.txt b/lib/sympy/doc/src/modules/mpmath/calculus/optimization.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/mpmath/calculus/optimization.txt
@@ -0,0 +1,29 @@
+Root-finding and optimization
+-----------------------------
+
+Root-finding (``findroot``)
+...........................
+
+.. autofunction:: mpmath.findroot(f, x0, solver=Secant, tol=None, verbose=False, verify=True, **kwargs)
+
+Solvers
+^^^^^^^
+
+.. autoclass:: mpmath.calculus.optimization.Secant
+.. autoclass:: mpmath.calculus.optimization.Newton
+.. autoclass:: mpmath.calculus.optimization.MNewton
+.. autoclass:: mpmath.calculus.optimization.Halley
+.. autoclass:: mpmath.calculus.optimization.Muller
+.. autoclass:: mpmath.calculus.optimization.Bisection
+.. autoclass:: mpmath.calculus.optimization.Illinois
+.. autoclass:: mpmath.calculus.optimization.Pegasus
+.. autoclass:: mpmath.calculus.optimization.Anderson
+.. autoclass:: mpmath.calculus.optimization.Ridder
+.. autoclass:: mpmath.calculus.optimization.ANewton
+.. autoclass:: mpmath.calculus.optimization.MDNewton
+
+
+.. Minimization and maximization (``findmin``, ``findmax``)
+.. ........................................................
+
+.. (To be added.)
diff --git a/lib/sympy/doc/src/modules/mpmath/calculus/polynomials.txt b/lib/sympy/doc/src/modules/mpmath/calculus/polynomials.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/mpmath/calculus/polynomials.txt
@@ -0,0 +1,15 @@
+Polynomials
+-----------
+
+See also :func:`taylor` and :func:`chebyfit` for
+approximation of functions by polynomials.
+
+Polynomial evaluation (``polyval``)
+...................................
+
+.. autofunction:: mpmath.polyval
+
+Polynomial roots (``polyroots``)
+................................
+
+.. autofunction:: mpmath.polyroots
diff --git a/lib/sympy/doc/src/modules/mpmath/calculus/sums_limits.txt b/lib/sympy/doc/src/modules/mpmath/calculus/sums_limits.txt
new file mode 100644
--- /dev/null
+++ b/lib/sympy/doc/src/modules/mpmath/calculus/sums_limits.txt
@@ -0,0 +1,58 @@
+Sums, products, limits and extrapolation
+----------------------------------------
+
+The functions listed here permit approximation of infinite
+sums, products, and other sequence limits.
+Use :func:`mpmath.fsum` and :func:`mpmath.fprod`
+for summation and multiplication of finite sequences.
+
+Summation
+..........................................
+
+:func:`nsum`


More information about the pypy-commit mailing list