chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:32:53 +08:00
commit 2a16f2f53b
247 changed files with 69150 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
coverage:
precision: 0
round: down
status:
patch:
default:
target: 97
project:
default:
threshold: 1%
comment: false
+2
View File
@@ -0,0 +1,2 @@
* text=auto
*.py diff=python text
+105
View File
@@ -0,0 +1,105 @@
Reporting Issues
================
When opening a new issue, please take the following steps:
1. Please search `GitHub issues`_ to avoid duplicate reports.
2. If possible, try updating to master and reproducing your issue.
3. Try to include a minimal code example that demonstrates the problem.
4. Include any relevant details of your local setup (mpmath version, Python
version, installed libraries).
Please avoid changing your messages on the GitHub, unless you want fix a typo
and so on. Just expand your comment or add a new one.
Contributing Code
=================
All work should be submitted via `Pull Requests (PR)`_.
1. PR can be submitted as soon as there is code worth discussing.
Please make a draft PR, if one is not intended to be merged
in its present shape even if all checks pass.
2. Please put your work on the branch of your fork, not in the
master branch. PR should generally be made against master.
3. One logical change per commit. Make good commit messages: short
(<= 78 characters) one-line summary, then newline followed by
verbose description of your changes. Please `mention closed
issues`_ with commit message.
4. Please conform to `PEP 8`_; run::
flake518
to check formatting.
5. PR should include tests:
1. Bugfixes should include regression tests (named as ``test_issue_123``).
2. All new functionality should be tested, every new line
should be covered by tests. Please use in tests only
public interfaces. Regression tests are not accounted in
the coverage statistics.
3. Optionally, provide doctests to illustrate usage. But keep in
mind, doctests are not tests. Think of them as examples that
happen to be tested.
6. It's good idea to be sure that **all** existing tests
pass and you don't break anything, so please run::
pytest
7. If your change affects documentation, please build it by::
sphinx-build -W -b html docs build/sphinx/html
and check that it looks as expected.
AI Generated Code and Communication Policy
==========================================
The person submitting an issue or PR is responsible for its content, regardless
of whether AI tools were used in its creation. Generative AI tools can produce
output quickly, but discretion, good judgment, and critical thinking are the
foundation of all good contributions.
You must understand and explain the code you submit as well as the existing
related code. It is not acceptable to submit a patch that you cannot
understand and explain yourself. In explaining your contribution, do not use
AI to automatically generate descriptions, as AI rarely communicates such
information correctly and concisely.
Disclosure
----------
If you substantially make use of AI to assist in the development of your patch,
you must disclose how it was used and what code in the patch is AI generated.
Pull request without such disclosure may be rejected.
Code Quality
------------
Code generated by AI is very often of low quality. Contributors are expected
to submit code that meets our standards (see above). We will reject pull
requests that we deem being "AI slop". Do not waste developers time by
submitting code that is fully or mostly generated by AI.
Communication
-------------
When interacting in communication among developers (email list, discussions,
issues, pull requests, etc) do not use AI to speak for you, other than for
translation or grammar editing.
.. _GitHub issues: https://github.com/mpmath/mpmath/issues
.. _Pull Requests (PR): https://github.com/mpmath/mpmath/pulls
.. _PEP 8: https://www.python.org/dev/peps/pep-0008/
.. _mention closed issues: https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue
+11
View File
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: "monthly"
rebase-strategy: "disabled"
groups:
actions-deps:
patterns:
- "*"
+45
View File
@@ -0,0 +1,45 @@
name: Run coverage tests
on: [workflow_dispatch, workflow_call]
jobs:
coverage:
runs-on: ubuntu-24.04
strategy:
fail-fast: true
env:
PYTEST_ADDOPTS: --cov mpmath --cov-append -n auto
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Install dependencies
run: |
pip install --upgrade setuptools pip
pip install --upgrade .[develop,gmpy2,gmp,ci]
- name: Run coverage tests
run: |
pytest
pip uninstall -y ipython
pytest mpmath/tests/test_cli.py
pip uninstall -y gmpy2
pytest mpmath/tests/test_basic_ops.py mpmath/tests/test_convert.py \
mpmath/tests/test_functions.py mpmath/tests/test_gammazeta.py \
mpmath/tests/test_bitwise.py
pip uninstall -y python-gmp
pytest mpmath/tests/test_basic_ops.py mpmath/tests/test_convert.py \
mpmath/tests/test_functions.py mpmath/tests/test_gammazeta.py \
mpmath/tests/test_bitwise.py
- name: Generate coverage reports
run: |
coverage xml
coverage html
diff-cover coverage.xml --fail-under=100 \
--compare-branch=origin/master
- uses: actions/upload-artifact@v7
with:
name: coverage
path: |
coverage.xml
build/coverage/html/
+34
View File
@@ -0,0 +1,34 @@
name: Build & test docs
on: [workflow_dispatch, workflow_call]
jobs:
docs:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Install libs
run: |
sudo apt update
sudo apt install latexmk texlive-xetex
- name: Install dependencies
run: |
pip install --upgrade setuptools pip
pip install --upgrade .[docs]
- name: Building docs
run: |
sphinx-build --color -W --keep-going -b html docs build/sphinx/html
sphinx-build --color -W --keep-going -b latex docs build/sphinx/latex
make -C build/sphinx/latex all-pdf
env:
NO_COLOR: 1 # workaround for sphinx-contrib/autoprogram#76
COLUMNS: 80 # also enable line wrapping for argparse
- uses: actions/upload-artifact@v7
with:
name: docs
path: |
build/sphinx/html/
build/sphinx/latex/mpmath.pdf
+15
View File
@@ -0,0 +1,15 @@
name: Linting with flake8, etc
on: [workflow_dispatch, workflow_call]
jobs:
linter:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/setup-python@v6
with:
python-version: "3.x"
- run: pip install --upgrade .[develop]
- run: python -We:invalid -m compileall -f mpmath -q
- run: flake518 mpmath
+35
View File
@@ -0,0 +1,35 @@
name: Publish on PyPI
on: [push, workflow_dispatch, workflow_call]
jobs:
build:
name: Build distributions
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/setup-python@v6
with:
python-version: "3.x"
- run: pip install build
- run: python -m build
- uses: actions/upload-artifact@v7
with:
name: build
path: dist/
publish-to-pypi:
name: Publish distributions to PyPI
if: startsWith(github.ref, 'refs/tags/')
needs:
- build
runs-on: ubuntu-24.04
steps:
- uses: actions/download-artifact@v8
with:
pattern: build
path: dist/
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
+64
View File
@@ -0,0 +1,64 @@
name: test
on:
push:
pull_request:
workflow_dispatch:
schedule:
- cron: '0 0 * * 2'
jobs:
linter:
uses: ./.github/workflows/linter.yml
coverage:
uses: ./.github/workflows/coverage.yml
docs:
uses: ./.github/workflows/docs.yml
frozen-version:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Run frozen version test
run: ./mpmath/tests/test_version_frozen.sh
tests:
needs:
- linter
- coverage
- frozen-version
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
python-version: ['3.10', 3.11, 3.12, 3.13, 3.14, 3.14t, 3.15, 3.15t]
nogmpy: [false]
purepy: [false]
include:
- python-version: "3.x"
nogmpy: true
- python-version: "3.x"
purepy: true
- python-version: pypy3.11
purepy: true
env:
PYTEST_ADDOPTS: -n auto --durations=20
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
- name: Install dependencies
run: |
pip install --upgrade setuptools pip
pip install --upgrade .[develop,gmpy2,gmp,ci]
- run: pip uninstall -y gmpy2
if: matrix.nogmpy
- run: pip uninstall -y gmpy2 python-gmp
if: matrix.purepy
- run: pytest
+74
View File
@@ -0,0 +1,74 @@
# This file tells git what files to ignore (e.g., you won't see them as
# untracked with "git status"). Add anything to it that can be cleared
# without any worry (e.g., by "git clean -Xdf"), because it can be
# regenerated. Lines beginning with # are comments. You can also ignore
# files on a per-repository basis by modifying the core.excludesfile
# configuration option (see "git help config"). If you need to make git
# track a file that is ignored for some reason, you have to use
# "git add -f". See "git help gitignore" for more information.
# Regular Python bytecode file
*.pyc
__pycache__/
# Optimized Python bytecode file
*.pyo
# Vim's swap files
*.sw[op]
# Generated files from Jython
*$py.class
# File generated by setup.py using MANIFEST.in
MANIFEST
# Generated by ctags (used to improve autocompletion in vim)
tags
my/
# Files generated by setup.py
dist/
build/
# Generated by setuptools_scm
mpmath/_version.py
# Tox files
.tox/
# Mac OS X Junk
.DS_Store
# Backup files
*~
.cache/
.coverage
doc/source/_build/
# Pytest cache
.pytest_cache/
# Files generated by setupegg.py
mpmath.egg-info/
.eggs
# Coverage-related files
.coverage
htmlcov/
# Visual Studio files
.vs/
# PyCharm files
.idea/
# Ignore files cached by Hypothesis (including examples directory so far)
.hypothesis/
# per-project directories for virtual environments
venv/
.venv/
+20
View File
@@ -0,0 +1,20 @@
version: 2
formats:
- htmlzip
- pdf
build:
os: ubuntu-22.04
tools:
python: "3"
jobs:
post_checkout:
- git fetch --unshallow
python:
install:
- method: pip
path: .
extra_requirements:
- docs
sphinx:
fail_on_warning: true
configuration: docs/conf.py
+1341
View File
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
@manual{mpmath,
key = {mpmath},
author = {The mpmath development team},
title = {mpmath: a {P}ython library for arbitrary-precision floating-point arithmetic (version 1.4.0)},
note = {{\tt https://mpmath.org/}},
year = {2026},
}
+27
View File
@@ -0,0 +1,27 @@
Copyright (c) 2005-2026 Fredrik Johansson and mpmath contributors
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 copyright holder 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.
+192
View File
@@ -0,0 +1,192 @@
mpmath
======
|pypi version| |Build status| |Zenodo Badge|
.. |pypi version| image:: https://img.shields.io/pypi/v/mpmath.svg
:target: https://pypi.python.org/pypi/mpmath
.. |Build status| image:: https://github.com/mpmath/mpmath/workflows/test/badge.svg
:target: https://github.com/mpmath/mpmath/actions?workflow=test
.. |Zenodo Badge| image:: https://zenodo.org/badge/2934512.svg
:target: https://zenodo.org/badge/latestdoi/2934512
A Python library for arbitrary-precision floating-point arithmetic.
Website: https://mpmath.org/
Main author: Fredrik Johansson <fredrik.johansson@gmail.com>
Mpmath is free software released under the New BSD License (see the
LICENSE file for details).
0. History and credits
----------------------
The following people (among others) have contributed major patches
or new features to mpmath:
* Pearu Peterson <pearu.peterson@gmail.com>
* Mario Pernici <mario.pernici@mi.infn.it>
* Ondrej Certik <ondrej@certik.cz>
* Vinzent Steinberg <vinzent.steinberg@gmail.com>
* Nimish Telang <ntelang@gmail.com>
* Mike Taschuk <mtaschuk@ece.ualberta.ca>
* Case Van Horsen <casevh@gmail.com>
* Jorn Baayen <jorn.baayen@gmail.com>
* Chris Smith <smichr@gmail.com>
* Juan Arias de Reyna <arias@us.es>
* Ioannis Tziakos <itziakos@gmail.com>
* Aaron Meurer <asmeurer@gmail.com>
* Stefan Krastanov <krastanov.stefan@gmail.com>
* Ken Allen <ken.allen@sbcglobal.net>
* Timo Hartmann <thartmann15@gmail.com>
* Sergey B Kirpichev <skirpichev@gmail.com>
* Kris Kuhlman <kristopher.kuhlman@gmail.com>
* Paul Masson <paulmasson@analyticphysics.com>
* Michael Kagalenko <michael.kagalenko@gmail.com>
* Jonathan Warner <warnerjon12@gmail.com>
* Max Gaukler <max.gaukler@fau.de>
* Guillermo Navas-Palencia <g.navas.palencia@gmail.com>
* Nike Dattani <nike@hpqc.org>
* Tim Peters <tim.peters@gmail.com>
* Javier Garcia <javier.garcia.tw@hotmail.com>
Numerous other people have contributed by reporting bugs,
requesting new features, or suggesting improvements to the
documentation.
For a detailed changelog, including individual contributions,
see the CHANGES file.
Fredrik's work on mpmath during summer 2008 was sponsored by Google
as part of the Google Summer of Code program.
Fredrik's work on mpmath during summer 2009 was sponsored by the
American Institute of Mathematics under the support of the National Science
Foundation Grant No. 0757627 (FRG: L-functions and Modular Forms).
Any opinions, findings, and conclusions or recommendations expressed in this
material are those of the author(s) and do not necessarily reflect the
views of the sponsors.
Credit also goes to:
* The authors of the GMP library and the Python wrapper
gmpy, enabling mpmath to become much faster at
high precision
* The authors of MPFR, pari/gp, MPFUN, and other arbitrary-
precision libraries, whose documentation has been helpful
for implementing many of the algorithms in mpmath
* Wikipedia contributors; Abramowitz & Stegun; Gradshteyn & Ryzhik;
Wolfram Research for MathWorld and the Wolfram Functions site.
These are the main references used for special functions
implementations.
* George Brandl for developing the Sphinx documentation tool
used to build mpmath's documentation
Release history:
* Version 1.4.1 released on March 15, 2026
* Version 1.4.0 released on February 23, 2026
* Version 1.3.0 released on March 7, 2023
* Version 1.2.1 released on February 9, 2021
* Version 1.2.0 released on February 1, 2021
* Version 1.1.0 released on December 11, 2018
* Version 1.0.0 released on September 27, 2017
* Version 0.19 released on June 10, 2014
* Version 0.18 released on December 31, 2013
* Version 0.17 released on February 1, 2011
* Version 0.16 released on September 24, 2010
* Version 0.15 released on June 6, 2010
* Version 0.14 released on February 5, 2010
* Version 0.13 released on August 13, 2009
* Version 0.12 released on June 9, 2009
* Version 0.11 released on January 26, 2009
* Version 0.10 released on October 15, 2008
* Version 0.9 released on August 23, 2008
* Version 0.8 released on April 20, 2008
* Version 0.7 released on March 12, 2008
* Version 0.6 released on January 13, 2008
* Version 0.5 released on November 24, 2007
* Version 0.4 released on November 3, 2007
* Version 0.3 released on October 5, 2007
* Version 0.2 released on October 2, 2007
* Version 0.1 released on September 27, 2007
1. Download & installation
--------------------------
Mpmath requires Python 3.10 or later versions. It has been tested with CPython
3.10 through 3.15 and for PyPy 3.11.
The latest release of mpmath can be downloaded from the mpmath
website and from https://github.com/mpmath/mpmath/releases
It should also be available in the Python Package Index at
https://pypi.python.org/pypi/mpmath
To install latest release of Mpmath with pip, simply run
``pip install mpmath``
or from the source tree
``pip install .``
The latest development code is available from
https://github.com/mpmath/mpmath
See the main documentation for more detailed instructions.
2. Documentation
----------------
Documentation in reStructuredText format is available in the
docs directory included with the source package. These files
are human-readable, but can be compiled to prettier HTML using
`Sphinx <https://www.sphinx-doc.org/>`_.
The most recent documentation is also available in HTML format:
https://mpmath.readthedocs.io/
3. Running tests
----------------
The unit tests in mpmath/tests/ can be run with `pytest
<https://pytest.org/>`_, see the main documentation.
You may also want to check out the demo scripts in the demo
directory.
The master branch is automatically tested on the Github Actions.
4. Known problems
-----------------
Mpmath is a work in progress. Major issues include:
* Some functions may return incorrect values when given extremely
large arguments or arguments very close to singularities.
* Directed rounding works for arithmetic operations. It is implemented
heuristically for other operations, and their results may be off by one
or two units in the last place (even if otherwise accurate).
* Some IEEE 754 features are not available. Inifinities and NaN are
partially supported, there is no signed zero; denormal rounding is
not available at all.
* The interface for switching precision and rounding is not finalized.
The current method is not threadsafe.
5. Help and bug reports
-----------------------
General questions and comments can be `sent <mailto:mpmath@googlegroups.com>`_
to the `mpmath mailinglist <https://groups.google.com/g/mpmath>`_.
You can also report bugs and send patches to the mpmath issue tracker,
https://github.com/mpmath/mpmath/issues
See also our `contributing guidelines
<https://github.com/mpmath/mpmath/blob/master/.github/CONTRIBUTING.rst>`_.
+7
View File
@@ -0,0 +1,7 @@
# WeHub 来源说明
- 原始项目:`mpmath/mpmath`
- 原始仓库:https://github.com/mpmath/mpmath
- 导入方式:上游默认分支的最新快照
- 原作者、版权和许可证信息以原始仓库及本仓库 LICENSE 为准
- 本文件仅用于记录来源,不代表 WeHub 是原项目作者
+35
View File
@@ -0,0 +1,35 @@
import sys
import pytest
import mpmath
def pytest_report_header(config):
print("mpmath backend: %s" % mpmath.libmp.backend.BACKEND)
print("mpmath mp class: %s" % repr(mpmath.mp))
print("mpmath version: %s" % mpmath.__version__)
print("Python version: %s" % sys.version)
def pytest_configure(config):
config.addinivalue_line('markers', 'slow: marks tests as slow')
if "no:hypothesispytest" not in config.getoption("-p"):
from hypothesis import settings
default = settings.get_profile("default")
settings.register_profile("default",
settings(default, max_examples=1000))
ci = settings.get_profile("ci")
settings.register_profile("ci", settings(ci, max_examples=10000))
@pytest.fixture(autouse=True)
def reset_mp_globals():
mpmath.mp.prec = sys.float_info.mant_dig
mpmath.mp.pretty = False
mpmath.mp.rounding = 'n'
mpmath.mp.pretty_dps = "str"
mpmath.iv.prec = mpmath.mp.prec
mpmath.iv.pretty = False
+33
View File
@@ -0,0 +1,33 @@
"""
This script uses the cplot function in mpmath to plot the Mandelbrot set.
By default, the fp context is used for speed. The mp context could be used
to improve accuracy at extremely high zoom levels.
"""
import mpmath
ctx = mpmath.fp
# ctx = mpmath.mp
ITERATIONS = 50
POINTS = 100000
ESCAPE_RADIUS = 8
# Full plot
RE = [-2.5, 1.5]
IM = [-1.5, 1.5]
# A pretty subplot
#RE = [-0.96, -0.80]
#IM = [-0.35, -0.2]
def mandelbrot(z):
c = z
for i in range(ITERATIONS):
zprev = z
z = z*z + c
if abs(z) > ESCAPE_RADIUS:
return ctx.exp(1j*(i + 1 - ctx.log(ctx.log(abs(z)))/ctx.log(2)))
return 0
ctx.cplot(mandelbrot, RE, IM, points=POINTS, verbose=1)
+106
View File
@@ -0,0 +1,106 @@
"""
This script calculates solutions to some of the problems from the
"Many Digits" competition:
http://www.cs.ru.nl/~milad/manydigits/problems.php
Run with:
python manydigits.py
"""
from mpmath import (asin, asinh, atan, atanh, catalan, cos, e, exp, findroot,
mp, mpf, pi, quadts, sin, sqrt, tan, tanh, zeta)
from mpmath.libmp.libintmath import bin_to_radix
from mpmath.libmp.libmpf import to_fixed
dps = 100
mp.dps = dps + 10
def pr(x):
"""Return the first dps digits after the decimal point"""
x = x._mpf_
p = int(dps*3.33 + 10)
t = to_fixed(x, p)
d = bin_to_radix(t, p, 10, dps)
s = str(d).zfill(dps)[-dps:]
return s[:dps//2] + "\n" + s[dps//2:]
print("""
This script prints answers to a selection of the "Many Digits"
competition problems: http://www.cs.ru.nl/~milad/manydigits/problems.php
The output for each problem is the first 100 digits after the
decimal point in the result.
""")
print("C01: sin(tan(cos(1)))")
print(pr(sin(tan(cos(1)))))
print()
print("C02: sqrt(e/pi)")
print(pr(sqrt(e/pi)))
print()
print("C03: sin((e+1)^3)")
print(pr(sin((e+1)**3)))
print()
print("C04: exp(pi*sqrt(2011))")
mp.dps += 65
print(pr(exp(pi*sqrt(2011))))
mp.dps -= 65
print()
print("C05: exp(exp(exp(1/2)))")
print(pr(exp(exp(exp(0.5)))))
print()
print("C06: arctanh(1-arctanh(1-arctanh(1-arctanh(1/pi))))")
print(pr(atanh(1-atanh(1-atanh(1-atanh(1/pi))))))
print()
print("C07: pi^1000")
mp.dps += 505
print(pr(pi**1000))
mp.dps -= 505
print()
print("C08: sin(6^(6^6))")
print(pr(sin(6**(6**6))))
print()
print("C09: sin(10*arctan(tanh(pi*(2011^(1/2))/3)))")
mp.dps += 150
print(pr(sin(10*atan(tanh(pi*sqrt(2011)/3)))))
mp.dps -= 150
print()
print("C10: (7+2^(1/5)-5*(8^(1/5)))^(1/3) + 4^(1/5)-2^(1/5)")
a = mpf(1)/5
print(pr(((7 + 2**a - 5*(8**a))**(mpf(1)/3) + 4**a - 2**a)))
print()
print("C11: tan(2^(1/2))+arctanh(sin(1))")
print(pr((tan(sqrt(2)) + atanh(sin(1)))))
print()
print("C12: arcsin(1/e^2) + arcsinh(e^2)")
print(pr(asin(1/exp(2)) + asinh(exp(2))))
print()
print("C17: S= -4*Zeta(2) - 2*Zeta(3) + 4*Zeta(2)*Zeta(3) + 2*Zeta(5)")
print(pr(-4*zeta(2) - 2*zeta(3) + 4*zeta(2)*zeta(3) + 2*zeta(5)))
print()
print(r"C18: Catalan G = Sum{i=0}{\infty}(-1)^i/(2i+1)^2")
print(pr(catalan))
print()
print("C21: Equation exp(cos(x)) = x")
print(pr(findroot(lambda x: exp(cos(x))-x, 1)))
print()
print("C22: J = integral(sin(sin(sin(x)))), x=0..1")
print(pr(quadts(lambda x: sin(sin(sin(x))), [0, 1])))
print()
+82
View File
@@ -0,0 +1,82 @@
"""
Calculate digits of pi. This module can be run interactively with
python pidigits.py
"""
import math
import sys
from time import perf_counter
from mpmath.libmp.libelefun import pi_fixed
from mpmath.libmp.libintmath import bin_to_radix, numeral
def display_fraction(digits, skip=0, colwidth=10, columns=5):
perline = colwidth * columns
printed = 0
for linecount in range((len(digits)-skip) // (colwidth * columns)):
line = digits[skip+linecount*perline:skip+(linecount+1)*perline]
for i in range(columns):
print(line[i*colwidth : (i+1)*colwidth], end=' ')
print(":", (linecount+1)*perline)
if (linecount+1) % 10 == 0:
print()
printed += colwidth*columns
rem = (len(digits)-skip) % (colwidth * columns)
if rem:
buf = digits[-rem:]
s = ""
for i in range(columns):
s += buf[:colwidth].ljust(colwidth+1, " ")
buf = buf[colwidth:]
print(s + ":", printed + colwidth*columns)
def calculateit(base, n, tofile):
intpart = numeral(3, base)
skip = 1
if base <= 3:
skip = 2
prec = int(n*math.log(base,2))+10
print("Step 1 of 2: calculating binary value...")
t = perf_counter()
a = pi_fixed(prec, verbose=True, verbose_base=base)
step1_time = perf_counter() - t
print("Step 2 of 2: converting to specified base...")
t = perf_counter()
d = bin_to_radix(a, prec, base, n)
d = numeral(d, base, n)
step2_time = perf_counter() - t
print("\nWriting output...\n")
if tofile:
out_ = sys.stdout
sys.stdout = tofile
print("%i base-%i digits of pi:\n" % (n, base))
print(intpart, ".\n")
display_fraction(d, skip, colwidth=10, columns=5)
if tofile:
sys.stdout = out_
print("\nFinished in %f seconds (%f calc, %f convert)" % \
((step1_time + step2_time), step1_time, step2_time))
def interactive():
print("Compute digits of pi with mpmath\n")
base = input("Which base? (2-36, 10 for decimal) \n> ")
digits = input("How many digits? (enter a big number, say, 10000)\n> ")
tofile = input("Output to file? (enter a filename, or just press " \
"enter\nto print directly to the screen) \n> ")
if tofile:
tofile = open(tofile, "w")
calculateit(int(base), int(digits), tofile)
input("\nPress enter to close this script.")
if __name__ == "__main__":
interactive()
+35
View File
@@ -0,0 +1,35 @@
"""
Function plotting demo.
"""
from mpmath import *
def main():
print("""
Simple function plotting. You can enter one or several
formulas, in ordinary Python syntax and using the mpmath
function library. The variable is 'x'. So for example
the input "sin(x/2)" (without quotation marks) defines
a valid function.
""")
functions = []
for i in range(10):
if i == 0:
s = input('Enter a function: ')
else:
s = input('Enter another function (optional): ')
if not s:
print()
break
f = eval("lambda x: " + s)
functions.append(f)
print("Added f(x) = " + s)
print()
xlim = input('Enter xmin, xmax (optional): ')
if xlim:
xlim = eval(xlim)
else:
xlim = [-5, 5]
print("Plotting...")
plot(functions, xlim=xlim)
main()
+63
View File
@@ -0,0 +1,63 @@
'''
This script calculates the constant in Gerver's solution to the moving sofa
problem.
See Finch, S. R. "Moving Sofa Constant." §8.12 in Mathematical Constants.
Cambridge, England: Cambridge University Press, pp. 519-523, 2003.
'''
from mpmath import cos, sin, pi, quad, findroot, mp
mp.prec = 113
eqs = [lambda A, B, φ, θ: (A*(cos(θ) - cos(φ)) - 2*B*sin(φ)
+ (θ - φ - 1)*cos(θ) - sin(θ) + cos(φ) + sin(φ)),
lambda A, B, φ, θ: (A*(3*sin(θ) + sin(φ)) - 2*B*cos(φ)
+ 3*(θ - φ - 1)*sin(θ) + 3*cos(θ) - sin(φ) + cos(φ)),
lambda A, B, φ, θ: A*cos(φ) - (sin(φ) + 0.5 - 0.5*cos(φ) + B*sin(φ)),
lambda A, B, φ, θ: ((A + pi/2 - φ - θ) - (B - (θ - φ)*(1 + A)/2
- 0.25*(θ - φ)**2))]
A, B, φ, θ = findroot(eqs, (0, 0, 0, 0))
def r(α):
if 0 <= α < φ:
return 0.5
if φ <= α < θ:
return (1 + A + α - φ)/2
if θ <= α < pi/2 - θ:
return A + α - φ
return B - (pi/2 - α - φ)*(1 + A)/2 - (pi/2 - α - φ)**2/4
s = lambda α: 1 - r(α)
def u(α):
if φ <= α < θ:
return B - (α - φ)*(1 + A)/2 - (α - φ)**2/4
return A + pi/2 - φ - α
def du(α):
if φ <= α < θ:
return -(1 + A)/2 - (α - φ)/2
return -1
def y(α, f):
if α > pi/2 - θ:
i = [0, φ, θ, pi/2 - θ, α]
elif α > θ:
i = [0, φ, θ, α]
elif α > φ:
i = [0, φ, α]
else:
i = i = [0, α]
return 1 - quad(lambda x: f(x)*sin(x), i)
y1 = lambda α: y(α, r)
y2 = lambda α: y(α, s)
y3 = lambda α: y2(α) - u(α)*sin(α)
S1 = quad(lambda x: y1(x)*r(x)*cos(x), [0, φ, θ, pi/2 - θ, pi/2 - φ])
S2 = quad(lambda x: y2(x)*s(x)*cos(x), [0, φ, θ])
S3 = quad(lambda x: y3(x)*(u(x)*sin(x) - du(x)*cos(x) - s(x)*cos(x)),
[φ, θ, pi/4])
print(2*(S1 + S2 + S3))
+71
View File
@@ -0,0 +1,71 @@
"""
Interval arithmetic demo: estimating error of numerical Taylor series.
This module can be run interactively with
python taylor.py
"""
from mpmath import mpi, exp, factorial, mpf
def taylor(x, n):
print("-"*75)
t = x = mpi(x)
s = 1
print("adding 1")
print(s, "\n")
s += t
print("adding x")
print(s, "\n")
for k in range(2, n+1):
t = (t * x) / k
s += t
print("adding x^%i / %i! ~= %s" % (k, k, t.mid))
print(s, "\n")
print("-"*75)
return s
# Note: this should really be computed using interval arithmetic too!
def remainder(x, n):
xi = max(0, x)
r = exp(xi) / factorial(n+1)
r = r * x**(n+1)
return abs(r)
def exponential(x, n):
"""
Compute exp(x) using n terms of the Taylor series for exp using
intervals, and print detailed error analysis.
"""
t = taylor(x, n)
r = remainder(x, n)
expx = exp(x)
print("Correct value of exp(x): ", expx)
print()
print("Computed interval: ")
print(t)
print()
print("Computed value (midpoint): ", t.mid)
print()
print("Estimated rounding error: ", t.delta)
print("Estimated truncation error: ", r)
print("Estimated total error: ", t.delta + r)
print("Actual error ", abs(expx - t.mid))
print()
u = t + mpi(-r, r)
print("Interval with est. truncation error added:")
print(u)
print()
print("Correct value contained in computed interval:", t.a <= expx <= t.b)
print("When accounting for truncation error:", u.a <= expx <= u.b)
if __name__ == "__main__":
print("Interval arithmetic demo")
print()
print("This script sums the Taylor series for exp(x) using interval arithmetic,")
print("and then compares the numerical errors due to rounding and truncation.")
print()
x = mpf(input("Enter the value of x (e.g. 3.5): "))
n = int(input("Enter the number of terms n (e.g. 10): "))
print()
exponential(x, n)
+253
View File
@@ -0,0 +1,253 @@
Basic usage
===========================
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
>>> sin(1)
mpf('0.8414709848078965')
>>> import mpmath
>>> mpmath.sin(1)
mpf('0.8414709848078965')
>>> from mpmath import mp # mp context object -- to be explained
>>> mp.sin(1)
mpf('0.8414709848078965')
.. note::
Importing everything with ``from mpmath import *`` can be convenient,
especially when using mpmath interactively, but is best to avoid such
import statements in production code, as they make it unclear which
names are present in the namespace and wildcard-imported names may
conflict with other modules or variable names.
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:
>>> from mpmath import mpf, mpc, mp
>>> 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.rounding = 'n' [default: 'n']
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.1666666666666666666666666666666666666666666666666666')
>>> mp.dps = 25
>>> mpf(2) ** mpf('0.5')
mpf('1.41421356237309504880168871')
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))
1.0e+100000000000000000000000000000000000000000000000000...
The (binary) exponent is stored exactly and is independent of the precision.
The ``rounding`` property control default rounding mode for the context:
>>> mp.rounding # round to nearest is the default
'n'
>>> sin(1)
mpf('0.8414709848078965')
>>> mp.rounding = 'u' # round up
>>> sin(1)
mpf('0.84147098480789662')
>>> mp.rounding = 'n'
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
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 mpmath import extradps, workdps
>>> with workdps(20):
... 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 ``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``:
>>> from mpmath import exp, 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(1090/100) # bad, beware Python's true division produces floats
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')
To use enough digits to be able recreate value exactly, set ``mp.pretty_dps``
to ``"repr"`` (default value is ``"str"``). Same option is used to control
default number of digits in the new-style string formatting *without format
specifier*, i.e. ``format(exp(mpf(1)))``.
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:`format syntax support
<mpmath.mpf.__format__>` or functions :func:`mpmath.nstr` and
:func:`mpmath.nprint`:
>>> a = mpf(1) / 6
>>> a
mpf('0.16666666666666666')
>>> f'{a:.8}'
'0.16666667'
>>> f'{a:.50}'
'0.16666666666666665741480812812369549646973609924316'
+23
View File
@@ -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
+19
View File
@@ -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
+14
View File
@@ -0,0 +1,14 @@
Numerical calculus
==================
.. toctree::
:maxdepth: 2
polynomials
optimization
sums_limits
differentiation
integration
odes
approximation
inverselaplace
+36
View File
@@ -0,0 +1,36 @@
Numerical integration (quadrature)
----------------------------------
Standard quadrature (``quad``)
..............................
.. autofunction:: mpmath.quad
Quadrature with subdivision (``quadsubdiv``)
............................................
.. autofunction:: mpmath.quadsubdiv
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:
+71
View File
@@ -0,0 +1,71 @@
Numerical inverse Laplace transform
-----------------------------------
One-step algorithm (``invertlaplace``)
......................................
.. autofunction:: mpmath.invertlaplace
Specific algorithms
...................
Fixed Talbot algorithm
~~~~~~~~~~~~~~~~~~~~~~
.. autoclass:: mpmath.calculus.inverselaplace.FixedTalbot
:members:
Gaver-Stehfest algorithm
~~~~~~~~~~~~~~~~~~~~~~~~
.. autoclass:: mpmath.calculus.inverselaplace.Stehfest
:members:
de Hoog, Knight & Stokes algorithm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. autoclass:: mpmath.calculus.inverselaplace.deHoog
:members:
Cohen acceleration algorithm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. autoclass:: mpmath.calculus.inverselaplace.Cohen
:members:
Manual approach
...............
It is possible and sometimes beneficial to re-create some of the
functionality in ``invertlaplace``. This could be used to compute the
Laplace-space function evaluations in a different way. For example,
the Laplace-space function evaluations could be the result of a
quadrature or sum, solution to a system of ordinary differential
equations, or possibly computed in parallel from some external library
or function call.
A trivial example showing the process (which could be implemented
using the existing interface):
>>> from mpmath import calculus, convert, exp, mp
>>> myTalbot = calculus.inverselaplace.FixedTalbot(mp)
>>> t = convert(0.25)
>>> myTalbot.calc_laplace_parameter(t)
>>> fp = lambda p: 1/(p + 1) - 1/(p + 1000)
>>> ft = lambda t: exp(-t) - exp(-1000*t)
>>> fpvec = [fp(p) for p in myTalbot.p]
>>> ft(t)-myTalbot.calc_time_domain_solution(fpvec,t,manual_prec=True)
mpf('1.92830017952889006175687218e-21')
This manual approach is also useful to look at the Laplace parameter,
order, or working precision which were computed.
>>> myTalbot.degree
34
Credit
......
The numerical inverse Laplace transform functionality was contributed
to mpmath by Kristopher L. Kuhlman in 2017. The Cohen method was contributed
to mpmath by Guillermo Navas-Palencia in 2022.
+7
View File
@@ -0,0 +1,7 @@
Ordinary differential equations
-------------------------------
Solving the ODE initial value problem (``odefun``)
..................................................
.. autofunction:: mpmath.odefun
+25
View File
@@ -0,0 +1,25 @@
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
.. autoclass:: mpmath.calculus.optimization.ModAB
.. autoclass:: mpmath.calculus.optimization.Brent
+15
View File
@@ -0,0 +1,15 @@
Polynomials
-----------
See also :func:`~mpmath.taylor` and :func:`~mpmath.chebyfit` for
approximation of functions by polynomials.
Polynomial evaluation (``polyval``)
...................................
.. autofunction:: mpmath.polyval
Polynomial roots (``polyroots``)
................................
.. autofunction:: mpmath.polyroots
+67
View File
@@ -0,0 +1,67 @@
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:`~mpmath.nsum`
^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.nsum
:func:`~mpmath.sumem`
^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.sumem
:func:`~mpmath.sumap`
^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.sumap
Products
...............................
:func:`~mpmath.nprod`
^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.nprod
Limits (``limit``)
..................
:func:`~mpmath.limit`
^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.limit
Extrapolation
..........................................
The following functions provide a direct interface to
extrapolation algorithms. :func:`~mpmath.nsum` and :func:`~mpmath.limit`
essentially work by calling the following functions with an increasing
number of terms until the extrapolated limit is accurate enough.
The following functions may be useful to call directly if the
precise number of terms needed to achieve a desired accuracy is
known in advance, or if one wishes to study the convergence
properties of the algorithms.
:func:`~mpmath.richardson`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.richardson
:func:`~mpmath.shanks`
^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.shanks
:func:`~mpmath.levin`
^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.levin
:func:`~mpmath.cohen_alt`
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.cohen_alt
+8
View File
@@ -0,0 +1,8 @@
.. _cli:
Command-Line Usage
==================
When called as a program from the command line, the following form is used:
.. autoprogram:: mpmath.__main__:parser
+52
View File
@@ -0,0 +1,52 @@
"""
Mpmath documentation build configuration file.
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).
"""
import mpmath
# Add any Sphinx extension module names here, as strings.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.mathjax',
'sphinx.ext.intersphinx', 'sphinxcontrib.autoprogram',
'matplotlib.sphinxext.plot_directive']
# Sphinx will warn about all references where the target cannot be found.
nitpicky = True
# Project information.
project = mpmath.__name__
copyright = '2007-2026, Fredrik Johansson and mpmath developers'
release = version = mpmath.__version__
# Define how the current time is formatted using time.strftime().
today_fmt = '%B %d, %Y'
# The "theme" that the HTML output should use.
html_theme = 'classic'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
latex_documents = [('index', 'mpmath.tex', 'mpmath documentation',
r'Fredrik Johansson \and mpmath contributors', 'manual')]
# The name of default reST role, that is, for text marked up `like this`.
default_role = 'math'
# Contains mapping the locations and names of other projects that
# should be linked to in this documentation.
intersphinx_mapping = {
'python': ('https://docs.python.org/3/', None),
'sympy': ('https://docs.sympy.org/latest/', None),
}
plot_include_source = True
plot_formats = [('png', 96), 'pdf']
plot_html_show_formats = False
plot_html_show_source_link = False
+370
View File
@@ -0,0 +1,370 @@
Contexts
========
High-level code in mpmath is implemented as methods on a "context object". The context implements arithmetic, type conversions and other fundamental operations. The context also holds settings such as precision, and stores cache data. A few different contexts (with a mostly compatible interface) are provided so that the high-level algorithms can be used with different implementations of the underlying arithmetic, allowing different features and speed-accuracy tradeoffs. Currently, mpmath provides the following contexts:
* Arbitrary-precision arithmetic (``mp``)
* Arbitrary-precision interval arithmetic (``iv``)
* Double-precision arithmetic using Python's builtin ``float`` and ``complex`` types (``fp``)
.. note::
Using global context is not thread-safe, create instead
local contexts with e.g. :class:`~mpmath.MPContext`.
Most global functions in the global mpmath namespace are actually methods of the ``mp``
context. This fact is usually transparent to the user, but sometimes shows up in the
form of an initial parameter called "ctx" visible in the help for the function::
>>> import mpmath
>>> help(mpmath.fsum)
Help on method fsum in module mpmath.ctx_mp_python:
<BLANKLINE>
fsum(terms, absolute=False, squared=False) method of mpmath.ctx_mp.MPContext instance
Calculates a sum containing a finite number of terms (for infinite
series, see :func:`~mpmath.nsum`). The terms will be converted to
...
The following operations are equivalent::
>>> mpmath.fsum([1,2,3])
mpf('6.0')
>>> mpmath.mp.fsum([1,2,3])
mpf('6.0')
The corresponding operation using the ``fp`` context::
>>> mpmath.fp.fsum([1,2,3])
6.0
Common interface
----------------
``ctx.mpf`` creates a real number::
>>> from mpmath import mp, fp
>>> mp.mpf(3)
mpf('3.0')
>>> fp.mpf(3)
3.0
``ctx.mpc`` creates a complex number::
>>> mp.mpc(2,3)
mpc(real='2.0', imag='3.0')
>>> fp.mpc(2,3)
(2+3j)
``ctx.matrix`` creates a matrix::
>>> mp.matrix([[1,0],[0,1]])
matrix(
[['1.0', '0.0'],
['0.0', '1.0']])
>>> _[0,0]
mpf('1.0')
>>> fp.matrix([[1,0],[0,1]])
matrix(
[['1.0', '0.0'],
['0.0', '1.0']])
>>> _[0,0]
1.0
``ctx.prec`` holds the current precision (in bits)::
>>> mp.prec
53
>>> fp.prec
53
``ctx.dps`` holds the current precision (in digits)::
>>> mp.dps
15
>>> fp.dps
15
``ctx.pretty`` controls whether objects should be pretty-printed automatically by :func:`repr`. Pretty-printing for ``mp`` numbers is disabled by default so that they can clearly be distinguished from Python numbers and so that ``eval(repr(x)) == x`` works::
>>> mp.mpf(3)
mpf('3.0')
>>> mpf = mp.mpf
>>> eval(repr(mp.mpf(3)))
mpf('3.0')
>>> mp.pretty = True
>>> mp.mpf(3)
3.0
>>> fp.matrix([[1,0],[0,1]])
matrix(
[['1.0', '0.0'],
['0.0', '1.0']])
>>> fp.pretty = True
>>> fp.matrix([[1,0],[0,1]])
[1.0 0.0]
[0.0 1.0]
>>> fp.pretty = False
Arbitrary-precision floating-point (``mp``)
---------------------------------------------
The ``mp`` context is what most users probably want to use most of the time, as it supports the most functions, is most well-tested, and is implemented with a high level of optimization. Nearly all examples in this documentation use ``mp`` functions.
See :doc:`basics` for a description of basic usage.
.. autoclass:: mpmath.MPContext
Local contexts, created on demand, could be used just as the global ``mp``:
>>> from mpmath import MPContext
>>> ctx = MPContext()
>>> ctx.sin(1)
mpf('0.8414709848078965')
>>> ctx.prec = 113
>>> ctx.sin(1)
mpf('0.841470984807896506652502321630298954')
Arbitrary-precision interval arithmetic (``iv``)
------------------------------------------------
The ``iv.mpf`` type represents a closed interval `[a,b]`; that is, the set `\{x : a \le x \le b\}`, where `a` and `b` are arbitrary-precision floating-point values, possibly `\pm \infty`. The ``iv.mpc`` type represents a rectangular complex interval `[a,b] + [c,d]i`; that is, the set `\{z = x+iy : a \le x \le b \land c \le y \le d\}`.
Interval arithmetic provides rigorous error tracking. If `f` is a mathematical function and `\hat f` is its interval arithmetic version, then the basic guarantee of interval arithmetic is that `f(v) \subseteq \hat f(v)` for any input interval `v`. Put differently, if an interval represents the known uncertainty for a fixed number, any sequence of interval operations will produce an interval that contains what would be the result of applying the same sequence of operations to the exact number. The principal drawbacks of interval arithmetic are speed (``iv`` arithmetic is typically at least two times slower than ``mp`` arithmetic) and that it sometimes provides far too pessimistic bounds.
.. note ::
The support for interval arithmetic in mpmath is still experimental, and many functions
do not yet properly support intervals. Please use this feature with caution.
Intervals can be created from single numbers (treated as zero-width intervals) or pairs of endpoint numbers. Strings are treated as exact decimal numbers. Note that a Python float like ``0.1`` generally does not represent the same number as its literal; use ``'0.1'`` instead::
>>> from mpmath import iv
>>> iv.mpf(3)
mpi('3.0', '3.0')
>>> print(iv.mpf(3))
[3.0, 3.0]
>>> iv.pretty = True
>>> iv.mpf([2,3])
[2.0, 3.0]
>>> iv.mpf(0.1) # probably not intended
[0.10000000000000000555, 0.10000000000000000555]
>>> iv.mpf('0.1') # good, gives a containing interval
[0.099999999999999991673, 0.10000000000000000555]
>>> iv.mpf(['0.1', '0.2'])
[0.099999999999999991673, 0.2000000000000000111]
The fact that ``'0.1'`` results in an interval of nonzero width indicates that 1/10 cannot be represented using binary floating-point numbers at this precision level (in fact, it cannot be represented exactly at any precision).
Intervals may be infinite or half-infinite::
>>> print(1 / iv.mpf([2, 'inf']))
[0.0, 0.5]
The equality testing operators ``==`` and ``!=`` check whether their operands
are identical as intervals; that is, have the same endpoints. The ordering
operators ``< <= > >=`` permit inequality testing using triple-valued logic: a
guaranteed inequality returns ``True`` or ``False`` while an indeterminate
inequality raises :exc:`ValueError`::
>>> iv.mpf([1,2]) == iv.mpf([1,2])
True
>>> iv.mpf([1,2]) != iv.mpf([1,2])
False
>>> iv.mpf([1,2]) <= 2
True
>>> iv.mpf([1,2]) > 0
True
>>> iv.mpf([1,2]) < 1
False
>>> iv.mpf([1,2]) < 2
Traceback (most recent call last):
...
ValueError
>>> iv.mpf([2,2]) < 2
False
>>> iv.mpf([1,2]) <= iv.mpf([2,3])
True
>>> iv.mpf([1,2]) < iv.mpf([2,3])
Traceback (most recent call last):
...
ValueError
>>> iv.mpf([1,2]) < iv.mpf([-1,0])
False
The ``in`` operator tests whether a number or interval is contained in another interval::
>>> iv.mpf([0,2]) in iv.mpf([0,10])
True
>>> 3 in iv.mpf(['-inf', 0])
False
Intervals have the properties ``.a``, ``.b`` (endpoints), ``.mid``, and ``.delta`` (width)::
>>> x = iv.mpf([2, 5])
>>> x.a
[2.0, 2.0]
>>> x.b
[5.0, 5.0]
>>> x.mid
[3.5, 3.5]
>>> x.delta
[3.0, 3.0]
Some transcendental functions are supported::
>>> iv.dps = 15
>>> mp.dps = 15
>>> iv.mpf([0.5,1.5]) ** iv.mpf([0.5, 1.5])
[0.35355339059327373086, 1.837117307087383633]
>>> iv.exp(0)
[1.0, 1.0]
>>> iv.exp(['-inf','inf'])
[0.0, inf]
>>>
>>> iv.exp(['-inf',0])
[0.0, 1.0]
>>> iv.exp([0,'inf'])
[1.0, inf]
>>> iv.exp([0,1])
[1.0, 2.7182818284590455349]
>>>
>>> iv.log(1)
[0.0, 0.0]
>>> iv.log([0,1])
[-inf, 0.0]
>>> iv.log([0,'inf'])
[-inf, inf]
>>> iv.log(2)
[0.69314718055994528623, 0.69314718055994539725]
>>>
>>> iv.sin([100,'inf'])
[-1.0, 1.0]
>>> iv.cos(['-0.1','0.1'])
[0.99500416527802570954, 1.0]
Interval arithmetic is useful for proving inequalities involving irrational numbers.
Naive use of ``mp`` arithmetic may result in wrong conclusions, such as the following::
>>> mp.dps = 25
>>> x = mp.exp(mp.pi*mp.sqrt(163))
>>> y = mp.mpf(640320**3+744)
>>> print(x)
262537412640768744.0000001
>>> print(y)
262537412640768744.0
>>> x > y
True
But the correct result is `e^{\pi \sqrt{163}} < 262537412640768744`, as can be
seen by increasing the precision::
>>> mp.dps = 50
>>> print(mp.exp(mp.pi*mp.sqrt(163)))
262537412640768743.99999999999925007259719818568888
With interval arithmetic, the comparison raises :exc:`ValueError` until the
precision is large enough for `x-y` to have a definite sign::
>>> iv.dps = 15
>>> iv.exp(iv.pi*iv.sqrt(163)) > (640320**3+744)
Traceback (most recent call last):
...
ValueError
>>> iv.dps = 30
>>> iv.exp(iv.pi*iv.sqrt(163)) > (640320**3+744)
Traceback (most recent call last):
...
ValueError
>>> iv.dps = 60
>>> iv.exp(iv.pi*iv.sqrt(163)) > (640320**3+744)
False
>>> iv.dps = 15
Fast low-precision arithmetic (``fp``)
---------------------------------------------
Although mpmath is generally designed for arbitrary-precision arithmetic, many of the high-level algorithms work perfectly well with ordinary Python ``float`` and ``complex`` numbers, which use hardware double precision (on most systems, this corresponds to 53 bits of precision). Whereas the global functions (which are methods of the ``mp`` object) always convert inputs to mpmath numbers, the ``fp`` object instead converts them to ``float`` or ``complex``, and in some cases employs basic functions optimized for double precision. When large amounts of function evaluations (numerical integration, plotting, etc) are required, and when ``fp`` arithmetic provides sufficient accuracy, this can give a significant speedup over ``mp`` arithmetic.
To take advantage of this feature, simply use the ``fp`` prefix, i.e. write ``fp.func`` instead of ``func`` or ``mp.func``::
>>> u = fp.erfc(0.5)
>>> print(u)
0.4795001221869535
>>> type(u)
<class 'float'>
>>> mp.dps = 16
>>> print(mp.erfc(0.5))
0.4795001221869535
>>> fp.matrix([[1,2],[3,4]]) ** 2
matrix(
[['7.0', '10.0'],
['15.0', '22.0']])
>>>
>>> type(_[0,0])
<class 'float'>
>>> print(fp.quad(fp.sin, [0, fp.pi])) # numerical integration
2.0
The ``fp`` context wraps Python's ``math`` and ``cmath`` modules for elementary functions. It supports both real and complex numbers and automatically generates complex results for real inputs (``math`` raises an exception)::
>>> fp.sqrt(5)
2.23606797749979
>>> fp.sqrt(-5)
2.23606797749979j
>>> fp.sin(10)
-0.5440211108893698
>>> fp.power(-1, 0.25)
(0.7071067811865476+0.7071067811865475j)
>>> (-1) ** 0.25
(0.7071067811865476+0.7071067811865475j)
The ``prec`` and ``dps`` attributes can be changed (for interface compatibility with the ``mp`` context) but this has no effect::
>>> fp.prec
53
>>> fp.dps
15
>>> fp.prec = 80
>>> fp.prec
53
>>> fp.dps
15
Due to intermediate rounding and cancellation errors, results computed with ``fp`` arithmetic may be much less accurate than those computed with ``mp`` using an equivalent precision (``mp.prec = 53``), since the latter often uses increased internal precision. The accuracy is highly problem-dependent: for some functions, ``fp`` almost always gives 14-15 correct digits; for others, results can be accurate to only 2-3 digits or even completely wrong. The recommended use for ``fp`` is therefore to speed up large-scale computations where accuracy can be verified in advance on a subset of the input set, or where results can be verified afterwards.
Beware that the ``fp`` context has signed zero, that can be used to distinguish
different sides of branch cuts. For example, ``fp.mpc(-1, -0.0)`` is treated
as though it lies *below* the branch cut for :func:`~mpmath.sqrt()`::
>>> fp.sqrt(fp.mpc(-1, -0.0))
-1j
>>> fp.sqrt(fp.mpc(-1, -1e-10))
(5e-11-1j)
But an argument of ``fp.mpc(-1, 0.0)`` is treated as though it lies *above* the
branch cut::
>>> fp.sqrt(fp.mpc(-1, +0.0))
1j
>>> fp.sqrt(fp.mpc(-1, +1e-10))
(5e-11+1j)
While near the branch cut, for small but nonzero deviations in components
results agreed with the ``mp`` contexts::
>>> fp.mpc(mp.sqrt(mp.mpc(-1, -1e-10)))
(5e-11-1j)
>>> fp.mpc(mp.sqrt(mp.mpc(-1, +1e-10)))
(5e-11+1j)
one has no signed zeros and allows to specify result *on the branch cut*
(nonpositive part of the real axis in this example)::
>>> fp.mpc(mp.sqrt(mp.mpc(-1, 0)))
1j
>>> fp.mpc(mp.sqrt(-1))
1j
Here it's continuous from the above of the :func:`~mpmath.sqrt()` branch
cut (from ``0`` along the negative real axis to the negative infinity).
+108
View File
@@ -0,0 +1,108 @@
Bessel functions and related functions
--------------------------------------
The functions in this section arise as solutions to various differential
equations in physics, typically describing wavelike oscillatory behavior or a
combination of oscillation and exponential decay or growth. Mathematically,
they are special cases of the confluent hypergeometric functions `\,_0F_1`,
`\,_1F_1` and `\,_1F_2` (see :doc:`hypergeometric`).
Bessel functions
................
.. autofunction:: mpmath.besselj
.. autofunction:: mpmath.j0
.. autofunction:: mpmath.j1
.. autofunction:: mpmath.bessely
.. autofunction:: mpmath.besseli
.. autofunction:: mpmath.besselk
Bessel function zeros
.....................
.. autofunction:: mpmath.besseljzero
.. autofunction:: mpmath.besselyzero
Hankel functions
................
.. autofunction:: mpmath.hankel1
.. autofunction:: mpmath.hankel2
Spherical Bessel functions
..........................
.. autofunction:: mpmath.spherical_jn
.. autofunction:: mpmath.spherical_yn
.. autofunction:: mpmath.spherical_in
.. autofunction:: mpmath.spherical_kn
Kelvin functions
................
.. autofunction:: mpmath.ber
.. autofunction:: mpmath.bei
.. autofunction:: mpmath.ker
.. autofunction:: mpmath.kei
Struve functions
................
.. autofunction:: mpmath.struveh
.. autofunction:: mpmath.struvel
Anger-Weber functions
.....................
.. autofunction:: mpmath.angerj
.. autofunction:: mpmath.webere
Lommel functions
................
.. autofunction:: mpmath.lommels1
.. autofunction:: mpmath.lommels2
Airy and Scorer functions
.........................
.. autofunction:: mpmath.airyai
.. autofunction:: mpmath.airybi
.. autofunction:: mpmath.airyaizero
.. autofunction:: mpmath.airybizero
.. autofunction:: mpmath.scorergi
.. autofunction:: mpmath.scorerhi
Coulomb wave functions
......................
.. autofunction:: mpmath.coulombf
.. autofunction:: mpmath.coulombg
.. autofunction:: mpmath.coulombc
Confluent U and Whittaker functions
...................................
.. autofunction:: mpmath.hyperu(a, b, z)
.. autofunction:: mpmath.whitm(k,m,z)
.. autofunction:: mpmath.whitw(k,m,z)
Parabolic cylinder functions
............................
.. autofunction:: mpmath.pcfd
.. autofunction:: mpmath.pcfu
.. autofunction:: mpmath.pcfv
.. autofunction:: mpmath.pcfw
+45
View File
@@ -0,0 +1,45 @@
Mathematical constants
----------------------
Mpmath supports arbitrary-precision computation of various common (and less
common) mathematical constants. These constants are implemented as lazy
objects that can evaluate to any precision. Whenever the objects are used as
function arguments or as operands in arithmetic operations, they automagically
evaluate to the current working precision. A lazy number can be converted to a
regular ``mpf`` using the unary ``+`` operator, or by calling it as a
function::
>>> from mpmath import pi, mp
>>> pi
<pi: 3.14159~>
>>> 2*pi
mpf('6.2831853071795862')
>>> +pi
mpf('3.1415926535897931')
>>> pi()
mpf('3.1415926535897931')
>>> mp.dps = 40
>>> pi
<pi: 3.14159~>
>>> 2*pi
mpf('6.28318530717958647692528676655900576839434')
>>> +pi
mpf('3.14159265358979323846264338327950288419717')
>>> pi()
mpf('3.14159265358979323846264338327950288419717')
The predefined objects ``j`` (imaginary unit), ``inf`` (positive infinity) and
``nan`` (not-a-number) are shortcuts to ``mpc`` and ``mpf`` instances with
these fixed values.
.. autofunction:: mpmath.mp.pi
.. autoattribute:: mpmath.mp.degree
.. autoattribute:: mpmath.mp.e
.. autoattribute:: mpmath.mp.phi
.. autofunction:: mpmath.mp.euler
.. autoattribute:: mpmath.mp.catalan
.. autoattribute:: mpmath.mp.apery
.. autoattribute:: mpmath.mp.khinchin
.. autoattribute:: mpmath.mp.glaisher
.. autoattribute:: mpmath.mp.mertens
.. autoattribute:: mpmath.mp.twinprime
+65
View File
@@ -0,0 +1,65 @@
Elliptic functions
------------------
.. automodule:: mpmath.functions.elliptic
:no-index:
Elliptic arguments
..................
.. autofunction:: mpmath.qfrom
.. autofunction:: mpmath.qbarfrom
.. autofunction:: mpmath.mfrom
.. autofunction:: mpmath.kfrom
.. autofunction:: mpmath.taufrom
Legendre elliptic integrals
...........................
.. autofunction:: mpmath.ellipk
.. autofunction:: mpmath.ellipf
.. autofunction:: mpmath.ellipe
.. autofunction:: mpmath.ellippi
Carlson symmetric elliptic integrals
....................................
.. autofunction:: mpmath.elliprf
.. autofunction:: mpmath.elliprc
.. autofunction:: mpmath.elliprj
.. autofunction:: mpmath.elliprd
.. autofunction:: mpmath.elliprg
Jacobi theta functions
......................
.. autofunction:: mpmath.jtheta
Jacobi elliptic functions
.........................
.. autofunction:: mpmath.ellipfun
Weierstrass elliptic functions
..............................
.. autofunction:: mpmath.weierinvariants
.. autofunction:: mpmath.weierhalfperiods
.. autofunction:: mpmath.weierp
.. autofunction:: mpmath.weierpprime
.. autofunction:: mpmath.weiersigma
.. autofunction:: mpmath.weierzeta
.. autofunction:: mpmath.weierpinv
Modular functions
.................
.. autofunction:: mpmath.eta
.. autofunction:: mpmath.kleinj
+70
View File
@@ -0,0 +1,70 @@
Exponential integrals and error functions
-----------------------------------------
Exponential integrals give closed-form solutions to a large class of commonly
occurring transcendental integrals that cannot be evaluated using elementary
functions. Integrals of this type include those with an integrand of the form
`t^a e^{t}` or `e^{-x^2}`, the latter giving rise to the Gaussian (or normal)
probability distribution.
The most general function in this section is the incomplete gamma function, to
which all others can be reduced. The incomplete gamma function, in turn, can
be expressed using hypergeometric functions (see :doc:`hypergeometric`).
Incomplete gamma functions
..........................
.. autofunction:: mpmath.gammainc
.. autofunction:: mpmath.lower_gamma
.. autofunction:: mpmath.upper_gamma
Exponential integrals
.....................
.. autofunction:: mpmath.ei
.. autofunction:: mpmath.e1
.. autofunction:: mpmath.expint
Logarithmic integral
....................
.. autofunction:: mpmath.li
Trigonometric integrals
.......................
.. autofunction:: mpmath.ci
.. autofunction:: mpmath.si
Hyperbolic integrals
....................
.. autofunction:: mpmath.chi
.. autofunction:: mpmath.shi
Error functions
...............
.. autofunction:: mpmath.erf
.. autofunction:: mpmath.erfc
.. autofunction:: mpmath.erfi
.. autofunction:: mpmath.erfinv
The normal distribution
.......................
.. autofunction:: mpmath.npdf
.. autofunction:: mpmath.ncdf
Fresnel integrals
.................
.. autofunction:: mpmath.fresnels
.. autofunction:: mpmath.fresnelc
+79
View File
@@ -0,0 +1,79 @@
Factorials and gamma functions
------------------------------
Factorials and factorial-like sums and products are basic tools of
combinatorics and number theory. Much like the exponential function is
fundamental to differential equations and analysis in general, the factorial
function (and its extension to complex numbers, the gamma function) is
fundamental to difference equations and functional equations.
A large selection of factorial-like functions is implemented in mpmath. All
functions support complex arguments, and arguments may be arbitrarily large.
Results are numerical approximations, so to compute *exact* values a high
enough precision must be set manually::
>>> from mpmath import mp, fac
>>> mp.dps = 15
>>> mp.pretty = True
>>> fac(100)
9.33262154439442e+157
>>> print(int(_)) # most digits are wrong
93326215443944150965646704795953882578400970373184098831012889540582227238570431295066113089288327277825849664006524270554535976289719382852181865895959724032
>>> mp.dps = 160
>>> fac(100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000.0
The gamma and polygamma functions are closely related to :doc:`zeta`. See also
:doc:`qfunctions` for q-analogs of factorial-like functions.
Factorials
..........
.. autofunction:: mpmath.factorial
.. autofunction:: mpmath.fac2
Binomial coefficients
.....................
.. autofunction:: mpmath.binomial
Gamma function
..............
.. autofunction:: mpmath.gamma
.. autofunction:: mpmath.rgamma
.. autofunction:: mpmath.gammaprod
.. autofunction:: mpmath.loggamma
Rising and falling factorials
.............................
.. autofunction:: mpmath.rf
.. autofunction:: mpmath.ff
Beta function
.............
.. autofunction:: mpmath.beta
.. autofunction:: mpmath.betainc
Super- and hyperfactorials
..........................
.. autofunction:: mpmath.superfac
.. autofunction:: mpmath.hyperfac
.. autofunction:: mpmath.barnesg
Polygamma functions and harmonic numbers
........................................
.. autofunction:: mpmath.psi
.. autofunction:: mpmath.digamma
.. autofunction:: mpmath.harmonic
+23
View File
@@ -0,0 +1,23 @@
Hyperbolic functions
--------------------
Hyperbolic functions
....................
.. autofunction:: mpmath.cosh
.. autofunction:: mpmath.sinh
.. autofunction:: mpmath.tanh
.. autofunction:: mpmath.sech
.. autofunction:: mpmath.csch
.. autofunction:: mpmath.coth
Inverse hyperbolic functions
............................
.. autofunction:: mpmath.acosh
.. autofunction:: mpmath.asinh
.. autofunction:: mpmath.atanh
.. autofunction:: mpmath.asech
.. autofunction:: mpmath.acsch
.. autofunction:: mpmath.acoth
+74
View File
@@ -0,0 +1,74 @@
Hypergeometric functions
------------------------
The functions listed in :doc:`expintegrals`, :doc:`bessel` and
:doc:`orthogonal`, and many other functions as well, are merely particular
instances of the generalized hypergeometric function `\,_pF_q`. The functions
listed in the following section enable efficient direct evaluation of the
underlying hypergeometric series, as well as linear combinations, limits with
respect to parameters, and analytic continuations thereof. Extensions to
twodimensional series are also provided. See also the basic or q-analog of the
hypergeometric series in :doc:`qfunctions`.
For convenience, most of the hypergeometric series of low order are provided as
standalone functions. They can equivalently be evaluated using
:func:`~mpmath.hyper`. As will be demonstrated in the respective docstrings,
all the ``hyp#f#`` functions implement analytic continuations and/or asymptotic
expansions with respect to the argument `z`, thereby permitting evaluation for
`z` anywhere in the complex plane. Functions of higher degree can be computed
via :func:`~mpmath.hyper`, but generally only in rapidly convergent instances.
Most hypergeometric and hypergeometric-derived functions accept optional
keyword arguments to specify options for :func:`~mpmath.hypercomb` or
:func:`~mpmath.hyper`. Some useful options are *maxprec*, *maxterms*,
*zeroprec*, *accurate_small*, *hmag*, *force_series*, *asymp_tol* and
*eliminate*. These options give control over what to do in case of slow
convergence, extreme loss of accuracy or evaluation at zeros (these two cases
cannot generally be distinguished from each other automatically), and singular
parameter combinations.
Common hypergeometric series
............................
.. autofunction:: mpmath.hyp0f1
.. autofunction:: mpmath.hyp1f1
.. autofunction:: mpmath.hyp1f2
.. autofunction:: mpmath.hyp2f0
.. autofunction:: mpmath.hyp2f1
.. autofunction:: mpmath.hyp2f2
.. autofunction:: mpmath.hyp2f3
.. autofunction:: mpmath.hyp3f2
Generalized hypergeometric functions
....................................
.. autofunction:: mpmath.hyper
.. autofunction:: mpmath.hypercomb
Meijer G-function
.................
.. autofunction:: mpmath.meijerg
Fox H-function
.................
.. autofunction:: mpmath.foxh
Bilateral hypergeometric series
...............................
.. autofunction:: mpmath.bihyper
Hypergeometric functions of two variables
.........................................
.. autofunction:: mpmath.hyper2d
.. autofunction:: mpmath.appellf1
.. autofunction:: mpmath.appellf2
.. autofunction:: mpmath.appellf3
.. autofunction:: mpmath.appellf4
+22
View File
@@ -0,0 +1,22 @@
Mathematical functions
======================
Mpmath implements the standard functions from Python's ``math`` and ``cmath`` modules, for both real and complex numbers and with arbitrary precision. Many other functions are also available in mpmath, including commonly-used variants of standard functions (such as the alternative trigonometric functions sec, csc, cot), but also a large number of "special functions" such as the gamma function, the Riemann zeta function, error functions, Bessel functions, etc.
.. toctree::
:maxdepth: 2
constants
powers
trigonometric
hyperbolic
signals
gamma
expintegrals
bessel
orthogonal
hypergeometric
elliptic
zeta
numtheory
qfunctions
+58
View File
@@ -0,0 +1,58 @@
Number-theoretical, combinatorial and integer functions
-------------------------------------------------------
For factorial-type functions, including binomial coefficients, double
factorials, etc, see the separate section :doc:`gamma`.
Fibonacci numbers
.................
.. autofunction:: mpmath.fibonacci
Bernoulli numbers and polynomials
.................................
.. autofunction:: mpmath.bernoulli
.. autofunction:: mpmath.bernfrac
.. autofunction:: mpmath.bernpoly
Euler numbers and polynomials
.............................
.. autofunction:: mpmath.eulernum
.. autofunction:: mpmath.eulerpoly
Bell numbers and polynomials
............................
.. autofunction:: mpmath.bell
Stirling numbers
................
.. autofunction:: mpmath.stirling1
.. autofunction:: mpmath.stirling2
Prime counting functions
........................
.. autofunction:: mpmath.primepi
.. autofunction:: mpmath.primepi2
.. autofunction:: mpmath.riemannr
Cyclotomic polynomials
......................
.. autofunction:: mpmath.cyclotomic
Arithmetic functions
......................
.. autofunction:: mpmath.mangoldt
+77
View File
@@ -0,0 +1,77 @@
Orthogonal polynomials
----------------------
An orthogonal polynomial sequence is a sequence of polynomials `P_0(x), P_1(x),
\ldots` of degree `0, 1, \ldots`, which are mutually orthogonal in the sense
that
.. math ::
\int_S P_n(x) P_m(x) w(x) dx =
\begin{cases}
c_n \ne 0 & \text{if $m = n$} \\
0 & \text{if $m \ne n$}
\end{cases}
where `S` is some domain (e.g. an interval `[a,b] \in \mathbb{R}`) and `w(x)`
is a fixed *weight function*. A sequence of orthogonal polynomials is
determined completely by `w`, `S`, and a normalization convention (e.g. `c_n =
1`). Applications of orthogonal polynomials include function approximation and
solution of differential equations.
Orthogonal polynomials are sometimes defined using the differential equations
they satisfy (as functions of `x`) or the recurrence relations they satisfy
with respect to the order `n`. Other ways of defining orthogonal polynomials
include differentiation formulas and generating functions. The standard
orthogonal polynomials can also be represented as hypergeometric series (see
:doc:`hypergeometric`), more specifically using the Gauss hypergeometric
function `\,_2F_1` in most cases. The following functions are generally
implemented using hypergeometric functions since this is computationally
efficient and easily generalizes.
For more information, see the `Wikipedia article on orthogonal polynomials
<http://en.wikipedia.org/wiki/Orthogonal_polynomials>`_.
Legendre functions
..................
.. autofunction:: mpmath.legendre
.. autofunction:: mpmath.legenp
.. autofunction:: mpmath.legenq
Chebyshev polynomials
.....................
.. autofunction:: mpmath.chebyt
.. autofunction:: mpmath.chebyu
Jacobi polynomials
..................
.. autofunction:: mpmath.jacobi
Gegenbauer polynomials
......................
.. autofunction:: mpmath.gegenbauer
Hermite polynomials
...................
.. autofunction:: mpmath.hermite
Laguerre polynomials
....................
.. autofunction:: mpmath.laguerre
Spherical harmonics
...................
.. autofunction:: mpmath.spherharm
+45
View File
@@ -0,0 +1,45 @@
Powers and logarithms
---------------------
Nth roots
.........
.. autofunction:: mpmath.sqrt
.. autofunction:: mpmath.hypot
.. autofunction:: mpmath.cbrt
.. autofunction:: mpmath.root
.. autofunction:: mpmath.unitroots
Exponentiation
..............
.. autofunction:: mpmath.exp
.. autofunction:: mpmath.exp2
.. autofunction:: mpmath.power
.. autofunction:: mpmath.expj
.. autofunction:: mpmath.expjpi
.. autofunction:: mpmath.expm1(x)
.. autofunction:: mpmath.powm1(x, y)
Logarithms
..........
.. autofunction:: mpmath.log
.. autofunction:: mpmath.ln
.. autofunction:: mpmath.log2
.. autofunction:: mpmath.log10
.. autofunction:: mpmath.log1p(x)
Lambert W function
..................
.. autofunction:: mpmath.lambertw
Arithmetic-geometric mean
.........................
.. autofunction:: mpmath.agm
+20
View File
@@ -0,0 +1,20 @@
q-functions
-----------
q-Pochhammer symbol
...................
.. autofunction:: mpmath.qp
q-gamma and factorial
.....................
.. autofunction:: mpmath.qgamma
.. autofunction:: mpmath.qfac
Hypergeometric q-series
.......................
.. autofunction:: mpmath.qhyper
+34
View File
@@ -0,0 +1,34 @@
Signal functions
----------------
The functions in this section describe non-sinusoidal waveforms, which are
often used in signal processing and electronics.
Square wave signal
..................
.. autofunction:: mpmath.squarew
Triangle wave signal
....................
.. autofunction:: mpmath.trianglew
Sawtooth wave signal
....................
.. autofunction:: mpmath.sawtoothw
Unit triangle signal
....................
.. autofunction:: mpmath.unit_triangle
Sigmoid wave signal
.....................
.. autofunction:: mpmath.sigmoid
+62
View File
@@ -0,0 +1,62 @@
Trigonometric functions
-----------------------
Except where otherwise noted, the trigonometric functions take a radian angle
as input and the inverse trigonometric functions return radian angles.
The ordinary trigonometric functions are single-valued functions defined
everywhere in the complex plane (except at the poles of tan, sec, csc, and
cot). They are defined generally via the exponential function, e.g.
.. math ::
\cos(x) = \frac{e^{ix} + e^{-ix}}{2}.
The inverse trigonometric functions are multivalued, thus requiring branch
cuts, and are generally real-valued only on a part of the real line.
Definitions and branch cuts are given in the documentation of each function.
The branch cut conventions used by mpmath are essentially the same as those
found in most standard mathematical software, such as Mathematica and Python's
own ``cmath`` libary.
Degree-radian conversion
........................
.. autofunction:: mpmath.degrees
.. autofunction:: mpmath.radians
Trigonometric functions
.......................
.. autofunction:: mpmath.cos
.. autofunction:: mpmath.sin
.. autofunction:: mpmath.tan
.. autofunction:: mpmath.sec
.. autofunction:: mpmath.csc
.. autofunction:: mpmath.cot
Trigonometric functions with modified argument
..............................................
.. autofunction:: mpmath.cospi
.. autofunction:: mpmath.sinpi
Inverse trigonometric functions
...............................
.. autofunction:: mpmath.acos
.. autofunction:: mpmath.asin
.. autofunction:: mpmath.atan
.. autofunction:: mpmath.atan2
.. autofunction:: mpmath.asec
.. autofunction:: mpmath.acsc
.. autofunction:: mpmath.acot
Sinc function
.............
.. autofunction:: mpmath.sinc
.. autofunction:: mpmath.sincpi
+60
View File
@@ -0,0 +1,60 @@
Zeta functions, L-series and polylogarithms
-------------------------------------------
This section includes the Riemann zeta functions and associated functions
pertaining to analytic number theory.
Riemann and Hurwitz zeta functions
..................................
.. autofunction:: mpmath.zeta
Dirichlet L-series
..................
.. autofunction:: mpmath.altzeta
.. autofunction:: mpmath.dirichlet
Stieltjes constants
...................
.. autofunction:: mpmath.stieltjes
Zeta function zeros
...................
These functions are used for the study of the Riemann zeta function in the
critical strip.
.. autofunction:: mpmath.zetazero
.. autofunction:: mpmath.nzeros
.. autofunction:: mpmath.siegelz
.. autofunction:: mpmath.siegeltheta
.. autofunction:: mpmath.grampoint
.. autofunction:: mpmath.backlunds
Lerch transcendent
..................
.. autofunction:: mpmath.lerchphi
Polylogarithms and Clausen functions
....................................
.. autofunction:: mpmath.polylog
.. autofunction:: mpmath.clsin
.. autofunction:: mpmath.clcos
.. autofunction:: mpmath.polyexp
Zeta function variants
......................
.. autofunction:: mpmath.primezeta
.. autofunction:: mpmath.secondzeta
+240
View File
@@ -0,0 +1,240 @@
Utility functions
===============================================
This page lists functions that perform basic operations
on numbers or aid general programming.
Conversion and printing
-----------------------
:func:`~mpmath.mpmathify` / ``convert()``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.mpmathify
:func:`~mpmath.nstr`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.nstr
:func:`~mpmath.nprint`
^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.nprint
:func:`mpmath.mpf.__format__`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.mpf.__format__
:func:`mpmath.mpc.__format__`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.mpc.__format__
Arithmetic operations
---------------------
See also :func:`mpmath.sqrt`, :func:`mpmath.exp` etc., listed
in :doc:`functions/powers`
:func:`~mpmath.fadd`
^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fadd
:func:`~mpmath.fsub`
^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fsub
:func:`~mpmath.fneg`
^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fneg
:func:`~mpmath.fmul`
^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fmul
:func:`~mpmath.fdiv`
^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fdiv
:func:`~mpmath.fmod`
^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fmod
:func:`~mpmath.fsum`
^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fsum
:func:`~mpmath.fprod`
^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fprod
:func:`~mpmath.fdot`
^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fdot
Complex components
------------------
:func:`~mpmath.fabs`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fabs
:func:`~mpmath.sign`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.sign
:func:`~mpmath.re`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.re
:func:`~mpmath.im`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.im
:func:`~mpmath.arg`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.arg
:func:`~mpmath.conj`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.conj
:func:`~mpmath.polar`
^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.polar
:func:`~mpmath.rect`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.rect
Integer and fractional parts
-----------------------------
:func:`~mpmath.floor`
^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.floor
:func:`~mpmath.ceil`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.ceil
:func:`~mpmath.nint`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.nint
:func:`~mpmath.frac`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.frac
Tolerances and approximate comparisons
--------------------------------------
:func:`~mpmath.chop`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.chop
:func:`~mpmath.almosteq`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.almosteq
Properties of numbers
-------------------------------------
:func:`~mpmath.isinf`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.isinf
:func:`~mpmath.isnan`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.isnan
:func:`~mpmath.isnormal`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.isnormal
:func:`~mpmath.isfinite`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.isfinite
:func:`~mpmath.isint`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.isint
:func:`~mpmath.ldexp`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.ldexp
:func:`~mpmath.frexp`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.frexp
:func:`~mpmath.mag`
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.mag
:func:`~mpmath.nint_distance`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.nint_distance
.. :func:`~mpmath.absmin`
.. ^^^^^^^^^^^^^^^^^^^^^^^^
.. .. autofunction:: mpmath.absmin(x)
.. .. autofunction:: mpmath.absmax(x)
Number generation
-----------------
:func:`~mpmath.fraction`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.fraction
:func:`~mpmath.rand`
^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.rand
:func:`~mpmath.arange`
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.arange
:func:`~mpmath.linspace`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.linspace
Precision management
--------------------
:func:`~mpmath.autoprec`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.autoprec
:func:`~mpmath.workprec`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.workprec
:func:`~mpmath.workdps`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.workdps
:func:`~mpmath.extraprec`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.extraprec
:func:`~mpmath.extradps`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.extradps
Performance and debugging
------------------------------------
:func:`~mpmath.memoize`
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.memoize
:func:`~mpmath.maxcalls`
^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.maxcalls
:func:`~mpmath.monitor`
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.monitor
:func:`~mpmath.timing`
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.timing
+2
View File
@@ -0,0 +1,2 @@
Index
=====
+31
View File
@@ -0,0 +1,31 @@
Number identification
=====================
Most function in mpmath are concerned with producing approximations from exact mathematical formulas. It is also useful to consider the inverse problem: given only a decimal approximation for a number, such as 0.7320508075688772935274463, is it possible to find an exact formula?
Subject to certain restrictions, such "reverse engineering" is indeed possible thanks to the existence of *integer relation algorithms*. Mpmath implements the PSLQ algorithm (developed by H. Ferguson), which is one such algorithm.
Automated number recognition based on PSLQ is not a silver bullet. Any occurring transcendental constants (`\pi`, `e`, etc) must be guessed by the user, and the relation between those constants in the formula must be linear (such as `x = 3 \pi + 4 e`). More complex formulas can be found by combining PSLQ with functional transformations; however, this is only feasible to a limited extent since the computation time grows exponentially with the number of operations that need to be combined.
The number identification facilities in mpmath are inspired by the `Inverse Symbolic Calculator <http://wayback.cecm.sfu.ca/projects/ISC/ISCmain.html>`_ (ISC). The ISC is more powerful than mpmath, as it uses a lookup table of millions of precomputed constants (thereby mitigating the problem with exponential complexity).
Constant recognition
-----------------------------------
:func:`~mpmath.identify`
^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.identify
Algebraic identification
---------------------------------------
:func:`~mpmath.findpoly`
^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.findpoly
Integer relations (PSLQ)
----------------------------
:func:`~mpmath.pslq`
^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: mpmath.pslq
+55
View File
@@ -0,0 +1,55 @@
.. mpmath documentation master file, created by sphinx-quickstart on Fri Mar 28 13:50:14 2008.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to mpmath's documentation!
==================================
Mpmath is a Python library for arbitrary-precision floating-point arithmetic.
For general information about mpmath, see the project website https://mpmath.org/
These documentation pages include general information as well as docstring listing with extensive use of examples that can be run in the interactive Python interpreter. For quick access to the docstrings of individual functions, use the `index listing <genindex.html>`_, or type ``help(mpmath.function_name)`` in the Python interactive prompt.
Introduction
------------
.. toctree ::
:maxdepth: 2
setup
basics
Basic features
----------------
.. toctree ::
:maxdepth: 2
contexts
general
plotting
cli
Advanced mathematics
--------------------
On top of its support for arbitrary-precision arithmetic, mpmath
provides extensive support for transcendental functions, evaluation of sums, integrals, limits, roots, and so on.
.. toctree ::
:maxdepth: 2
functions/index
calculus/index
matrices
identification
End matter
----------
.. toctree ::
:maxdepth: 2
technical
references
genindex
+569
View File
@@ -0,0 +1,569 @@
Matrices
========
Creating matrices
-----------------
Basic methods
.............
Matrices in mpmath are implemented using dictionaries. Only non-zero values are
stored, so it is cheap to represent sparse matrices.
The most basic way to create one is to use the ``matrix`` class directly. You
can create an empty matrix specifying the dimensions::
>>> from mpmath import (matrix, ones, zeros, randmatrix, nprint, chop, iv,
... lu_solve, residual, fp, lu, diag, eye, eps, qr)
>>> matrix(2)
matrix(
[['0.0', '0.0'],
['0.0', '0.0']])
>>> matrix(2, 3)
matrix(
[['0.0', '0.0', '0.0'],
['0.0', '0.0', '0.0']])
Calling ``matrix`` with one dimension will create a square matrix.
To access the dimensions of a matrix, use the ``rows`` or ``cols`` keyword::
>>> A = matrix(3, 2)
>>> A
matrix(
[['0.0', '0.0'],
['0.0', '0.0'],
['0.0', '0.0']])
>>> A.rows
3
>>> A.cols
2
You can also change the dimension of an existing matrix. This will set the
new elements to 0. If the new dimension is smaller than before, the
concerning elements are discarded::
>>> A.rows = 2
>>> A
matrix(
[['0.0', '0.0'],
['0.0', '0.0']])
Internally ``convert`` is applied every time an element is set. This is
done using the syntax A[row,column], counting from 0::
>>> A = matrix(2)
>>> A[1,1] = 1 + 1j
>>> print(A)
[0.0 0.0]
[0.0 (1.0 + 1.0j)]
A more comfortable way to create a matrix lets you use nested lists::
>>> matrix([[1, 2], [3, 4]])
matrix(
[['1.0', '2.0'],
['3.0', '4.0']])
Advanced methods
................
Convenient functions are available for creating various standard matrices::
>>> zeros(2)
matrix(
[['0.0', '0.0'],
['0.0', '0.0']])
>>> ones(2)
matrix(
[['1.0', '1.0'],
['1.0', '1.0']])
>>> diag([1, 2, 3]) # diagonal matrix
matrix(
[['1.0', '0.0', '0.0'],
['0.0', '2.0', '0.0'],
['0.0', '0.0', '3.0']])
>>> eye(2) # identity matrix
matrix(
[['1.0', '0.0'],
['0.0', '1.0']])
You can even create random matrices::
>>> randmatrix(2) # doctest:+SKIP
matrix(
[['0.53491598236191806', '0.57195669543302752'],
['0.85589992269513615', '0.82444367501382143']])
Vectors
.......
Vectors may also be represented by the ``matrix`` class (with rows = 1 or cols = 1).
For vectors there are some things which make life easier. A column vector can
be created using a flat list, a row vectors using an almost flat nested list::
>>> matrix([1, 2, 3])
matrix(
[['1.0'],
['2.0'],
['3.0']])
>>> matrix([[1, 2, 3]])
matrix(
[['1.0', '2.0', '3.0']])
Optionally vectors can be accessed like lists, using only a single index::
>>> x = matrix([1, 2, 3])
>>> x[1]
mpf('2.0')
>>> x[1,0]
mpf('2.0')
Other
.....
Like you probably expected, matrices can be printed::
>>> print(randmatrix(3)) # doctest:+SKIP
[ 0.782963853573023 0.802057689719883 0.427895717335467]
[0.0541876859348597 0.708243266653103 0.615134039977379]
[ 0.856151514955773 0.544759264818486 0.686210904770947]
Use ``nstr`` or ``nprint`` to specify the number of digits to print::
>>> nprint(randmatrix(5), 3) # doctest:+SKIP
[2.07e-1 1.66e-1 5.06e-1 1.89e-1 8.29e-1]
[6.62e-1 6.55e-1 4.47e-1 4.82e-1 2.06e-2]
[4.33e-1 7.75e-1 6.93e-2 2.86e-1 5.71e-1]
[1.01e-1 2.53e-1 6.13e-1 3.32e-1 2.59e-1]
[1.56e-1 7.27e-2 6.05e-1 6.67e-2 2.79e-1]
As matrices are mutable, you will need to copy them sometimes::
>>> A = matrix(2)
>>> A
matrix(
[['0.0', '0.0'],
['0.0', '0.0']])
>>> B = A.copy()
>>> B[0,0] = 1
>>> B
matrix(
[['1.0', '0.0'],
['0.0', '0.0']])
>>> A
matrix(
[['0.0', '0.0'],
['0.0', '0.0']])
Finally, it is possible to convert a matrix to a nested list. This is very useful,
as most Python libraries involving matrices or arrays (namely NumPy or SymPy)
support this format::
>>> B.tolist()
[[mpf('1.0'), mpf('0.0')], [mpf('0.0'), mpf('0.0')]]
Matrix operations
-----------------
You can add and subtract matrices of compatible dimensions::
>>> A = matrix([[1, 2], [3, 4]])
>>> B = matrix([[-2, 4], [5, 9]])
>>> A + B
matrix(
[['-1.0', '6.0'],
['8.0', '13.0']])
>>> A - B
matrix(
[['3.0', '-2.0'],
['-2.0', '-5.0']])
>>> A + ones(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "...", line 238, in __add__
raise ValueError('incompatible dimensions for addition')
ValueError: incompatible dimensions for addition
It is possible to multiply or add matrices and scalars. In the latter case the
operation will be done element-wise::
>>> A * 2
matrix(
[['2.0', '4.0'],
['6.0', '8.0']])
>>> A / 4
matrix(
[['0.25', '0.5'],
['0.75', '1.0']])
>>> A - 1
matrix(
[['0.0', '1.0'],
['2.0', '3.0']])
Of course you can perform matrix multiplication, if the dimensions are
compatible::
>>> A * B
matrix(
[['8.0', '22.0'],
['14.0', '48.0']])
>>> matrix([[1, 2, 3]]) * matrix([[-6], [7], [-2]])
matrix(
[['2.0']])
You can raise powers of square matrices::
>>> A**2
matrix(
[['7.0', '10.0'],
['15.0', '22.0']])
Negative powers will calculate the inverse::
>>> A**-1
matrix(
[['-2.0', '1.0'],
['1.5', '-0.5']])
>>> nprint(A * A**-1, 3)
[ 1.0 1.08e-19]
[-2.17e-19 1.0]
Matrix transposition is straightforward::
>>> A = ones(2, 3)
>>> A
matrix(
[['1.0', '1.0', '1.0'],
['1.0', '1.0', '1.0']])
>>> A.T
matrix(
[['1.0', '1.0'],
['1.0', '1.0'],
['1.0', '1.0']])
Norms
.....
Sometimes you need to know how "large" a matrix or vector is. Due to their
multidimensional nature it's not possible to compare them, but there are
several functions to map a matrix or a vector to a positive real number, the
so called norms.
.. autofunction :: mpmath.norm
.. autofunction :: mpmath.mnorm
Linear algebra
--------------
Determinant and Rank
....................
.. autofunction :: mpmath.det
.. autofunction :: mpmath.rank
Decompositions
..............
.. autofunction :: mpmath.cholesky
Linear equations
................
Basic linear algebra is implemented; you can for example solve the linear
equation system::
x + 2*y = -10
3*x + 4*y = 10
using ``lu_solve``::
>>> A = matrix([[1, 2], [3, 4]])
>>> b = matrix([-10, 10])
>>> x = lu_solve(A, b)
>>> x
matrix(
[['30.0'],
['-20.0']])
If you don't trust the result, use ``residual`` to calculate
the residual `||A x-b||`::
>>> residual(A, x, b)
matrix(
[['3.46944695195361e-18'],
['3.46944695195361e-18']])
>>> str(eps)
'2.22044604925031e-16'
As you can see, the solution is quite accurate. The error is caused by the
inaccuracy of the internal floating-point arithmetic. Though, it's even smaller
than the current machine epsilon, which basically means you can trust the
result.
If you need more speed, use NumPy, or use ``fp`` instead ``mp`` matrices
and methods::
>>> A = fp.matrix([[1, 2], [3, 4]])
>>> b = fp.matrix([-10, 10])
>>> fp.lu_solve(A, b)
matrix(
[['29.999999999999996'],
['-19.999999999999996']])
``lu_solve`` accepts overdetermined systems. It is usually not possible to solve
such systems, so the residual is minimized instead. Internally this is done
using Cholesky decomposition to compute a least squares approximation. This means
that that ``lu_solve`` will square the errors. If you can't afford this, use
``qr_solve`` instead. It is twice as slow but more accurate, and it calculates
the residual automatically.
.. autofunction:: mpmath.lu_solve
Matrix factorization
....................
The function ``lu`` computes an explicit LU factorization of a matrix::
>>> P, L, U = lu(matrix([[0,2,3],[4,5,6],[7,8,9]]))
>>> print(P)
[0.0 0.0 1.0]
[1.0 0.0 0.0]
[0.0 1.0 0.0]
>>> print(L)
[ 1.0 0.0 0.0]
[ 0.0 1.0 0.0]
[0.571428571428571 0.214285714285714 1.0]
>>> print(U)
[7.0 8.0 9.0]
[0.0 2.0 3.0]
[0.0 0.0 0.214285714285714]
>>> print(P.T*L*U)
[0.0 2.0 3.0]
[4.0 5.0 6.0]
[7.0 8.0 9.0]
The function ``qr`` computes a QR factorization of a matrix::
>>> A = matrix([[1, 2], [3, 4], [1, 1]])
>>> Q, R = qr(A)
>>> print(Q)
[-0.301511344577764 0.861640436855329 0.408248290463863]
[-0.904534033733291 -0.123091490979333 -0.408248290463863]
[-0.301511344577764 -0.492365963917331 0.816496580927726]
>>> print(R)
[-3.3166247903554 -4.52267016866645]
[ 0.0 0.738548945875996]
[ 0.0 0.0]
>>> print(Q * R)
[1.0 2.0]
[3.0 4.0]
[1.0 1.0]
>>> print(chop(Q.T * Q))
[1.0 0.0 0.0]
[0.0 1.0 0.0]
[0.0 0.0 1.0]
The singular value decomposition
................................
The routines ``svd_r`` and ``svd_c`` compute the singular value decomposition
of a real or complex matrix A. ``svd`` is an unified interface calling
either ``svd_r`` or ``svd_c`` depending on whether *A* is real or complex.
Given *A*, two orthogonal (*A* real) or unitary (*A* complex) matrices *U* and *V*
are calculated such that
.. math ::
A = U S V, \quad U' U = 1, \quad V V' = 1
where *S* is a suitable shaped matrix whose off-diagonal elements are zero.
Here ' denotes the hermitian transpose (i.e. transposition and complex
conjugation). The diagonal elements of *S* are the singular values of *A*,
i.e. the square roots of the eigenvalues of `A' A` or `A A'`.
Examples::
>>> from mpmath import mp
>>> A = mp.matrix([[2, -2, -1], [3, 4, -2], [-2, -2, 0]])
>>> S = mp.svd_r(A, compute_uv = False)
>>> print(S)
[6.0]
[3.0]
[1.0]
>>> U, S, V = mp.svd_r(A)
>>> print(mp.chop(A - U * mp.diag(S) * V))
[0.0 0.0 0.0]
[0.0 0.0 0.0]
[0.0 0.0 0.0]
The Schur decomposition
.......................
This routine computes the Schur decomposition of a square matrix *A*.
Given *A*, a unitary matrix *Q* is determined such that
.. math ::
Q' A Q = R, \quad Q' Q = Q Q' = 1
where *R* is an upper right triangular matrix. Here ' denotes the
hermitian transpose (i.e. transposition and conjugation).
Examples::
>>> from mpmath import mp
>>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]])
>>> Q, R = mp.schur(A)
>>> mp.nprint(R, 3)
[2.0 0.417 2.53]
[0.0 4.0 4.74]
[0.0 0.0 9.0]
>>> print(mp.chop(A - Q * R * Q.transpose_conj()))
[0.0 0.0 0.0]
[0.0 0.0 0.0]
[0.0 0.0 0.0]
The eigenvalue problem
......................
The routine ``eig`` solves the (ordinary) eigenvalue problem for a real or complex
square matrix *A*. Given *A*, a vector *E* and matrices *ER* and *EL* are calculated such that
.. code ::
A ER[:,i] = E[i] ER[:,i]
EL[i,:] A = EL[i,:] E[i]
*E* contains the eigenvalues of *A*. The columns of *ER* contain the right eigenvectors
of *A* whereas the rows of *EL* contain the left eigenvectors.
Examples::
>>> from mpmath import mp
>>> A = mp.matrix([[3, -1, 2], [2, 5, -5], [-2, -3, 7]])
>>> E, ER = mp.eig(A)
>>> print(mp.chop(A * ER[:,0] - E[0] * ER[:,0]))
[0.0]
[0.0]
[0.0]
>>> E, EL, ER = mp.eig(A,left = True, right = True)
>>> E, EL, ER = mp.eig_sort(E, EL, ER)
>>> mp.nprint(E)
[2.0, 4.0, 9.0]
>>> print(mp.chop(A * ER[:,0] - E[0] * ER[:,0]))
[0.0]
[0.0]
[0.0]
>>> print(mp.chop( EL[0,:] * A - EL[0,:] * E[0]))
[0.0 0.0 0.0]
See also [Stoer]_ and [Kresser]_.
The symmetric eigenvalue problem
................................
The routines ``eigsy`` and ``eighe`` solve the (ordinary) eigenvalue problem
for a real symmetric or complex hermitian square matrix *A*.
``eigh`` is an unified interface for this two functions calling either
``eigsy`` or ``eighe`` depending on whether *A* is real or complex.
Given *A*, an orthogonal (*A* real) or unitary matrix *Q* (*A* complex) is
calculated which diagonalizes A:
.. math ::
Q' A Q = \operatorname{diag}(E), \quad Q Q' = Q' Q = 1
Here diag(*E*) a is diagonal matrix whose diagonal is *E*.
' denotes the hermitian transpose (i.e. ordinary transposition and
complex conjugation).
The columns of *Q* are the eigenvectors of *A* and *E* contains the eigenvalues:
.. code ::
A Q[:,i] = E[i] Q[:,i]
Examples::
>>> from mpmath import mp
>>> A = mp.matrix([[3, 2], [2, 0]])
>>> E = mp.eigsy(A, eigvals_only = True)
>>> print(E)
[-1.0]
[ 4.0]
>>> A = mp.matrix([[1, 2], [2, 3]])
>>> E, Q = mp.eigsy(A) # alternative: E, Q = mp.eigh(A)
>>> print(mp.chop(A * Q[:,0] - E[0] * Q[:,0]))
[0.0]
[0.0]
>>> A = mp.matrix([[1, 2 + 5j], [2 - 5j, 3]])
>>> E, Q = mp.eighe(A) # alternative: E, Q = mp.eigh(A)
>>> print(mp.chop(A * Q[:,0] - E[0] * Q[:,0]))
[0.0]
[0.0]
See also [Golub]_, [GolubWelsch]_, [Stoer]_ and [Stroud]_.
Determinant
...........
The determinant of a square matrix is computed by the
function ``det``::
>>> from mpmath import mp
>>> A = mp.matrix([[7, 2], [1.5, 3]])
>>> print(mp.det(A))
18.0
Interval and double-precision matrices
--------------------------------------
The ``iv.matrix`` and ``fp.matrix`` classes convert inputs
to intervals and Python floating-point numbers respectively.
Interval matrices can be used to perform linear algebra operations
with rigorous error tracking::
>>> a = iv.matrix([['0.1','0.3','1.0'],
... ['7.1','5.5','4.8'],
... ['3.2','4.4','5.6']])
>>>
>>> b = iv.matrix(['4','0.6','0.5'])
>>> c = iv.lu_solve(a, b)
>>> print(c)
[ [5.2582327113062393041, 5.2582327113062749951]]
[[-13.155049396267856583, -13.155049396267821167]]
[ [7.4206915477497212555, 7.4206915477497310922]]
>>> print(a*c)
[ [3.9999999999999866773, 4.0000000000000133227]]
[[0.59999999999972430942, 0.60000000000027142733]]
[[0.49999999999982236432, 0.50000000000018474111]]
Matrix functions
----------------
.. autofunction :: mpmath.expm
.. autofunction :: mpmath.cosm
.. autofunction :: mpmath.sinm
.. autofunction :: mpmath.sqrtm
.. autofunction :: mpmath.logm
.. autofunction :: mpmath.powm
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

+5
View File
@@ -0,0 +1,5 @@
# Airy function Ai(x), Ai'(x) and int_0^x Ai(t) dt on the real line
f = airyai
f_diff = lambda z: airyai(z, derivative=1)
f_int = lambda z: airyai(z, derivative=-1)
plot([f, f_diff, f_int], [-10,5])
Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

+2
View File
@@ -0,0 +1,2 @@
# Airy function Ai(z) in the complex plane
cplot(airyai, [-8,8], [-8,8], points=50000)
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

+6
View File
@@ -0,0 +1,6 @@
# Kelvin functions ber_n(x) and bei_n(x) on the real line for n=0,2
f0 = lambda x: ber(0,x)
f1 = lambda x: bei(0,x)
f2 = lambda x: ber(2,x)
f3 = lambda x: bei(2,x)
plot([f0,f1,f2,f3],[0,10],[-10,10])
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

+6
View File
@@ -0,0 +1,6 @@
# Modified Bessel function I_n(x) on the real line for n=0,1,2,3
i0 = lambda x: besseli(0,x)
i1 = lambda x: besseli(1,x)
i2 = lambda x: besseli(2,x)
i3 = lambda x: besseli(3,x)
plot([i0,i1,i2,i3],[0,5],[0,5])
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

+2
View File
@@ -0,0 +1,2 @@
# Modified Bessel function I_n(z) in the complex plane
cplot(lambda z: besseli(1,z), [-8,8], [-8,8], points=50000)
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

+6
View File
@@ -0,0 +1,6 @@
# Bessel function J_n(x) on the real line for n=0,1,2,3
j0 = lambda x: besselj(0,x)
j1 = lambda x: besselj(1,x)
j2 = lambda x: besselj(2,x)
j3 = lambda x: besselj(3,x)
plot([j0,j1,j2,j3],[0,14])
Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

+2
View File
@@ -0,0 +1,2 @@
# Bessel function J_n(z) in the complex plane
cplot(lambda z: besselj(1,z), [-8,8], [-8,8], points=50000)
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+6
View File
@@ -0,0 +1,6 @@
# Modified Bessel function of 2nd kind K_n(x) on the real line for n=0,1,2,3
k0 = lambda x: besselk(0,x)
k1 = lambda x: besselk(1,x)
k2 = lambda x: besselk(2,x)
k3 = lambda x: besselk(3,x)
plot([k0,k1,k2,k3],[0,8],[0,5])
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

+2
View File
@@ -0,0 +1,2 @@
# Modified Bessel function of 2nd kind K_n(z) in the complex plane
cplot(lambda z: besselk(1,z), [-8,8], [-8,8], points=50000)
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

+6
View File
@@ -0,0 +1,6 @@
# Bessel function of 2nd kind Y_n(x) on the real line for n=0,1,2,3
y0 = lambda x: bessely(0,x)
y1 = lambda x: bessely(1,x)
y2 = lambda x: bessely(2,x)
y3 = lambda x: bessely(3,x)
plot([y0,y1,y2,y3],[0,10],[-4,1])
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

+2
View File
@@ -0,0 +1,2 @@
# Bessel function of 2nd kind Y_n(z) in the complex plane
cplot(lambda z: bessely(1,z), [-8,8], [-8,8], points=50000)
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

+5
View File
@@ -0,0 +1,5 @@
# Airy function Bi(x), Bi'(x) and int_0^x Bi(t) dt on the real line
f = airybi
f_diff = lambda z: airybi(z, derivative=1)
f_int = lambda z: airybi(z, derivative=-1)
plot([f, f_diff, f_int], [-10,2], [-1,2])
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

+2
View File
@@ -0,0 +1,2 @@
# Airy function Bi(z) in the complex plane
cplot(airybi, [-8,8], [-8,8], points=50000)
+22
View File
@@ -0,0 +1,22 @@
import os.path
import glob
for f in glob.glob("*.py"):
if "buildplots" in f or os.path.exists(f[:-3]+".png"):
continue
print("Processing", f)
code = open(f).readlines()
code = ["from mpmath import *; mp.dps=5"] + code
for i in range(len(code)):
l = code[i].rstrip()
if "cplot(" in l:
l = l[:-1] + (", dpi=45, file='%s.png', verbose=True)" % f[:-3])
code[i] = l
elif "splot(" in l:
l = l[:-1] + (", dpi=45, file='%s.png')" % f[:-3])
code[i] = l
elif "plot(" in l:
l = l[:-1] + (", dpi=45, file='%s.png')" % f[:-3])
code[i] = l
code = "\n".join(code)
exec(code)
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+7
View File
@@ -0,0 +1,7 @@
# Chebyshev polynomials T_n(x) on [-1,1] for n=0,1,2,3,4
f0 = lambda x: chebyt(0,x)
f1 = lambda x: chebyt(1,x)
f2 = lambda x: chebyt(2,x)
f3 = lambda x: chebyt(3,x)
f4 = lambda x: chebyt(4,x)
plot([f0,f1,f2,f3,f4],[-1,1])
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

+7
View File
@@ -0,0 +1,7 @@
# Chebyshev polynomials U_n(x) on [-1,1] for n=0,1,2,3,4
f0 = lambda x: chebyu(0,x)
f1 = lambda x: chebyu(1,x)
f2 = lambda x: chebyu(2,x)
f3 = lambda x: chebyu(3,x)
f4 = lambda x: chebyu(4,x)
plot([f0,f1,f2,f3,f4],[-1,1])
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

+7
View File
@@ -0,0 +1,7 @@
# Regular Coulomb wave functions -- equivalent to figure 14.3 in A&S
F1 = lambda x: coulombf(0,0,x)
F2 = lambda x: coulombf(0,1,x)
F3 = lambda x: coulombf(0,5,x)
F4 = lambda x: coulombf(0,10,x)
F5 = lambda x: coulombf(0,x/2,x)
plot([F1,F2,F3,F4,F5], [0,25], [-1.2,1.6])
Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

+2
View File
@@ -0,0 +1,2 @@
# Regular Coulomb wave function in the complex plane
cplot(lambda z: coulombf(1,1,z), points=50000)
Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

+7
View File
@@ -0,0 +1,7 @@
# Irregular Coulomb wave functions -- equivalent to figure 14.5 in A&S
F1 = lambda x: coulombg(0,0,x)
F2 = lambda x: coulombg(0,1,x)
F3 = lambda x: coulombg(0,5,x)
F4 = lambda x: coulombg(0,10,x)
F5 = lambda x: coulombg(0,x/2,x)
plot([F1,F2,F3,F4,F5], [0,30], [-2,2])
Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

+2
View File
@@ -0,0 +1,2 @@
# Irregular Coulomb wave function in the complex plane
cplot(lambda z: coulombg(1,1,z), points=50000)
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+7
View File
@@ -0,0 +1,7 @@
# Elliptic integral E(z,m) for some different m
f1 = lambda z: ellipe(z,-2)
f2 = lambda z: ellipe(z,-1)
f3 = lambda z: ellipe(z,0)
f4 = lambda z: ellipe(z,1)
f5 = lambda z: ellipe(z,2)
plot([f1,f2,f3,f4,f5], [0,pi], [0,4])
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

+7
View File
@@ -0,0 +1,7 @@
# Elliptic integral F(z,m) for some different m
f1 = lambda z: ellipf(z,-1)
f2 = lambda z: ellipf(z,-0.5)
f3 = lambda z: ellipf(z,0)
f4 = lambda z: ellipf(z,0.5)
f5 = lambda z: ellipf(z,1)
plot([f1,f2,f3,f4,f5], [0,pi], [0,4])
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Some files were not shown because too many files have changed in this diff Show More