Spaces:
Running
Running
Upload 3077 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- MLPY/Lib/site-packages/sympy-1.13.1.dist-info/AUTHORS +1317 -0
- MLPY/Lib/site-packages/sympy-1.13.1.dist-info/INSTALLER +1 -0
- MLPY/Lib/site-packages/sympy-1.13.1.dist-info/LICENSE +153 -0
- MLPY/Lib/site-packages/sympy-1.13.1.dist-info/METADATA +304 -0
- MLPY/Lib/site-packages/sympy-1.13.1.dist-info/RECORD +0 -0
- MLPY/Lib/site-packages/sympy-1.13.1.dist-info/WHEEL +5 -0
- MLPY/Lib/site-packages/sympy-1.13.1.dist-info/entry_points.txt +2 -0
- MLPY/Lib/site-packages/sympy-1.13.1.dist-info/top_level.txt +2 -0
- MLPY/Lib/site-packages/sympy/__init__.py +542 -0
- MLPY/Lib/site-packages/sympy/__pycache__/__init__.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/__pycache__/abc.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/__pycache__/conftest.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/__pycache__/galgebra.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/__pycache__/release.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/__pycache__/this.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/abc.py +111 -0
- MLPY/Lib/site-packages/sympy/algebras/__init__.py +3 -0
- MLPY/Lib/site-packages/sympy/algebras/__pycache__/__init__.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/algebras/__pycache__/quaternion.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/algebras/quaternion.py +1667 -0
- MLPY/Lib/site-packages/sympy/algebras/tests/__init__.py +0 -0
- MLPY/Lib/site-packages/sympy/algebras/tests/__pycache__/__init__.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/algebras/tests/__pycache__/test_quaternion.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/algebras/tests/test_quaternion.py +428 -0
- MLPY/Lib/site-packages/sympy/assumptions/__init__.py +18 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/__init__.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/ask.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/ask_generated.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/assume.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/cnf.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/facts.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/lra_satask.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/refine.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/satask.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/sathandlers.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/__pycache__/wrapper.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/ask.py +651 -0
- MLPY/Lib/site-packages/sympy/assumptions/ask_generated.py +352 -0
- MLPY/Lib/site-packages/sympy/assumptions/assume.py +485 -0
- MLPY/Lib/site-packages/sympy/assumptions/cnf.py +445 -0
- MLPY/Lib/site-packages/sympy/assumptions/facts.py +270 -0
- MLPY/Lib/site-packages/sympy/assumptions/handlers/__init__.py +13 -0
- MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/__init__.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/calculus.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/common.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/matrices.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/ntheory.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/order.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/sets.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/sympy/assumptions/handlers/calculus.py +258 -0
MLPY/Lib/site-packages/sympy-1.13.1.dist-info/AUTHORS
ADDED
@@ -0,0 +1,1317 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
All people who contributed to SymPy by sending at least a patch or
|
2 |
+
more (in the order of the date of their first contribution), except
|
3 |
+
those who explicitly didn't want to be mentioned. People with a * next
|
4 |
+
to their names are not found in the metadata of the git history. This
|
5 |
+
file is generated automatically by running `./bin/authors_update.py`.
|
6 |
+
|
7 |
+
There are a total of 1309 authors.
|
8 |
+
|
9 |
+
Ondřej Čertík <[email protected]>
|
10 |
+
Fabian Pedregosa <[email protected]>
|
11 |
+
Jurjen N.E. Bos <[email protected]>
|
12 |
+
Mateusz Paprocki <[email protected]>
|
13 |
+
*Marc-Etienne M.Leveille <[email protected]>
|
14 |
+
Brian Jorgensen <[email protected]>
|
15 |
+
Jason Gedge <[email protected]>
|
16 |
+
Robert Schwarz <[email protected]>
|
17 |
+
Pearu Peterson <[email protected]>
|
18 |
+
Fredrik Johansson <[email protected]>
|
19 |
+
Chris Wu <[email protected]>
|
20 |
+
*Ulrich Hecht <[email protected]>
|
21 |
+
Goutham Lakshminarayan <[email protected]>
|
22 |
+
David Lawrence <[email protected]>
|
23 |
+
Jaroslaw Tworek <[email protected]>
|
24 |
+
David Marek <[email protected]>
|
25 |
+
Bernhard R. Link <[email protected]>
|
26 |
+
Andrej Tokarčík <[email protected]>
|
27 |
+
Or Dvory <[email protected]>
|
28 |
+
Saroj Adhikari <[email protected]>
|
29 |
+
Pauli Virtanen <[email protected]>
|
30 |
+
Robert Kern <[email protected]>
|
31 |
+
James Aspnes <[email protected]>
|
32 |
+
Nimish Telang <[email protected]>
|
33 |
+
Abderrahim Kitouni <[email protected]>
|
34 |
+
Pan Peng <[email protected]>
|
35 |
+
Friedrich Hagedorn <[email protected]>
|
36 |
+
Elrond der Elbenfuerst <[email protected]>
|
37 |
+
Rizgar Mella <[email protected]>
|
38 |
+
Felix Kaiser <[email protected]>
|
39 |
+
Roberto Nobrega <[email protected]>
|
40 |
+
David Roberts <[email protected]>
|
41 |
+
Sebastian Krämer <[email protected]>
|
42 |
+
Vinzent Steinberg <[email protected]>
|
43 |
+
Riccardo Gori <[email protected]>
|
44 |
+
Case Van Horsen <[email protected]>
|
45 |
+
Stepan Roucka <[email protected]>
|
46 |
+
Ali Raza Syed <[email protected]>
|
47 |
+
Stefano Maggiolo <[email protected]>
|
48 |
+
Robert Cimrman <[email protected]>
|
49 |
+
Bastian Weber <[email protected]>
|
50 |
+
Sebastian Krause <[email protected]>
|
51 |
+
Sebastian Kreft <[email protected]>
|
52 |
+
*Dan <[email protected]>
|
53 |
+
Alan Bromborsky <[email protected]>
|
54 |
+
Boris Timokhin <[email protected]>
|
55 |
+
Robert <[email protected]>
|
56 |
+
Andy R. Terrel <[email protected]>
|
57 |
+
Hubert Tsang <[email protected]>
|
58 |
+
Konrad Meyer <[email protected]>
|
59 |
+
Henrik Johansson <[email protected]>
|
60 |
+
Priit Laes <[email protected]>
|
61 |
+
Freddie Witherden <[email protected]>
|
62 |
+
Brian E. Granger <[email protected]>
|
63 |
+
Andrew Straw <[email protected]>
|
64 |
+
Kaifeng Zhu <[email protected]>
|
65 |
+
Ted Horst <[email protected]>
|
66 |
+
Andrew Docherty <[email protected]>
|
67 |
+
Akshay Srinivasan <[email protected]>
|
68 |
+
Aaron Meurer <[email protected]>
|
69 |
+
Barry Wardell <[email protected]>
|
70 |
+
Tomasz Buchert <[email protected]>
|
71 |
+
Vinay Kumar <[email protected]>
|
72 |
+
Johann Cohen-Tanugi <[email protected]>
|
73 |
+
Jochen Voss <[email protected]>
|
74 |
+
Luke Peterson <[email protected]>
|
75 |
+
Chris Smith <[email protected]>
|
76 |
+
Thomas Sidoti <[email protected]>
|
77 |
+
Florian Mickler <[email protected]>
|
78 |
+
Nicolas Pourcelot <[email protected]>
|
79 |
+
Ben Goodrich <[email protected]>
|
80 |
+
Toon Verstraelen <[email protected]>
|
81 |
+
Ronan Lamy <[email protected]>
|
82 |
+
James Abbatiello <[email protected]>
|
83 |
+
Ryan Krauss <[email protected]>
|
84 |
+
Bill Flynn <[email protected]>
|
85 |
+
Kevin Goodsell <[email protected]>
|
86 |
+
Jorn Baayen <[email protected]>
|
87 |
+
Eh Tan <[email protected]>
|
88 |
+
Renato Coutinho <[email protected]>
|
89 |
+
Oscar Benjamin <[email protected]>
|
90 |
+
Øyvind Jensen <[email protected]>
|
91 |
+
Julio Idichekop Filho <[email protected]>
|
92 |
+
Łukasz Pankowski <[email protected]>
|
93 |
+
*Chu-Ching Huang <[email protected]>
|
94 |
+
Fernando Perez <[email protected]>
|
95 |
+
Raffaele De Feo <[email protected]>
|
96 |
+
Christian Muise <[email protected]>
|
97 |
+
Matt Curry <[email protected]>
|
98 |
+
Kazuo Thow <[email protected]>
|
99 |
+
Christian Schubert <[email protected]>
|
100 |
+
Jezreel Ng <[email protected]>
|
101 |
+
James Pearson <[email protected]>
|
102 |
+
Matthew Brett <[email protected]>
|
103 |
+
Addison Cugini <[email protected]>
|
104 |
+
Nicholas J.S. Kinar <[email protected]>
|
105 |
+
Harold Erbin <[email protected]>
|
106 |
+
Thomas Dixon <[email protected]>
|
107 |
+
Cristóvão Sousa <[email protected]>
|
108 |
+
Andre de Fortier Smit <[email protected]>
|
109 |
+
Mark Dewing <[email protected]>
|
110 |
+
Alexey U. Gudchenko <[email protected]>
|
111 |
+
Gary Kerr <[email protected]>
|
112 |
+
Sherjil Ozair <[email protected]>
|
113 |
+
Oleksandr Gituliar <[email protected]>
|
114 |
+
Sean Vig <[email protected]>
|
115 |
+
Prafullkumar P. Tale <[email protected]>
|
116 |
+
Vladimir Perić <[email protected]>
|
117 |
+
Tom Bachmann <[email protected]>
|
118 |
+
Yuri Karadzhov <[email protected]>
|
119 |
+
Vladimir Lagunov <[email protected]>
|
120 |
+
Matthew Rocklin <[email protected]>
|
121 |
+
Saptarshi Mandal <[email protected]>
|
122 |
+
Gilbert Gede <[email protected]>
|
123 |
+
Anatolii Koval <[email protected]>
|
124 |
+
Tomo Lazovich <[email protected]>
|
125 |
+
Pavel Fedotov <[email protected]>
|
126 |
+
Jack McCaffery <[email protected]>
|
127 |
+
Jeremias Yehdegho <[email protected]>
|
128 |
+
Kibeom Kim <[email protected]>
|
129 |
+
Gregory Ksionda <[email protected]>
|
130 |
+
Tomáš Bambas <[email protected]>
|
131 |
+
Raymond Wong <[email protected]>
|
132 |
+
Luca Weihs <[email protected]>
|
133 |
+
Shai 'Deshe' Wyborski <[email protected]>
|
134 |
+
Thomas Wiecki <[email protected]>
|
135 |
+
Óscar Nájera <[email protected]>
|
136 |
+
Mario Pernici <[email protected]>
|
137 |
+
Benjamin McDonald <[email protected]>
|
138 |
+
Sam Magura <[email protected]>
|
139 |
+
Stefan Krastanov <[email protected]>
|
140 |
+
Bradley Froehle <[email protected]>
|
141 |
+
Min Ragan-Kelley <[email protected]>
|
142 |
+
Emma Hogan <[email protected]>
|
143 |
+
Nikhil Sarda <[email protected]>
|
144 |
+
Julien Rioux <[email protected]>
|
145 |
+
Roberto Colistete, Jr. <[email protected]>
|
146 |
+
Raoul Bourquin <[email protected]>
|
147 |
+
Gert-Ludwig Ingold <[email protected]>
|
148 |
+
Srinivas Vasudevan <[email protected]>
|
149 |
+
Jason Moore <[email protected]>
|
150 |
+
Miha Marolt <[email protected]>
|
151 |
+
Tim Lahey <[email protected]>
|
152 |
+
Luis Garcia <[email protected]>
|
153 |
+
Matt Rajca <[email protected]>
|
154 |
+
David Li <[email protected]>
|
155 |
+
Alexandr Gudulin <[email protected]>
|
156 |
+
Bilal Akhtar <[email protected]>
|
157 |
+
Grzegorz Świrski <[email protected]>
|
158 |
+
Matt Habel <[email protected]>
|
159 |
+
David Ju <[email protected]>
|
160 |
+
Nichita Utiu <[email protected]>
|
161 |
+
Nikolay Lazarov <[email protected]>
|
162 |
+
Steve Anton <[email protected]>
|
163 |
+
Imran Ahmed Manzoor <[email protected]>
|
164 |
+
Ljubiša Moćić <[email protected]>
|
165 |
+
Piotr Korgul <[email protected]>
|
166 |
+
Jim Zhang <[email protected]>
|
167 |
+
Sam Sleight <[email protected]>
|
168 |
+
tborisova <[email protected]>
|
169 |
+
Chancellor Arkantos <[email protected]>
|
170 |
+
Stepan Simsa <[email protected]>
|
171 |
+
Tobias Lenz <[email protected]>
|
172 |
+
Siddhanathan Shanmugam <[email protected]>
|
173 |
+
Tiffany Zhu <[email protected]>
|
174 |
+
Tristan Hume <[email protected]>
|
175 |
+
Alexey Subach <[email protected]>
|
176 |
+
Joan Creus <[email protected]>
|
177 |
+
Geoffry Song <[email protected]>
|
178 |
+
Puneeth Chaganti <[email protected]>
|
179 |
+
Marcin Kostrzewa <>
|
180 |
+
Natalia Nawara <[email protected]>
|
181 |
+
vishal <[email protected]>
|
182 |
+
Shruti Mangipudi <[email protected]>
|
183 |
+
Davy Mao <[email protected]>
|
184 |
+
Swapnil Agarwal <[email protected]>
|
185 |
+
Dhia Kennouche <[email protected]>
|
186 |
+
jerryma1121 <[email protected]>
|
187 |
+
Joachim Durchholz <[email protected]>
|
188 |
+
Martin Povišer <[email protected]>
|
189 |
+
Siddhant Jain <[email protected]>
|
190 |
+
Kevin Hunter <[email protected]>
|
191 |
+
Michael Mayorov <[email protected]>
|
192 |
+
Nathan Alison <[email protected]>
|
193 |
+
Christian Bühler <[email protected]>
|
194 |
+
Carsten Knoll <[email protected]>
|
195 |
+
Bharath M R <[email protected]>
|
196 |
+
Matthias Toews <[email protected]>
|
197 |
+
Sergiu Ivanov <[email protected]>
|
198 |
+
Jorge E. Cardona <[email protected]>
|
199 |
+
Sanket Agarwal <[email protected]>
|
200 |
+
Manoj Babu K. <[email protected]>
|
201 |
+
Sai Nikhil <[email protected]>
|
202 |
+
Aleksandar Makelov <[email protected]>
|
203 |
+
Sachin Irukula <[email protected]>
|
204 |
+
Raphael Michel <[email protected]>
|
205 |
+
Ashwini Oruganti <[email protected]>
|
206 |
+
Andreas Klöckner <[email protected]>
|
207 |
+
Prateek Papriwal <[email protected]>
|
208 |
+
Arpit Goyal <[email protected]>
|
209 |
+
Angadh Nanjangud <[email protected]>
|
210 |
+
Comer Duncan <[email protected]>
|
211 |
+
Jens H. Nielsen <[email protected]>
|
212 |
+
Joseph Dougherty <[email protected]>
|
213 |
+
Elliot Marshall <[email protected]>
|
214 |
+
Guru Devanla <[email protected]>
|
215 |
+
George Waksman <[email protected]>
|
216 |
+
Alexandr Popov <[email protected]>
|
217 |
+
Tarun Gaba <[email protected]>
|
218 |
+
Takafumi Arakaki <[email protected]>
|
219 |
+
Saurabh Jha <[email protected]>
|
220 |
+
Rom le Clair <[email protected]>
|
221 |
+
Angus Griffith <[email protected]>
|
222 |
+
Timothy Reluga <[email protected]>
|
223 |
+
Brian Stephanik <[email protected]>
|
224 |
+
Alexander Eberspächer <[email protected]>
|
225 |
+
Sachin Joglekar <[email protected]>
|
226 |
+
Tyler Pirtle <[email protected]>
|
227 |
+
Vasily Povalyaev <[email protected]>
|
228 |
+
Colleen Lee <[email protected]>
|
229 |
+
Matthew Hoff <[email protected]>
|
230 |
+
Niklas Thörne <[email protected]>
|
231 |
+
Huijun Mai <[email protected]>
|
232 |
+
Marek Šuppa <[email protected]>
|
233 |
+
Ramana Venkata <[email protected]>
|
234 |
+
Prasoon Shukla <[email protected]>
|
235 |
+
Stefen Yin <[email protected]>
|
236 |
+
Thomas Hisch <[email protected]>
|
237 |
+
Madeleine Ball <[email protected]>
|
238 |
+
Mary Clark <[email protected]>
|
239 |
+
Rishabh Dixit <[email protected]>
|
240 |
+
Manoj Kumar <[email protected]>
|
241 |
+
Akshit Agarwal <[email protected]>
|
242 |
+
CJ Carey <[email protected]>
|
243 |
+
Patrick Lacasse <[email protected]>
|
244 |
+
Ananya H <[email protected]>
|
245 |
+
Tarang Patel <[email protected]>
|
246 |
+
Christopher Dembia <[email protected]>
|
247 |
+
Benjamin Fishbein <[email protected]>
|
248 |
+
Sean Ge <[email protected]>
|
249 |
+
Amit Jamadagni <[email protected]>
|
250 |
+
Ankit Agrawal <[email protected]>
|
251 |
+
Björn Dahlgren <[email protected]>
|
252 |
+
Christophe Saint-Jean <[email protected]>
|
253 |
+
Demian Wassermann <[email protected]>
|
254 |
+
Khagesh Patel <[email protected]>
|
255 |
+
Stephen Loo <[email protected]>
|
256 |
+
hm <[email protected]>
|
257 |
+
Patrick Poitras <[email protected]>
|
258 |
+
Katja Sophie Hotz <[email protected]>
|
259 |
+
Varun Joshi <[email protected]>
|
260 |
+
Chetna Gupta <[email protected]>
|
261 |
+
Thilina Rathnayake <[email protected]>
|
262 |
+
Max Hutchinson <[email protected]>
|
263 |
+
Shravas K Rao <[email protected]>
|
264 |
+
Matthew Tadd <[email protected]>
|
265 |
+
Alexander Hirzel <[email protected]>
|
266 |
+
Randy Heydon <[email protected]>
|
267 |
+
Oliver Lee <[email protected]>
|
268 |
+
Seshagiri Prabhu <[email protected]>
|
269 |
+
Pradyumna <[email protected]>
|
270 |
+
Erik Welch <[email protected]>
|
271 |
+
Eric Nelson <[email protected]>
|
272 |
+
Roland Puntaier <[email protected]>
|
273 |
+
Chris Conley <[email protected]>
|
274 |
+
Tim Swast <[email protected]>
|
275 |
+
Dmitry Batkovich <[email protected]>
|
276 |
+
Francesco Bonazzi <[email protected]>
|
277 |
+
Yuriy Demidov <[email protected]>
|
278 |
+
Rick Muller <[email protected]>
|
279 |
+
Manish Gill <[email protected]>
|
280 |
+
Markus Müller <[email protected]>
|
281 |
+
Amit Saha <[email protected]>
|
282 |
+
Jeremy <[email protected]>
|
283 |
+
QuaBoo <[email protected]>
|
284 |
+
Stefan van der Walt <[email protected]>
|
285 |
+
David Joyner <[email protected]>
|
286 |
+
Lars Buitinck <[email protected]>
|
287 |
+
Alkiviadis G. Akritas <[email protected]>
|
288 |
+
Vinit Ravishankar <[email protected]>
|
289 |
+
Mike Boyle <[email protected]>
|
290 |
+
Heiner Kirchhoffer <[email protected]>
|
291 |
+
Pablo Puente <[email protected]>
|
292 |
+
James Fiedler <[email protected]>
|
293 |
+
Harsh Gupta <[email protected]>
|
294 |
+
Tuomas Airaksinen <[email protected]>
|
295 |
+
Paul Strickland <[email protected]>
|
296 |
+
James Goppert <[email protected]>
|
297 |
+
rathmann <[email protected]>
|
298 |
+
Avichal Dayal <[email protected]>
|
299 |
+
Paul Scott <[email protected]>
|
300 |
+
Shipra Banga <[email protected]>
|
301 |
+
Pramod Ch <[email protected]>
|
302 |
+
Akshay <[email protected]>
|
303 |
+
Buck Shlegeris <[email protected]>
|
304 |
+
Jonathan Miller <[email protected]>
|
305 |
+
Edward Schembor <[email protected]>
|
306 |
+
Rajath Shashidhara <[email protected]>
|
307 |
+
Zamrath Nizam <[email protected]>
|
308 |
+
Aditya Shah <[email protected]>
|
309 |
+
Rajat Aggarwal <[email protected]>
|
310 |
+
Sambuddha Basu <[email protected]>
|
311 |
+
Zeel Shah <[email protected]>
|
312 |
+
Abhinav Chanda <[email protected]>
|
313 |
+
Jim Crist <[email protected]>
|
314 |
+
Sudhanshu Mishra <[email protected]>
|
315 |
+
Anurag Sharma <[email protected]>
|
316 |
+
Soumya Dipta Biswas <[email protected]>
|
317 |
+
Sushant Hiray <[email protected]>
|
318 |
+
Ben Lucato <[email protected]>
|
319 |
+
Kunal Arora <[email protected]>
|
320 |
+
Henry Gebhardt <[email protected]>
|
321 |
+
Dammina Sahabandu <[email protected]>
|
322 |
+
Manish Shukla <manish.shukla393@gmail>
|
323 |
+
Ralph Bean <[email protected]>
|
324 |
+
richierichrawr <[email protected]>
|
325 |
+
John Connor <[email protected]>
|
326 |
+
Juan Luis Cano Rodríguez <[email protected]>
|
327 |
+
Sahil Shekhawat <[email protected]>
|
328 |
+
Kundan Kumar <[email protected]>
|
329 |
+
Stas Kelvich <[email protected]>
|
330 |
+
sevaader <[email protected]>
|
331 |
+
Dhruvesh Vijay Parikh <[email protected]>
|
332 |
+
Venkatesh Halli <[email protected]>
|
333 |
+
Lennart Fricke <[email protected]>
|
334 |
+
Vlad Seghete <[email protected]>
|
335 |
+
Shashank Agarwal <[email protected]>
|
336 |
+
carstimon <[email protected]>
|
337 |
+
Pierre Haessig <[email protected]>
|
338 |
+
Maciej Baranski <[email protected]>
|
339 |
+
Benjamin Gudehus <[email protected]>
|
340 |
+
Faisal Anees <[email protected]>
|
341 |
+
Mark Shoulson <[email protected]>
|
342 |
+
Robert Johansson <[email protected]>
|
343 |
+
Kalevi Suominen <[email protected]>
|
344 |
+
Kaushik Varanasi <[email protected]>
|
345 |
+
Fawaz Alazemi <[email protected]>
|
346 |
+
Ambar Mehrotra <[email protected]>
|
347 |
+
David P. Sanders <[email protected]>
|
348 |
+
Peter Brady <[email protected]>
|
349 |
+
John V. Siratt <[email protected]>
|
350 |
+
Sarwar Chahal <[email protected]>
|
351 |
+
Nathan Woods <[email protected]>
|
352 |
+
Colin B. Macdonald <[email protected]>
|
353 |
+
Marcus Näslund <[email protected]>
|
354 |
+
Clemens Novak <[email protected]>
|
355 |
+
Mridul Seth <[email protected]>
|
356 |
+
Craig A. Stoudt <[email protected]>
|
357 |
+
Raj <[email protected]>
|
358 |
+
Mihai A. Ionescu <[email protected]>
|
359 |
+
immerrr <[email protected]>
|
360 |
+
Chai Wah Wu <[email protected]>
|
361 |
+
Leonid Blouvshtein <[email protected]>
|
362 |
+
Peleg Michaeli <[email protected]>
|
363 |
+
ck Lux <[email protected]>
|
364 |
+
zsc347 <[email protected]>
|
365 |
+
Hamish Dickson <[email protected]>
|
366 |
+
Michael Gallaspy <[email protected]>
|
367 |
+
Roman Inflianskas <[email protected]>
|
368 |
+
Duane Nykamp <[email protected]>
|
369 |
+
Ted Dokos <[email protected]>
|
370 |
+
Sunny Aggarwal <[email protected]>
|
371 |
+
Victor Brebenar <[email protected]>
|
372 |
+
Akshat Jain <[email protected]>
|
373 |
+
Shivam Vats <[email protected]>
|
374 |
+
Longqi Wang <[email protected]>
|
375 |
+
Juan Felipe Osorio <[email protected]>
|
376 |
+
Ray Cathcart <[email protected]>
|
377 |
+
Lukas Zorich <[email protected]>
|
378 |
+
Eric Miller <[email protected]>
|
379 |
+
Cody Herbst <[email protected]>
|
380 |
+
Nishith Shah <[email protected]>
|
381 |
+
Amit Kumar <[email protected]>
|
382 |
+
Yury G. Kudryashov <[email protected]>
|
383 |
+
Guillaume Gay <[email protected]>
|
384 |
+
Mihir Wadwekar <[email protected]>
|
385 |
+
Tuan Manh Lai <[email protected]>
|
386 |
+
Asish Panda <[email protected]>
|
387 |
+
Darshan Chaudhary <[email protected]>
|
388 |
+
Alec Kalinin <[email protected]>
|
389 |
+
Ralf Stephan <[email protected]>
|
390 |
+
Aaditya Nair <[email protected]>
|
391 |
+
Jayesh Lahori <[email protected]>
|
392 |
+
Harshil Goel <[email protected]>
|
393 |
+
Luv Agarwal <[email protected]>
|
394 |
+
Jason Ly <[email protected]>
|
395 |
+
Lokesh Sharma <[email protected]>
|
396 |
+
Sartaj Singh <[email protected]>
|
397 |
+
Chris Swierczewski <[email protected]>
|
398 |
+
Konstantin Togoi <[email protected]>
|
399 |
+
Param Singh <[email protected]>
|
400 |
+
Sumith Kulal <[email protected]>
|
401 |
+
Juha Remes <[email protected]>
|
402 |
+
Philippe Bouafia <[email protected]>
|
403 |
+
Peter Schmidt <[email protected]>
|
404 |
+
Jiaxing Liang <[email protected]>
|
405 |
+
Lucas Jones <[email protected]>
|
406 |
+
Gregory Ashton <[email protected]>
|
407 |
+
Jennifer White <[email protected]>
|
408 |
+
Renato Orsino <[email protected]>
|
409 |
+
Michael Boyle <[email protected]>
|
410 |
+
Alistair Lynn <[email protected]>
|
411 |
+
Govind Sahai <[email protected]>
|
412 |
+
Adam Bloomston <[email protected]>
|
413 |
+
Kyle McDaniel <[email protected]>
|
414 |
+
Nguyen Truong Duy <[email protected]>
|
415 |
+
Alex Lindsay <[email protected]>
|
416 |
+
Mathew Chong <[email protected]>
|
417 |
+
Jason Siefken <[email protected]>
|
418 |
+
Gaurav Dhingra <[email protected]>
|
419 |
+
Gao, Xiang <[email protected]>
|
420 |
+
Kevin Ventullo <[email protected]>
|
421 |
+
mao8 <[email protected]>
|
422 |
+
Isuru Fernando <[email protected]>
|
423 |
+
Shivam Tyagi <[email protected]>
|
424 |
+
Richard Otis <[email protected]>
|
425 |
+
Rich LaSota <[email protected]>
|
426 |
+
dustyrockpyle <[email protected]>
|
427 |
+
Anton Akhmerov <[email protected]>
|
428 |
+
Michael Zingale <[email protected]>
|
429 |
+
Chak-Pong Chung <[email protected]>
|
430 |
+
David T <[email protected]>
|
431 |
+
Phil Ruffwind <[email protected]>
|
432 |
+
Sebastian Koslowski <[email protected]>
|
433 |
+
Kumar Krishna Agrawal <[email protected]>
|
434 |
+
Dustin Gadal <[email protected]>
|
435 |
+
João Moura <[email protected]>
|
436 |
+
Yu Kobayashi <[email protected]>
|
437 |
+
Shashank Kumar <[email protected]>
|
438 |
+
Timothy Cyrus <[email protected]>
|
439 |
+
Devyani Kota <[email protected]>
|
440 |
+
Keval Shah <[email protected]>
|
441 |
+
Dzhelil Rufat <[email protected]>
|
442 |
+
Pastafarianist <[email protected]>
|
443 |
+
Sourav Singh <[email protected]>
|
444 |
+
Jacob Garber <[email protected]>
|
445 |
+
Vinay Singh <[email protected]>
|
446 |
+
GolimarOurHero <[email protected]>
|
447 |
+
Prashant Tyagi <[email protected]>
|
448 |
+
Matthew Davis <[email protected]>
|
449 |
+
Tschijnmo TSCHAU <[email protected]>
|
450 |
+
Alexander Bentkamp <[email protected]>
|
451 |
+
Jack Kemp <[email protected]>
|
452 |
+
Kshitij Saraogi <[email protected]>
|
453 |
+
Thomas Baruchel <[email protected]>
|
454 |
+
Nicolás Guarín-Zapata <[email protected]>
|
455 |
+
Jens Jørgen Mortensen <[email protected]>
|
456 |
+
Sampad Kumar Saha <[email protected]>
|
457 |
+
Eva Charlotte Mayer <[email protected]>
|
458 |
+
Laura Domine <[email protected]>
|
459 |
+
Justin Blythe <[email protected]>
|
460 |
+
Meghana Madhyastha <[email protected]>
|
461 |
+
Tanu Hari Dixit <[email protected]>
|
462 |
+
Shekhar Prasad Rajak <[email protected]>
|
463 |
+
Aqnouch Mohammed <[email protected]>
|
464 |
+
Arafat Dad Khan <[email protected]>
|
465 |
+
Boris Atamanovskiy <[email protected]>
|
466 |
+
Sam Tygier <[email protected]>
|
467 |
+
Jai Luthra <[email protected]>
|
468 |
+
Guo Xingjian <[email protected]>
|
469 |
+
Sandeep Veethu <[email protected]>
|
470 |
+
Archit Verma <[email protected]>
|
471 |
+
Shubham Tibra <[email protected]>
|
472 |
+
Ashutosh Saboo <[email protected]>
|
473 |
+
Michael S. Hansen <[email protected]>
|
474 |
+
Anish Shah <[email protected]>
|
475 |
+
Guillaume Jacquenot <[email protected]>
|
476 |
+
Bhautik Mavani <[email protected]>
|
477 |
+
Michał Radwański <[email protected]>
|
478 |
+
Jerry Li <[email protected]>
|
479 |
+
Pablo Zubieta <[email protected]>
|
480 |
+
Shivam Agarwal <[email protected]>
|
481 |
+
Chaitanya Sai Alaparthi <[email protected]>
|
482 |
+
Arihant Parsoya <[email protected]>
|
483 |
+
Ruslan Pisarev <[email protected]>
|
484 |
+
Akash Trehan <[email protected]>
|
485 |
+
Nishant Nikhil <[email protected]>
|
486 |
+
Vladimir Poluhsin <[email protected]>
|
487 |
+
Akshay Nagar <[email protected]>
|
488 |
+
James Brandon Milam <[email protected]>
|
489 |
+
Abhinav Agarwal <[email protected]>
|
490 |
+
Rishabh Daal <[email protected]>
|
491 |
+
Sanya Khurana <[email protected]>
|
492 |
+
Aman Deep <[email protected]>
|
493 |
+
Aravind Reddy <[email protected]>
|
494 |
+
Abhishek Verma <[email protected]>
|
495 |
+
Matthew Parnell <[email protected]>
|
496 |
+
Thomas Hickman <[email protected]>
|
497 |
+
Akshay Siramdas <[email protected]>
|
498 |
+
YiDing Jiang <[email protected]>
|
499 |
+
Jatin Yadav <[email protected]>
|
500 |
+
Matthew Thomas <[email protected]>
|
501 |
+
Rehas Sachdeva <[email protected]>
|
502 |
+
Michael Mueller <[email protected]>
|
503 |
+
Srajan Garg <[email protected]>
|
504 |
+
Prabhjot Singh <[email protected]>
|
505 |
+
Haruki Moriguchi <[email protected]>
|
506 |
+
Tom Gijselinck <[email protected]>
|
507 |
+
Nitin Chaudhary <[email protected]>
|
508 |
+
Alex Argunov <[email protected]>
|
509 |
+
Nathan Musoke <[email protected]>
|
510 |
+
Abhishek Garg <[email protected]>
|
511 |
+
Dana Jacobsen <[email protected]>
|
512 |
+
Vasiliy Dommes <[email protected]>
|
513 |
+
Phillip Berndt <[email protected]>
|
514 |
+
Haimo Zhang <[email protected]>
|
515 |
+
Anthony Scopatz <[email protected]>
|
516 |
+
bluebrook <[email protected]>
|
517 |
+
Leonid Kovalev <[email protected]>
|
518 |
+
Josh Burkart <[email protected]>
|
519 |
+
Dimitra Konomi <[email protected]>
|
520 |
+
Christina Zografou <[email protected]>
|
521 |
+
Fiach Antaw <[email protected]>
|
522 |
+
Langston Barrett <[email protected]>
|
523 |
+
Krit Karan <[email protected]>
|
524 |
+
G. D. McBain <[email protected]>
|
525 |
+
Prempal Singh <[email protected]>
|
526 |
+
Gabriel Orisaka <[email protected]>
|
527 |
+
Matthias Bussonnier <[email protected]>
|
528 |
+
rahuldan <[email protected]>
|
529 |
+
Colin Marquardt <[email protected]>
|
530 |
+
Andrew Taber <[email protected]>
|
531 |
+
Yash Reddy <[email protected]>
|
532 |
+
Peter Stangl <[email protected]>
|
533 |
+
elvis-sik <[email protected]>
|
534 |
+
Nikos Karagiannakis <[email protected]>
|
535 |
+
Jainul Vaghasia <[email protected]>
|
536 |
+
Dennis Meckel <[email protected]>
|
537 |
+
Harshil Meena <[email protected]>
|
538 |
+
Micky <[email protected]>
|
539 |
+
Nick Curtis <[email protected]>
|
540 |
+
Michele Zaffalon <[email protected]>
|
541 |
+
Martha Giannoudovardi <[email protected]>
|
542 |
+
Devang Kulshreshtha <[email protected]>
|
543 |
+
Steph Papanik <[email protected]>
|
544 |
+
Mohammad Sadeq Dousti <[email protected]>
|
545 |
+
Arif Ahmed <[email protected]>
|
546 |
+
Abdullah Javed Nesar <[email protected]>
|
547 |
+
Lakshya Agrawal <[email protected]>
|
548 |
+
shruti <[email protected]>
|
549 |
+
Rohit Rango <[email protected]>
|
550 |
+
Hong Xu <[email protected]>
|
551 |
+
Ivan Petuhov <[email protected]>
|
552 |
+
Alsheh <[email protected]>
|
553 |
+
Marcel Stimberg <[email protected]>
|
554 |
+
Alexey Pakhocmhik <[email protected]>
|
555 |
+
Tommy Olofsson <[email protected]>
|
556 |
+
Zulfikar <[email protected]>
|
557 |
+
Blair Azzopardi <[email protected]>
|
558 |
+
Danny Hermes <[email protected]>
|
559 |
+
Sergey Pestov <[email protected]>
|
560 |
+
Mohit Chandra <[email protected]>
|
561 |
+
Karthik Chintapalli <[email protected]>
|
562 |
+
Marcin Briański <[email protected]>
|
563 |
+
andreo <[email protected]>
|
564 |
+
Flamy Owl <[email protected]>
|
565 |
+
Yicong Guo <[email protected]>
|
566 |
+
Varun Garg <[email protected]>
|
567 |
+
Rishabh Madan <[email protected]>
|
568 |
+
Aditya Kapoor <[email protected]>
|
569 |
+
Karan Sharma <[email protected]>
|
570 |
+
Vedant Rathore <[email protected]>
|
571 |
+
Johan Blåbäck <[email protected]>
|
572 |
+
Pranjal Tale <[email protected]>
|
573 |
+
Jason Tokayer <[email protected]>
|
574 |
+
Raghav Jajodia <[email protected]>
|
575 |
+
Rajat Thakur <[email protected]>
|
576 |
+
Dhruv Bhanushali <[email protected]>
|
577 |
+
Anjul Kumar Tyagi <[email protected]>
|
578 |
+
Barun Parruck <[email protected]>
|
579 |
+
Bao Chau <[email protected]>
|
580 |
+
Tanay Agrawal <[email protected]>
|
581 |
+
Ranjith Kumar <[email protected]>
|
582 |
+
Shikhar Makhija <[email protected]>
|
583 |
+
Yathartha Joshi <[email protected]>
|
584 |
+
Valeriia Gladkova <[email protected]>
|
585 |
+
Sagar Bharadwaj <[email protected]>
|
586 |
+
Daniel Mahler <[email protected]>
|
587 |
+
Ka Yi <[email protected]>
|
588 |
+
Rishat Iskhakov <[email protected]>
|
589 |
+
Szymon Mieszczak <[email protected]>
|
590 |
+
Sachin Agarwal <[email protected]>
|
591 |
+
Priyank Patel <[email protected]>
|
592 |
+
Satya Prakash Dwibedi <[email protected]>
|
593 |
+
tools4origins <[email protected]>
|
594 |
+
Nico Schlömer <[email protected]>
|
595 |
+
Fermi Paradox <[email protected]>
|
596 |
+
Ekansh Purohit <[email protected]>
|
597 |
+
Vedarth Sharma <[email protected]>
|
598 |
+
Peeyush Kushwaha <[email protected]>
|
599 |
+
Jayjayyy <[email protected]>
|
600 |
+
Christopher J. Wright <[email protected]>
|
601 |
+
Jakub Wilk <[email protected]>
|
602 |
+
Mauro Garavello <[email protected]>
|
603 |
+
Chris Tefer <[email protected]>
|
604 |
+
Shikhar Jaiswal <[email protected]>
|
605 |
+
Chiu-Hsiang Hsu <[email protected]>
|
606 |
+
Carlos Cordoba <[email protected]>
|
607 |
+
Fabian Ball <[email protected]>
|
608 |
+
Yerniyaz <[email protected]>
|
609 |
+
Christiano Anderson <[email protected]>
|
610 |
+
Robin Neatherway <[email protected]>
|
611 |
+
Thomas Hunt <[email protected]>
|
612 |
+
Theodore Han <[email protected]>
|
613 |
+
Duc-Minh Phan <[email protected]>
|
614 |
+
Lejla Metohajrova <[email protected]>
|
615 |
+
Samyak Jain <[email protected]>
|
616 |
+
Aditya Rohan <[email protected]>
|
617 |
+
Vincent Delecroix <[email protected]>
|
618 |
+
Michael Sparapany <[email protected]>
|
619 |
+
Harsh Jain <[email protected]>
|
620 |
+
Nathan Goldbaum <[email protected]>
|
621 |
+
latot <[email protected]>
|
622 |
+
Kenneth Lyons <[email protected]>
|
623 |
+
Stan Schymanski <[email protected]>
|
624 |
+
David Daly <[email protected]>
|
625 |
+
Ayush Shridhar <[email protected]>
|
626 |
+
Javed Nissar <[email protected]>
|
627 |
+
Jiri Kuncar <[email protected]>
|
628 |
+
vedantc98 <[email protected]>
|
629 |
+
Rupesh Harode <[email protected]>
|
630 |
+
Rob Zinkov <[email protected]>
|
631 |
+
James Harrop <[email protected]>
|
632 |
+
James Taylor <[email protected]>
|
633 |
+
Ishan Joshi <[email protected]>
|
634 |
+
Marco Mancini <[email protected]>
|
635 |
+
Boris Ettinger <[email protected]>
|
636 |
+
Micah Fitch <[email protected]>
|
637 |
+
Daniel Wennberg <[email protected]>
|
638 |
+
ylemkimon <[email protected]>
|
639 |
+
Akash Vaish <[email protected]>
|
640 |
+
Peter Enenkel <[email protected]>
|
641 |
+
Waldir Pimenta <[email protected]>
|
642 |
+
Jithin D. George <[email protected]>
|
643 |
+
Lev Chelyadinov <[email protected]>
|
644 |
+
Lucas Wiman <[email protected]>
|
645 |
+
Rhea Parekh <[email protected]>
|
646 |
+
James Cotton <[email protected]>
|
647 |
+
Robert Pollak <[email protected]>
|
648 |
+
anca-mc <[email protected]>
|
649 |
+
Sourav Ghosh <[email protected]>
|
650 |
+
Jonathan Allan <[email protected]>
|
651 |
+
Nikhil Pappu <[email protected]>
|
652 |
+
Ethan Ward <[email protected]>
|
653 |
+
Cezary Marczak <[email protected]>
|
654 |
+
dps7ud <[email protected]>
|
655 |
+
Nilabja Bhattacharya <[email protected]>
|
656 |
+
Itay4 <[email protected]>
|
657 |
+
Poom Chiarawongse <[email protected]>
|
658 |
+
Yang Yang <[email protected]>
|
659 |
+
Cavendish McKay <[email protected]>
|
660 |
+
Bradley Gannon <[email protected]>
|
661 |
+
B McG <[email protected]>
|
662 |
+
Rob Drynkin <[email protected]>
|
663 |
+
Seth Ebner <[email protected]>
|
664 |
+
Akash Kundu <[email protected]>
|
665 |
+
Mark Jeromin <[email protected]>
|
666 |
+
Roberto Díaz Pérez <[email protected]>
|
667 |
+
Gleb Siroki <[email protected]>
|
668 |
+
Segev Finer <[email protected]>
|
669 |
+
Alex Lubbock <[email protected]>
|
670 |
+
Ayodeji Ige <[email protected]>
|
671 |
+
Matthew Wardrop <[email protected]>
|
672 |
+
Hugo van Kemenade <[email protected]>
|
673 |
+
Austin Palmer <[email protected]>
|
674 |
+
der-blaue-elefant <[email protected]>
|
675 |
+
Filip Gokstorp <[email protected]>
|
676 |
+
Yuki Matsuda <[email protected]>
|
677 |
+
Aaron Miller <[email protected]>
|
678 |
+
Salil Vishnu Kapur <[email protected]>
|
679 |
+
Atharva Khare <[email protected]>
|
680 |
+
Shubham Maheshwari <[email protected]>
|
681 |
+
Pavel Tkachenko <[email protected]>
|
682 |
+
Ashish Kumar Gaurav <[email protected]>
|
683 |
+
Rajeev Singh <[email protected]>
|
684 |
+
Keno Goertz <[email protected]>
|
685 |
+
Lucas Gallindo <[email protected]>
|
686 |
+
Himanshu <[email protected]>
|
687 |
+
David Menéndez Hurtado <[email protected]>
|
688 |
+
Amit Manchanda <[email protected]>
|
689 |
+
Rohit Jain <[email protected]>
|
690 |
+
Jonathan A. Gross <[email protected]>
|
691 |
+
Unknown <[email protected]>
|
692 |
+
Sayan Goswami <[email protected]>
|
693 |
+
Subhash Saurabh <[email protected]>
|
694 |
+
Rastislav Rabatin <[email protected]>
|
695 |
+
Vishal <[email protected]>
|
696 |
+
Jeremey Gluck <[email protected]>
|
697 |
+
Akshat Maheshwari <[email protected]>
|
698 |
+
symbolique <[email protected]>
|
699 |
+
Saloni Jain <[email protected]>
|
700 |
+
Arighna Chakrabarty <[email protected]>
|
701 |
+
Abhigyan Khaund <[email protected]>
|
702 |
+
Jashanpreet Singh <[email protected]>
|
703 |
+
Saurabh Agarwal <[email protected]>
|
704 |
+
luzpaz <[email protected]>
|
705 |
+
P. Sai Prasanth <[email protected]>
|
706 |
+
Nirmal Sarswat <[email protected]>
|
707 |
+
Cristian Di Pietrantonio <[email protected]>
|
708 |
+
Ravi charan <[email protected]>
|
709 |
+
Nityananda Gohain <[email protected]>
|
710 |
+
Cédric Travelletti <[email protected]>
|
711 |
+
Nicholas Bollweg <[email protected]>
|
712 |
+
Himanshu Ladia <[email protected]>
|
713 |
+
Adwait Baokar <[email protected]>
|
714 |
+
Mihail Tarigradschi <[email protected]>
|
715 |
+
Saketh <[email protected]>
|
716 |
+
rushyam <[email protected]>
|
717 |
+
sfoo <[email protected]>
|
718 |
+
Rahil Hastu <[email protected]>
|
719 |
+
Zach Raines <[email protected]>
|
720 |
+
Sidhant Nagpal <[email protected]>
|
721 |
+
Gagandeep Singh <[email protected]>
|
722 |
+
Rishav Chakraborty <[email protected]>
|
723 |
+
Malkhan Singh <[email protected]>
|
724 |
+
Joaquim Monserrat <[email protected]>
|
725 |
+
Mayank Singh <[email protected]>
|
726 |
+
Rémy Léone <[email protected]>
|
727 |
+
Maxence Mayrand <[email protected]>
|
728 |
+
Nikoleta Glynatsi <[email protected]>
|
729 |
+
helo9 <[email protected]>
|
730 |
+
Ken Wakita <[email protected]>
|
731 |
+
Carl Sandrock <[email protected]>
|
732 |
+
Fredrik Eriksson <[email protected]>
|
733 |
+
Ian Swire <[email protected]>
|
734 |
+
Bulat <[email protected]>
|
735 |
+
Ehren Metcalfe <[email protected]>
|
736 |
+
Dmitry Savransky <[email protected]>
|
737 |
+
Kiyohito Yamazaki <[email protected]>
|
738 |
+
Caley Finn <[email protected]>
|
739 |
+
Zhi-Qiang Zhou <[email protected]>
|
740 |
+
Alexander Pozdneev <[email protected]>
|
741 |
+
Wes Turner <[email protected]>
|
742 |
+
JMSS-Unknown <[email protected]>
|
743 |
+
Arshdeep Singh <[email protected]>
|
744 |
+
cym1 <[email protected]>
|
745 |
+
Stewart Wadsworth <[email protected]>
|
746 |
+
Jared Lumpe <[email protected]>
|
747 |
+
Avi Shrivastava <[email protected]>
|
748 |
+
ramvenkat98 <[email protected]>
|
749 |
+
Bilal Ahmed <[email protected]>
|
750 |
+
Dimas Abreu Archanjo Dutra <[email protected]>
|
751 |
+
Yatna Verma <[email protected]>
|
752 |
+
S.Y. Lee <[email protected]>
|
753 |
+
Miro Hrončok <[email protected]>
|
754 |
+
Sudarshan Kamath <[email protected]>
|
755 |
+
Ayushman Koul <[email protected]>
|
756 |
+
Robert Dougherty-Bliss <[email protected]>
|
757 |
+
Andrey Grozin <[email protected]>
|
758 |
+
Bavish Kulur <[email protected]>
|
759 |
+
Arun Singh <[email protected]>
|
760 |
+
sirnicolaf <[email protected]>
|
761 |
+
Zachariah Etienne <[email protected]>
|
762 |
+
Prayush Dawda <[email protected]>
|
763 |
+
2torus <[email protected]>
|
764 |
+
Faisal Riyaz <[email protected]>
|
765 |
+
Martin Roelfs <[email protected]>
|
766 |
+
SirJohnFranklin <[email protected]>
|
767 |
+
Anthony Sottile <[email protected]>
|
768 |
+
ViacheslavP <[email protected]>
|
769 |
+
Safiya03 <[email protected]>
|
770 |
+
Alexander Dunlap <[email protected]>
|
771 |
+
Rohit Sharma <[email protected]>
|
772 |
+
Jonathan Warner <[email protected]>
|
773 |
+
Mohit Balwani <[email protected]>
|
774 |
+
Marduk Bolaños <[email protected]>
|
775 |
+
amsuhane <[email protected]>
|
776 |
+
Matthias Geier <[email protected]>
|
777 |
+
klaasvanaarsen <[email protected]>
|
778 |
+
Shubham Kumar Jha <[email protected]>
|
779 |
+
rationa-kunal <[email protected]>
|
780 |
+
Animesh Sinha <[email protected]>
|
781 |
+
Gaurang Tandon <[email protected]>
|
782 |
+
Matthew Craven <[email protected]>
|
783 |
+
Daniel Ingram <[email protected]>
|
784 |
+
Jogi Miglani <[email protected]>
|
785 |
+
Takumasa Nakamura <[email protected]>
|
786 |
+
Ritu Raj Singh <[email protected]>
|
787 |
+
Rajiv Ranjan Singh <[email protected]>
|
788 |
+
Vera Lozhkina <[email protected]>
|
789 |
+
adhoc-king <[email protected]>
|
790 |
+
Mikel Rouco <[email protected]>
|
791 |
+
Oscar Gustafsson <[email protected]>
|
792 |
+
damianos <[email protected]>
|
793 |
+
Supreet Agrawal <[email protected]>
|
794 |
+
shiksha11 <[email protected]>
|
795 |
+
Martin Ueding <[email protected]>
|
796 |
+
sharma-kunal <[email protected]>
|
797 |
+
Divyanshu Thakur <[email protected]>
|
798 |
+
Susumu Ishizuka <[email protected]>
|
799 |
+
Samnan Rahee <[email protected]>
|
800 |
+
Fredrik Andersson <[email protected]>
|
801 |
+
Bhavya Srivastava <[email protected]>
|
802 |
+
Alpesh Jamgade <[email protected]>
|
803 |
+
Shubham Abhang <[email protected]>
|
804 |
+
Vishesh Mangla <[email protected]>
|
805 |
+
Nicko van Someren <[email protected]>
|
806 |
+
dandiez <[email protected]>
|
807 |
+
Frédéric Chapoton <[email protected]>
|
808 |
+
jhanwar <[email protected]>
|
809 |
+
Noumbissi valere Gille Geovan <[email protected]>
|
810 |
+
Salmista-94 <[email protected]>
|
811 |
+
Shivani Kohli <[email protected]>
|
812 |
+
Parker Berry <[email protected]>
|
813 |
+
Pragyan Mehrotra <[email protected]>
|
814 |
+
Nabanita Dash <[email protected]>
|
815 |
+
Gaetano Guerriero <[email protected]>
|
816 |
+
Ankit Raj Pandey <[email protected]>
|
817 |
+
Ritesh Kumar <[email protected]>
|
818 |
+
kangzhiq <[email protected]>
|
819 |
+
Jun Lin <[email protected]>
|
820 |
+
Petr Kungurtsev <[email protected]>
|
821 |
+
Anway De <[email protected]>
|
822 |
+
znxftw <[email protected]>
|
823 |
+
Denis Ivanenko <[email protected]>
|
824 |
+
Orestis Vaggelis <[email protected]>
|
825 |
+
Nikhil Maan <[email protected]>
|
826 |
+
Abhinav Anand <[email protected]>
|
827 |
+
Qingsha Shi <[email protected]>
|
828 |
+
Juan Barbosa <[email protected]>
|
829 |
+
Prionti Nasir <[email protected]>
|
830 |
+
Bharat Raghunathan <[email protected]>
|
831 |
+
arooshiverma <[email protected]>
|
832 |
+
Christoph Gohle <[email protected]>
|
833 |
+
Charalampos Tsiagkalis <[email protected]>
|
834 |
+
Daniel Sears <[email protected]>
|
835 |
+
Megan Ly <[email protected]>
|
836 |
+
Sean P. Cornelius <[email protected]>
|
837 |
+
Erik R. Gomez <[email protected]>
|
838 |
+
Riccardo Magliocchetti <[email protected]>
|
839 |
+
Henry Metlov <[email protected]>
|
840 |
+
pekochun <[email protected]>
|
841 |
+
Bendik Samseth <[email protected]>
|
842 |
+
Vighnesh Shenoy <[email protected]>
|
843 |
+
Versus Void <[email protected]>
|
844 |
+
Denys Rybalka <[email protected]>
|
845 |
+
Mark Dickinson <[email protected]>
|
846 |
+
Rimi <[email protected]>
|
847 |
+
rimibis <[email protected]>
|
848 |
+
Steven Lee <[email protected]>
|
849 |
+
Gilles Schintgen <[email protected]>
|
850 |
+
Abhi58 <[email protected]>
|
851 |
+
Tomasz Pytel <[email protected]>
|
852 |
+
Aadit Kamat <[email protected]>
|
853 |
+
Samesh <[email protected]>
|
854 |
+
Velibor Zeli <[email protected]>
|
855 |
+
Gabriel Bernardino <[email protected]>
|
856 |
+
Joseph Redfern <[email protected]>
|
857 |
+
Evelyn King <[email protected]>
|
858 |
+
Miguel Marco <[email protected]>
|
859 |
+
David Hagen <[email protected]>
|
860 |
+
Hannah Kari <[email protected]>
|
861 |
+
Soniya Nayak <[email protected]>
|
862 |
+
Harsh Agarwal <[email protected]>
|
863 |
+
Enric Florit <[email protected]>
|
864 |
+
Yogesh Mishra <[email protected]>
|
865 |
+
Denis Rykov <[email protected]>
|
866 |
+
Ivan Tkachenko <[email protected]>
|
867 |
+
Kenneth Emeka Odoh <[email protected]>
|
868 |
+
Stephan Seitz <[email protected]>
|
869 |
+
Yeshwanth N <[email protected]>
|
870 |
+
Oscar Gerardo Lazo Arjona <[email protected]>
|
871 |
+
Srinivasa Arun Yeragudipati <[email protected]>
|
872 |
+
Kirtan Mali <[email protected]>
|
873 |
+
TitanSnow <[email protected]>
|
874 |
+
Pengning Chao <[email protected]>
|
875 |
+
Louis Abraham <[email protected]>
|
876 |
+
Morten Olsen Lysgaard <[email protected]>
|
877 |
+
Akash Nagaraj (akasnaga) <[email protected]>
|
878 |
+
Akash Nagaraj <[email protected]>
|
879 |
+
Lauren Glattly <[email protected]>
|
880 |
+
Hou-Rui <[email protected]>
|
881 |
+
George Korepanov <[email protected]>
|
882 |
+
dranknight09 <[email protected]>
|
883 |
+
aditisingh2362 <[email protected]>
|
884 |
+
Gina <[email protected]>
|
885 |
+
gregmedlock <[email protected]>
|
886 |
+
Georgios Giapitzakis Tzintanos <[email protected]>
|
887 |
+
Eric Wieser <[email protected]>
|
888 |
+
Bradley Dowling <[email protected]>
|
889 |
+
Maria Marginean <[email protected]>
|
890 |
+
Akash Agrawall <[email protected]>
|
891 |
+
jgulian <[email protected]>
|
892 |
+
Sourav Goyal <[email protected]>
|
893 |
+
Zlatan Vasović <[email protected]>
|
894 |
+
Alex Meiburg <[email protected]>
|
895 |
+
Smit Lunagariya <[email protected]>
|
896 |
+
Naman Gera <[email protected]>
|
897 |
+
Julien Palard <[email protected]>
|
898 |
+
Dhruv Mendiratta <[email protected]>
|
899 |
+
erdOne <[email protected]>
|
900 |
+
risubaba <[email protected]>
|
901 |
+
abhinav28071999 <[email protected]>
|
902 |
+
Jisoo Song <[email protected]>
|
903 |
+
Jaime R <[email protected]>
|
904 |
+
Vikrant Malik <[email protected]>
|
905 |
+
Hardik Saini <[email protected]>
|
906 |
+
Abhishek <[email protected]>
|
907 |
+
Johannes Hartung <[email protected]>
|
908 |
+
Milan Jolly <[email protected]>
|
909 |
+
faizan2700 <[email protected]>
|
910 |
+
mohit <[email protected]>
|
911 |
+
Mohit Gupta <[email protected]>
|
912 |
+
Psycho-Pirate <[email protected]>
|
913 |
+
Chanakya-Ekbote <[email protected]>
|
914 |
+
Rashmi Shehana <[email protected]>
|
915 |
+
Jonty16117 <[email protected]>
|
916 |
+
Anubhav Gupta <[email protected]>
|
917 |
+
Michal Grňo <[email protected]>
|
918 |
+
vezeli <[email protected]>
|
919 |
+
Tim Gates <[email protected]>
|
920 |
+
Sandeep Murthy <[email protected]>
|
921 |
+
Neil <[email protected]>
|
922 |
+
V1krant <[email protected]>
|
923 |
+
alejandro <[email protected]>
|
924 |
+
Riyan Dhiman <[email protected]>
|
925 |
+
sbt4104 <[email protected]>
|
926 |
+
Seth Troisi <[email protected]>
|
927 |
+
Bhaskar Gupta <[email protected]>
|
928 |
+
Smit Gajjar <[email protected]>
|
929 |
+
rbl <[email protected]>
|
930 |
+
Ilya Pchelintsev <[email protected]>
|
931 |
+
Omar Wagih <[email protected]>
|
932 |
+
prshnt19 <[email protected]>
|
933 |
+
Johan Guzman <[email protected]>
|
934 |
+
Vasileios Kalos <[email protected]>
|
935 |
+
BasileiosKal <[email protected]>
|
936 |
+
Shubham Thorat <[email protected]>
|
937 |
+
Arpan Chattopadhyay <[email protected]>
|
938 |
+
Ashutosh Hathidara <[email protected]>
|
939 |
+
Moses Paul R <[email protected]>
|
940 |
+
Saanidhya vats <[email protected]>
|
941 |
+
tnzl <[email protected]>
|
942 |
+
Vatsal Srivastava <[email protected]>
|
943 |
+
Jean-Luc Herren <[email protected]>
|
944 |
+
Dhruv Kothari <[email protected]>
|
945 |
+
seadavis <[email protected]>
|
946 |
+
kamimura <[email protected]>
|
947 |
+
slacker404 <[email protected]>
|
948 |
+
Jaime Resano <[email protected]>
|
949 |
+
Ebrahim Byagowi <[email protected]>
|
950 |
+
wuyudi <[email protected]>
|
951 |
+
Akira Kyle <[email protected]>
|
952 |
+
Calvin Jay Ross <[email protected]>
|
953 |
+
Martin Thoma <[email protected]>
|
954 |
+
Thomas A Caswell <[email protected]>
|
955 |
+
Lagaras Stelios <[email protected]>
|
956 |
+
Jerry James <[email protected]>
|
957 |
+
Jan Kruse <[email protected]>
|
958 |
+
Nathan Taylor <[email protected]>
|
959 |
+
Vaishnav Damani <[email protected]>
|
960 |
+
Mohit Shah <[email protected]>
|
961 |
+
Mathias Louboutin <[email protected]>
|
962 |
+
Marijan Smetko <[email protected]>
|
963 |
+
Dave Witte Morris <[email protected]>
|
964 |
+
soumi7 <[email protected]>
|
965 |
+
Zhongshi <[email protected]>
|
966 |
+
Wes Galbraith <[email protected]>
|
967 |
+
KaustubhDamania <[email protected]>
|
968 |
+
w495 <[email protected]>
|
969 |
+
Akhil Rajput <[email protected]>
|
970 |
+
Markus Mohrhard <[email protected]>
|
971 |
+
Benjamin Wolba <[email protected]>
|
972 |
+
彭于斌 <[email protected]>
|
973 |
+
Rudr Tiwari <[email protected]>
|
974 |
+
Aaryan Dewan <[email protected]>
|
975 |
+
Benedikt Placke <[email protected]>
|
976 |
+
Sneha Goddu <[email protected]>
|
977 |
+
goddus <[email protected]>
|
978 |
+
Shivang Dubey <[email protected]>
|
979 |
+
Michael Greminger <[email protected]>
|
980 |
+
Peter Cock <[email protected]>
|
981 |
+
Willem Melching <[email protected]>
|
982 |
+
Elias Basler <[email protected]>
|
983 |
+
Brandon David <[email protected]>
|
984 |
+
Abhay_Dhiman <[email protected]>
|
985 |
+
Tasha Kim <[email protected]>
|
986 |
+
Ayush Malik <[email protected]>
|
987 |
+
Devesh Sawant <[email protected]>
|
988 |
+
Wolfgang Stöcher <[email protected]>
|
989 |
+
Sudeep Sidhu <[email protected]>
|
990 |
+
foice <[email protected]>
|
991 |
+
Ben Payne <[email protected]>
|
992 |
+
Muskan Kumar <[email protected]>
|
993 |
+
noam simcha finkelstein <[email protected]>
|
994 |
+
Garrett Folbe <[email protected]>
|
995 |
+
Islam Mansour <[email protected]>
|
996 |
+
Sayandip Halder <[email protected]>
|
997 |
+
Shubham Agrawal <[email protected]>
|
998 |
+
numbermaniac <[email protected]>
|
999 |
+
Sakirul Alam <[email protected]>
|
1000 |
+
Mohammed Bilal <[email protected]>
|
1001 |
+
Chris du Plessis <[email protected]>
|
1002 |
+
Coder-RG <[email protected]>
|
1003 |
+
Ansh Mishra <[email protected]>
|
1004 |
+
Alex Malins <[email protected]>
|
1005 |
+
Lorenzo Contento <[email protected]>
|
1006 |
+
Naveen Sai <[email protected]>
|
1007 |
+
Shital Mule <[email protected]>
|
1008 |
+
Amanda Dsouza <[email protected]>
|
1009 |
+
Nijso Beishuizen <[email protected]>
|
1010 |
+
Harry Zheng <[email protected]>
|
1011 |
+
Felix Yan <[email protected]>
|
1012 |
+
Constantin Mateescu <[email protected]>
|
1013 |
+
Eva Tiwari <[email protected]>
|
1014 |
+
Aditya Kumar Sinha <[email protected]>
|
1015 |
+
Soumi Bardhan <[email protected]>
|
1016 |
+
Kaustubh Chaudhari <[email protected]>
|
1017 |
+
Kristian Brünn <[email protected]>
|
1018 |
+
Neel Gorasiya <[email protected]>
|
1019 |
+
Akshat Sood <[email protected]>
|
1020 |
+
Jose M. Gomez <[email protected]>
|
1021 |
+
Stefan Petrea <[email protected]>
|
1022 |
+
Praveen Sahu <[email protected]>
|
1023 |
+
Mark Bell <[email protected]>
|
1024 |
+
AlexCQY <[email protected]>
|
1025 |
+
Fabian Froehlich <[email protected]>
|
1026 |
+
Nikhil Gopalam <[email protected]>
|
1027 |
+
Kartik Sethi <[email protected]>
|
1028 |
+
Muhammed Abdul Quadir Owais <[email protected]>
|
1029 |
+
Harshit Yadav <[email protected]>
|
1030 |
+
Sidharth Mundhra <[email protected]>
|
1031 |
+
Suryam Arnav Kalra <[email protected]>
|
1032 |
+
Prince Gupta <[email protected]>
|
1033 |
+
Kunal Singh <[email protected]>
|
1034 |
+
Mayank Raj <[email protected]>
|
1035 |
+
Achal Jain <[email protected]>
|
1036 |
+
Mario Maio <[email protected]>
|
1037 |
+
Aaron Stiff <[email protected]>
|
1038 |
+
Wyatt Peak <[email protected]>
|
1039 |
+
Bhaskar Joshi <[email protected]>
|
1040 |
+
Aditya Jindal <[email protected]>
|
1041 |
+
Vaibhav Bhat <[email protected]>
|
1042 |
+
Priyansh Rathi <[email protected]>
|
1043 |
+
Saket Kumar Singh <[email protected]>
|
1044 |
+
Yukai Chou <[email protected]>
|
1045 |
+
Qijia Liu <[email protected]>
|
1046 |
+
Paul Mandel <[email protected]>
|
1047 |
+
Nisarg Chaudhari <[email protected]>
|
1048 |
+
Dominik Stańczak <[email protected]>
|
1049 |
+
Rodrigo Luger <[email protected]>
|
1050 |
+
Marco Antônio Habitzreuter <[email protected]>
|
1051 |
+
Ayush Bisht <[email protected]>
|
1052 |
+
Akshansh Bhatt <[email protected]>
|
1053 |
+
Brandon T. Willard <[email protected]>
|
1054 |
+
Thomas Aarholt <[email protected]>
|
1055 |
+
Hiren Chalodiya <[email protected]>
|
1056 |
+
Roland Dixon <[email protected]>
|
1057 |
+
dimasvq <[email protected]>
|
1058 |
+
Sagar231 <[email protected]>
|
1059 |
+
Michael Chu <[email protected]>
|
1060 |
+
Abby Ng <[email protected]>
|
1061 |
+
Angad Sandhu <[email protected]>
|
1062 |
+
Alexander Cockburn <[email protected]>
|
1063 |
+
Yaser AlOsh <[email protected]>
|
1064 |
+
Davide Sandonà <[email protected]>
|
1065 |
+
Jonathan Gutow <[email protected]>
|
1066 |
+
Nihir Agarwal <[email protected]>
|
1067 |
+
Lee Johnston <[email protected]>
|
1068 |
+
Zach Carmichael <[email protected]>
|
1069 |
+
Vijairam Ganesh Moorthy <[email protected]>
|
1070 |
+
Hanspeter Schmid <[email protected]>
|
1071 |
+
Ben Oostendorp <[email protected]>
|
1072 |
+
Nikita <[email protected]>
|
1073 |
+
Aman <[email protected]>
|
1074 |
+
Shashank KS <[email protected]>
|
1075 |
+
Aman Sharma <[email protected]>
|
1076 |
+
Anup Parikh <[email protected]>
|
1077 |
+
Lucy Mountain <[email protected]>
|
1078 |
+
Miguel Torres Costa <[email protected]>
|
1079 |
+
Rikard Nordgren <[email protected]>
|
1080 |
+
Arun sanganal <[email protected]>
|
1081 |
+
Kamlesh Joshi <[email protected]>
|
1082 |
+
Joseph Rance <[email protected]>
|
1083 |
+
Huangduirong <[email protected]>
|
1084 |
+
Nils Schulte <[email protected]>
|
1085 |
+
Matt Bogosian <[email protected]>
|
1086 |
+
Elisha Hollander <[email protected]>
|
1087 |
+
Aditya Ravuri <[email protected]>
|
1088 |
+
Mamidi Ratna Praneeth <[email protected]>
|
1089 |
+
Jeffrey Ryan <[email protected]>
|
1090 |
+
Jonathan Daniel <[email protected]>
|
1091 |
+
Robin Richard <[email protected]>
|
1092 |
+
Gautam Menghani <[email protected]>
|
1093 |
+
Remco de Boer <[email protected]>
|
1094 |
+
Sebastian East <[email protected]>
|
1095 |
+
Evani Balasubramanyam <[email protected]>
|
1096 |
+
Rahil Parikh <[email protected]>
|
1097 |
+
Jason Ross <[email protected]>
|
1098 |
+
Joannah Nanjekye <[email protected]>
|
1099 |
+
Ayush Kumar <[email protected]>
|
1100 |
+
Kshitij <[email protected]>
|
1101 |
+
Daniel Hyams <[email protected]>
|
1102 |
+
alijosephine <[email protected]>
|
1103 |
+
Matthias Köppe <[email protected]>
|
1104 |
+
mohajain <[email protected]>
|
1105 |
+
Anibal M. Medina-Mardones <[email protected]>
|
1106 |
+
Travis Ens <[email protected]>
|
1107 |
+
Evgenia Karunus <[email protected]>
|
1108 |
+
Risiraj Dey <[email protected]>
|
1109 |
+
lastcodestanding <[email protected]>
|
1110 |
+
Andrey Lekar <[email protected]>
|
1111 |
+
Abbas Mohammed <[email protected]>
|
1112 |
+
anutosh491 <[email protected]>
|
1113 |
+
Steve Kieffer <[email protected]>
|
1114 |
+
Paul Spiering <[email protected]>
|
1115 |
+
Pieter Gijsbers <[email protected]>
|
1116 |
+
Wang Ran (汪然) <[email protected]>
|
1117 |
+
naelsondouglas <[email protected]>
|
1118 |
+
Aman Thakur <[email protected]>
|
1119 |
+
S. Hanko <[email protected]>
|
1120 |
+
Dennis Sweeney <[email protected]>
|
1121 |
+
Gurpartap Singh <[email protected]>
|
1122 |
+
Hampus Malmberg <[email protected]>
|
1123 |
+
scimax <[email protected]>
|
1124 |
+
Nikhil Date <[email protected]>
|
1125 |
+
Kuldeep Borkar Jr <[email protected]>
|
1126 |
+
AkuBrain <[email protected]>
|
1127 |
+
Leo Battle <[email protected]>
|
1128 |
+
Advait Pote <[email protected]>
|
1129 |
+
Anurag Bhat <[email protected]>
|
1130 |
+
Jeremy Monat <[email protected]>
|
1131 |
+
Diane Tchuindjo <[email protected]>
|
1132 |
+
Tom Fryers <[email protected]>
|
1133 |
+
Zouhair <[email protected]>
|
1134 |
+
zzj <[email protected]>
|
1135 |
+
shubhayu09 <[email protected]>
|
1136 |
+
Siddhant Jain <[email protected]>
|
1137 |
+
Tirthankar Mazumder <[email protected]>
|
1138 |
+
Sumit Kumar <[email protected]>
|
1139 |
+
Shivam Sagar <[email protected]>
|
1140 |
+
Gaurav Jain <[email protected]>
|
1141 |
+
Andrii Oriekhov <[email protected]>
|
1142 |
+
Luis Talavera <[email protected]>
|
1143 |
+
Arie Bovenberg <[email protected]>
|
1144 |
+
Carson McManus <[email protected]>
|
1145 |
+
Jack Schmidt <[email protected]>
|
1146 |
+
Riley Britten <[email protected]>
|
1147 |
+
Georges Khaznadar <[email protected]>
|
1148 |
+
Donald Wilson <[email protected]>
|
1149 |
+
Timo Stienstra <[email protected]>
|
1150 |
+
dispasha <[email protected]>
|
1151 |
+
Saksham Alok <[email protected]>
|
1152 |
+
Varenyam Bhardwaj <[email protected]>
|
1153 |
+
oittaa <[email protected]>
|
1154 |
+
Omkaar <[email protected]>
|
1155 |
+
Islem BOUZENIA <[email protected]>
|
1156 |
+
extraymond <[email protected]>
|
1157 |
+
Alexander Behrens <[email protected]>
|
1158 |
+
user202729 <[email protected]>
|
1159 |
+
Pieter Eendebak <[email protected]>
|
1160 |
+
Zaz Brown <[email protected]>
|
1161 |
+
ritikBhandari <[email protected]>
|
1162 |
+
viocha <[email protected]>
|
1163 |
+
Arthur Ryman <[email protected]>
|
1164 |
+
Xiang Wu <[email protected]>
|
1165 |
+
tttc3 <[email protected]>
|
1166 |
+
Seth Poulsen <[email protected]>
|
1167 |
+
cocolato <[email protected]>
|
1168 |
+
Anton Golovanov <[email protected]>
|
1169 |
+
Gareth Ma <[email protected]>
|
1170 |
+
Clément M.T. Robert <[email protected]>
|
1171 |
+
Glenn Horton-Smith <[email protected]>
|
1172 |
+
Karan <[email protected]>
|
1173 |
+
Stefan Behnle <[email protected]>
|
1174 |
+
Shreyash Mishra <[email protected]>
|
1175 |
+
Arthur Milchior <[email protected]>
|
1176 |
+
NotWearingPants <[email protected]>
|
1177 |
+
Ishan Pandhare <[email protected]>
|
1178 |
+
Carlos García Montoro <[email protected]>
|
1179 |
+
Parcly Taxel <[email protected]>
|
1180 |
+
Saicharan <[email protected]>
|
1181 |
+
Kunal Sheth <[email protected]>
|
1182 |
+
Biswadeep Purkayastha <[email protected]>
|
1183 |
+
Jyn Spring 琴春 <[email protected]>
|
1184 |
+
Phil LeMaitre <[email protected]>
|
1185 |
+
Chris Kerr <[email protected]>
|
1186 |
+
José Senart <[email protected]>
|
1187 |
+
Uwe L. Korn <[email protected]>
|
1188 |
+
ForeverHaibara <[email protected]>
|
1189 |
+
Yves Tumushimire <[email protected]>
|
1190 |
+
wookie184 <[email protected]>
|
1191 |
+
Costor <[email protected]>
|
1192 |
+
Klaus Rettinghaus <[email protected]>
|
1193 |
+
Sam Brockie <[email protected]>
|
1194 |
+
Abhishek Patidar <[email protected]>
|
1195 |
+
Eric Demer <[email protected]>
|
1196 |
+
Pontus von Brömssen <[email protected]>
|
1197 |
+
Victor Immanuel <[email protected]>
|
1198 |
+
Evandro Bernardes <[email protected]>
|
1199 |
+
Michele Ceccacci <[email protected]>
|
1200 |
+
Ayush Aryan <[email protected]>
|
1201 |
+
Kishore Gopalakrishnan <[email protected]>
|
1202 |
+
Jan-Philipp Hoffmann <[email protected]>
|
1203 |
+
Daiki Takahashi <[email protected]>
|
1204 |
+
Sayan Mitra <[email protected]>
|
1205 |
+
Aman Kumar Shukla <[email protected]>
|
1206 |
+
Zoufiné Lauer-Baré <[email protected]>
|
1207 |
+
Charles Harris <[email protected]>
|
1208 |
+
Tejaswini Sanapathi <[email protected]>
|
1209 |
+
Devansh <[email protected]>
|
1210 |
+
Aaron Gokaslan <[email protected]>
|
1211 |
+
Daan Koning (he/him) <[email protected]>
|
1212 |
+
Steven Burns <[email protected]>
|
1213 |
+
Jay Patankar <[email protected]>
|
1214 |
+
Vivek Soni <[email protected]>
|
1215 |
+
Le Cong Minh Hieu <[email protected]>
|
1216 |
+
Sam Ritchie <[email protected]>
|
1217 |
+
Maciej Skórski <[email protected]>
|
1218 |
+
Tilo Reneau-Cardoso <[email protected]>
|
1219 |
+
Laurence Warne <[email protected]>
|
1220 |
+
Lukas Molleman <[email protected]>
|
1221 |
+
Konstantinos Riganas <[email protected]>
|
1222 |
+
Grace Su <[email protected]>
|
1223 |
+
Pedro Rosa <[email protected]>
|
1224 |
+
Abhinav Cillanki <[email protected]>
|
1225 |
+
Baiyuan Qiu <[email protected]>
|
1226 |
+
Liwei Cai <[email protected]>
|
1227 |
+
Daniel Weindl <[email protected]>
|
1228 |
+
Isidora Araya <[email protected]>
|
1229 |
+
Seb Tiburzio <[email protected]>
|
1230 |
+
Victory Omole <[email protected]>
|
1231 |
+
Abhishek Chaudhary <[email protected]>
|
1232 |
+
Alexander Zhura <[email protected]>
|
1233 |
+
Shuai Zhou <[email protected]>
|
1234 |
+
Martin Manns <[email protected]>
|
1235 |
+
John Möller <[email protected]>
|
1236 |
+
zzc <[email protected]>
|
1237 |
+
Pablo Galindo Salgado <[email protected]>
|
1238 |
+
Johannes Kasimir <[email protected]>
|
1239 |
+
Theodore Dias <[email protected]>
|
1240 |
+
Kaustubh <[email protected]>
|
1241 |
+
Idan Pazi <[email protected]>
|
1242 |
+
Ishan Pandhare <[email protected]>
|
1243 |
+
Shishir Kushwaha <[email protected]>
|
1244 |
+
Bobby Palmer <[email protected]>
|
1245 |
+
Saikat Das <[email protected]>
|
1246 |
+
Suman mondal <[email protected]>
|
1247 |
+
Taylan Sahin <[email protected]>
|
1248 |
+
Fabio Luporini <[email protected]>
|
1249 |
+
Oriel Malihi <[email protected]>
|
1250 |
+
Geetika Vadali <[email protected]>
|
1251 |
+
Matthias Rettl <[email protected]>
|
1252 |
+
Mikhail Remnev <[email protected]>
|
1253 |
+
philwillnyc <[email protected]>
|
1254 |
+
Raphael Lehner <[email protected]>
|
1255 |
+
Harry Mountain <[email protected]>
|
1256 |
+
Bhavik Sachdev <[email protected]>
|
1257 |
+
袁野 (Yuan Ye) <[email protected]>
|
1258 |
+
fazledyn-or <[email protected]>
|
1259 |
+
mohammedouahman <[email protected]>
|
1260 |
+
K. Kraus <[email protected]>
|
1261 |
+
Zac Hatfield-Dodds <[email protected]>
|
1262 |
+
platypus <[email protected]>
|
1263 |
+
codecruisader <[email protected]>
|
1264 |
+
James Whitehead <[email protected]>
|
1265 |
+
atharvParlikar <[email protected]>
|
1266 |
+
Ivan Petukhov <[email protected]>
|
1267 |
+
Augusto Borges <[email protected]>
|
1268 |
+
Han Wei Ang <[email protected]>
|
1269 |
+
Congxu Yang <[email protected]>
|
1270 |
+
Saicharan <[email protected]>
|
1271 |
+
Arnab Nandi <[email protected]>
|
1272 |
+
Harrison Oates <[email protected]>
|
1273 |
+
Corey Cerovsek <[email protected]>
|
1274 |
+
Harsh Kasat <[email protected]>
|
1275 |
+
omahs <[email protected]>
|
1276 |
+
Pascal Gitz <[email protected]>
|
1277 |
+
Ravindu-Hirimuthugoda <[email protected]>
|
1278 |
+
Sophia Pustova <[email protected]>
|
1279 |
+
George Pittock <[email protected]>
|
1280 |
+
Warren Jacinto <[email protected]>
|
1281 |
+
Sachin Singh <[email protected]>
|
1282 |
+
Zedmat <[email protected]>
|
1283 |
+
Samith Karunathilake <[email protected]>
|
1284 |
+
Viraj Vekaria <[email protected]>
|
1285 |
+
Ankit Kumar Singh <[email protected]>
|
1286 |
+
Abhishek Kumar <[email protected]>
|
1287 |
+
Mohak Malviya <[email protected]>
|
1288 |
+
Matthias Liesenfeld <[email protected]>
|
1289 |
+
dodo <[email protected]>
|
1290 |
+
Mohamed Rezk <[email protected]>
|
1291 |
+
Tommaso Vaccari <[email protected]>
|
1292 |
+
Alexis Schotte <[email protected]>
|
1293 |
+
Lauren Yim <[email protected]>
|
1294 |
+
Prey Patel <[email protected]>
|
1295 |
+
Riccardo Di Girolamo <[email protected]>
|
1296 |
+
Abhishek kumar <[email protected]>
|
1297 |
+
Sam Lubelsky <[email protected]>
|
1298 |
+
Henrique Soares <[email protected]>
|
1299 |
+
Vladimir Sereda <[email protected]>
|
1300 |
+
Raj Sapale <[email protected]>
|
1301 |
+
Gerald Teschl <[email protected]>
|
1302 |
+
Richard Samuel <[email protected]>
|
1303 |
+
HeeJae Chang <[email protected]>
|
1304 |
+
Hwayeon Kang <[email protected]>
|
1305 |
+
Nick Harder <[email protected]>
|
1306 |
+
Ethan DeGuire <[email protected]>
|
1307 |
+
Lorenz Winkler <[email protected]>
|
1308 |
+
Richard Rodenbusch <[email protected]>
|
1309 |
+
Zhenxu Zhu <[email protected]>
|
1310 |
+
Mark van Gelder <[email protected]>
|
1311 |
+
James A. Preiss <[email protected]>
|
1312 |
+
Emile Fourcini <[email protected]>
|
1313 |
+
Alberto Jiménez Ruiz <[email protected]>
|
1314 |
+
João Bravo <[email protected]>
|
1315 |
+
Dean Price <[email protected]>
|
1316 |
+
Hugo Kerstens <[email protected]>
|
1317 |
+
Jan Jancar <[email protected]>
|
MLPY/Lib/site-packages/sympy-1.13.1.dist-info/INSTALLER
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
pip
|
MLPY/Lib/site-packages/sympy-1.13.1.dist-info/LICENSE
ADDED
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (c) 2006-2023 SymPy Development Team
|
2 |
+
|
3 |
+
All rights reserved.
|
4 |
+
|
5 |
+
Redistribution and use in source and binary forms, with or without
|
6 |
+
modification, are permitted provided that the following conditions are met:
|
7 |
+
|
8 |
+
a. Redistributions of source code must retain the above copyright notice,
|
9 |
+
this list of conditions and the following disclaimer.
|
10 |
+
b. Redistributions in binary form must reproduce the above copyright
|
11 |
+
notice, this list of conditions and the following disclaimer in the
|
12 |
+
documentation and/or other materials provided with the distribution.
|
13 |
+
c. Neither the name of SymPy nor the names of its contributors
|
14 |
+
may be used to endorse or promote products derived from this software
|
15 |
+
without specific prior written permission.
|
16 |
+
|
17 |
+
|
18 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19 |
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21 |
+
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
22 |
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23 |
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24 |
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25 |
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
26 |
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
27 |
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
28 |
+
DAMAGE.
|
29 |
+
|
30 |
+
--------------------------------------------------------------------------------
|
31 |
+
|
32 |
+
Patches that were taken from the Diofant project (https://github.com/diofant/diofant)
|
33 |
+
are licensed as:
|
34 |
+
|
35 |
+
Copyright (c) 2006-2018 SymPy Development Team,
|
36 |
+
2013-2023 Sergey B Kirpichev
|
37 |
+
|
38 |
+
All rights reserved.
|
39 |
+
|
40 |
+
Redistribution and use in source and binary forms, with or without
|
41 |
+
modification, are permitted provided that the following conditions are met:
|
42 |
+
|
43 |
+
a. Redistributions of source code must retain the above copyright notice,
|
44 |
+
this list of conditions and the following disclaimer.
|
45 |
+
b. Redistributions in binary form must reproduce the above copyright
|
46 |
+
notice, this list of conditions and the following disclaimer in the
|
47 |
+
documentation and/or other materials provided with the distribution.
|
48 |
+
c. Neither the name of Diofant or SymPy nor the names of its contributors
|
49 |
+
may be used to endorse or promote products derived from this software
|
50 |
+
without specific prior written permission.
|
51 |
+
|
52 |
+
|
53 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
54 |
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
55 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
56 |
+
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
57 |
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
58 |
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
59 |
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
60 |
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
61 |
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
62 |
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
63 |
+
DAMAGE.
|
64 |
+
|
65 |
+
--------------------------------------------------------------------------------
|
66 |
+
|
67 |
+
Submodules taken from the multipledispatch project (https://github.com/mrocklin/multipledispatch)
|
68 |
+
are licensed as:
|
69 |
+
|
70 |
+
Copyright (c) 2014 Matthew Rocklin
|
71 |
+
|
72 |
+
All rights reserved.
|
73 |
+
|
74 |
+
Redistribution and use in source and binary forms, with or without
|
75 |
+
modification, are permitted provided that the following conditions are met:
|
76 |
+
|
77 |
+
a. Redistributions of source code must retain the above copyright notice,
|
78 |
+
this list of conditions and the following disclaimer.
|
79 |
+
b. Redistributions in binary form must reproduce the above copyright
|
80 |
+
notice, this list of conditions and the following disclaimer in the
|
81 |
+
documentation and/or other materials provided with the distribution.
|
82 |
+
c. Neither the name of multipledispatch nor the names of its contributors
|
83 |
+
may be used to endorse or promote products derived from this software
|
84 |
+
without specific prior written permission.
|
85 |
+
|
86 |
+
|
87 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
88 |
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
89 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
90 |
+
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
91 |
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
92 |
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
93 |
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
94 |
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
95 |
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
96 |
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
97 |
+
DAMAGE.
|
98 |
+
|
99 |
+
--------------------------------------------------------------------------------
|
100 |
+
|
101 |
+
The files under the directory sympy/parsing/autolev/tests/pydy-example-repo
|
102 |
+
are directly copied from PyDy project and are licensed as:
|
103 |
+
|
104 |
+
Copyright (c) 2009-2023, PyDy Authors
|
105 |
+
All rights reserved.
|
106 |
+
|
107 |
+
Redistribution and use in source and binary forms, with or without
|
108 |
+
modification, are permitted provided that the following conditions are met:
|
109 |
+
|
110 |
+
* Redistributions of source code must retain the above copyright
|
111 |
+
notice, this list of conditions and the following disclaimer.
|
112 |
+
* Redistributions in binary form must reproduce the above copyright
|
113 |
+
notice, this list of conditions and the following disclaimer in the
|
114 |
+
documentation and/or other materials provided with the distribution.
|
115 |
+
* Neither the name of this project nor the names of its contributors may be
|
116 |
+
used to endorse or promote products derived from this software without
|
117 |
+
specific prior written permission.
|
118 |
+
|
119 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
120 |
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
121 |
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
122 |
+
DISCLAIMED. IN NO EVENT SHALL PYDY AUTHORS BE LIABLE FOR ANY DIRECT,
|
123 |
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
124 |
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
125 |
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
126 |
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
127 |
+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
128 |
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
129 |
+
|
130 |
+
--------------------------------------------------------------------------------
|
131 |
+
|
132 |
+
The files under the directory sympy/parsing/latex
|
133 |
+
are directly copied from latex2sympy project and are licensed as:
|
134 |
+
|
135 |
+
Copyright 2016, latex2sympy
|
136 |
+
|
137 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
138 |
+
of this software and associated documentation files (the "Software"), to deal
|
139 |
+
in the Software without restriction, including without limitation the rights
|
140 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
141 |
+
copies of the Software, and to permit persons to whom the Software is
|
142 |
+
furnished to do so, subject to the following conditions:
|
143 |
+
|
144 |
+
The above copyright notice and this permission notice shall be included in all
|
145 |
+
copies or substantial portions of the Software.
|
146 |
+
|
147 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
148 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
149 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
150 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
151 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
152 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
153 |
+
SOFTWARE.
|
MLPY/Lib/site-packages/sympy-1.13.1.dist-info/METADATA
ADDED
@@ -0,0 +1,304 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Metadata-Version: 2.1
|
2 |
+
Name: sympy
|
3 |
+
Version: 1.13.1
|
4 |
+
Summary: Computer algebra system (CAS) in Python
|
5 |
+
Home-page: https://sympy.org
|
6 |
+
Author: SymPy development team
|
7 |
+
Author-email: [email protected]
|
8 |
+
License: BSD
|
9 |
+
Project-URL: Source, https://github.com/sympy/sympy
|
10 |
+
Keywords: Math CAS
|
11 |
+
Classifier: License :: OSI Approved :: BSD License
|
12 |
+
Classifier: Operating System :: OS Independent
|
13 |
+
Classifier: Programming Language :: Python
|
14 |
+
Classifier: Topic :: Scientific/Engineering
|
15 |
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
16 |
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
17 |
+
Classifier: Programming Language :: Python :: 3
|
18 |
+
Classifier: Programming Language :: Python :: 3.8
|
19 |
+
Classifier: Programming Language :: Python :: 3.9
|
20 |
+
Classifier: Programming Language :: Python :: 3.10
|
21 |
+
Classifier: Programming Language :: Python :: 3.11
|
22 |
+
Classifier: Programming Language :: Python :: 3 :: Only
|
23 |
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
24 |
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
25 |
+
Requires-Python: >=3.8
|
26 |
+
Description-Content-Type: text/markdown
|
27 |
+
License-File: LICENSE
|
28 |
+
License-File: AUTHORS
|
29 |
+
Requires-Dist: mpmath <1.4,>=1.1.0
|
30 |
+
Provides-Extra: dev
|
31 |
+
Requires-Dist: pytest >=7.1.0 ; extra == 'dev'
|
32 |
+
Requires-Dist: hypothesis >=6.70.0 ; extra == 'dev'
|
33 |
+
|
34 |
+
# SymPy
|
35 |
+
|
36 |
+
[](https://pypi.python.org/pypi/sympy)
|
37 |
+
[](https://gitter.im/sympy/sympy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
38 |
+
[](https://zenodo.org/badge/latestdoi/18918/sympy/sympy)
|
39 |
+
[](https://pepy.tech/project/sympy)
|
40 |
+
[](https://github.com/sympy/sympy/issues)
|
41 |
+
[](https://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project)
|
42 |
+
[](https://numfocus.org)
|
43 |
+
[](https://github.com/sympy/sympy/releases)
|
44 |
+
|
45 |
+
[](https://sympy.org/)
|
46 |
+
|
47 |
+
|
48 |
+
See the [AUTHORS](AUTHORS) file for the list of authors.
|
49 |
+
|
50 |
+
And many more people helped on the SymPy mailing list, reported bugs,
|
51 |
+
helped organize SymPy's participation in the Google Summer of Code, the
|
52 |
+
Google Highly Open Participation Contest, Google Code-In, wrote and
|
53 |
+
blogged about SymPy...
|
54 |
+
|
55 |
+
License: New BSD License (see the [LICENSE](LICENSE) file for details) covers all
|
56 |
+
files in the sympy repository unless stated otherwise.
|
57 |
+
|
58 |
+
Our mailing list is at
|
59 |
+
<https://groups.google.com/forum/?fromgroups#!forum/sympy>.
|
60 |
+
|
61 |
+
We have a community chat at [Gitter](https://gitter.im/sympy/sympy). Feel
|
62 |
+
free to ask us anything there. We have a very welcoming and helpful
|
63 |
+
community.
|
64 |
+
|
65 |
+
## Download
|
66 |
+
|
67 |
+
The recommended installation method is through Anaconda,
|
68 |
+
<https://www.anaconda.com/products/distribution>
|
69 |
+
|
70 |
+
You can also get the latest version of SymPy from
|
71 |
+
<https://pypi.python.org/pypi/sympy/>
|
72 |
+
|
73 |
+
To get the git version do
|
74 |
+
|
75 |
+
$ git clone https://github.com/sympy/sympy.git
|
76 |
+
|
77 |
+
For other options (tarballs, debs, etc.), see
|
78 |
+
<https://docs.sympy.org/dev/install.html>.
|
79 |
+
|
80 |
+
## Documentation and Usage
|
81 |
+
|
82 |
+
For in-depth instructions on installation and building the
|
83 |
+
documentation, see the [SymPy Documentation Style Guide](https://docs.sympy.org/dev/documentation-style-guide.html).
|
84 |
+
|
85 |
+
Everything is at:
|
86 |
+
|
87 |
+
<https://docs.sympy.org/>
|
88 |
+
|
89 |
+
You can generate everything at the above site in your local copy of
|
90 |
+
SymPy by:
|
91 |
+
|
92 |
+
$ cd doc
|
93 |
+
$ make html
|
94 |
+
|
95 |
+
Then the docs will be in <span class="title-ref">\_build/html</span>. If
|
96 |
+
you don't want to read that, here is a short usage:
|
97 |
+
|
98 |
+
From this directory, start Python and:
|
99 |
+
|
100 |
+
``` python
|
101 |
+
>>> from sympy import Symbol, cos
|
102 |
+
>>> x = Symbol('x')
|
103 |
+
>>> e = 1/cos(x)
|
104 |
+
>>> print(e.series(x, 0, 10))
|
105 |
+
1 + x**2/2 + 5*x**4/24 + 61*x**6/720 + 277*x**8/8064 + O(x**10)
|
106 |
+
```
|
107 |
+
|
108 |
+
SymPy also comes with a console that is a simple wrapper around the
|
109 |
+
classic python console (or IPython when available) that loads the SymPy
|
110 |
+
namespace and executes some common commands for you.
|
111 |
+
|
112 |
+
To start it, issue:
|
113 |
+
|
114 |
+
$ bin/isympy
|
115 |
+
|
116 |
+
from this directory, if SymPy is not installed or simply:
|
117 |
+
|
118 |
+
$ isympy
|
119 |
+
|
120 |
+
if SymPy is installed.
|
121 |
+
|
122 |
+
## Installation
|
123 |
+
|
124 |
+
To install SymPy using PyPI, run the following command:
|
125 |
+
|
126 |
+
$ pip install sympy
|
127 |
+
|
128 |
+
To install SymPy using Anaconda, run the following command:
|
129 |
+
|
130 |
+
$ conda install -c anaconda sympy
|
131 |
+
|
132 |
+
To install SymPy from GitHub source, first clone SymPy using `git`:
|
133 |
+
|
134 |
+
$ git clone https://github.com/sympy/sympy.git
|
135 |
+
|
136 |
+
Then, in the `sympy` repository that you cloned, simply run:
|
137 |
+
|
138 |
+
$ pip install .
|
139 |
+
|
140 |
+
See <https://docs.sympy.org/dev/install.html> for more information.
|
141 |
+
|
142 |
+
## Contributing
|
143 |
+
|
144 |
+
We welcome contributions from anyone, even if you are new to open
|
145 |
+
source. Please read our [Introduction to Contributing](https://docs.sympy.org/dev/contributing/introduction-to-contributing.html)
|
146 |
+
page and the [SymPy Documentation Style Guide](https://docs.sympy.org/dev/documentation-style-guide.html). If you
|
147 |
+
are new and looking for some way to contribute, a good place to start is
|
148 |
+
to look at the issues tagged [Easy to Fix](https://github.com/sympy/sympy/issues?q=is%3Aopen+is%3Aissue+label%3A%22Easy+to+Fix%22).
|
149 |
+
|
150 |
+
Please note that all participants in this project are expected to follow
|
151 |
+
our Code of Conduct. By participating in this project you agree to abide
|
152 |
+
by its terms. See [CODE\_OF\_CONDUCT.md](CODE_OF_CONDUCT.md).
|
153 |
+
|
154 |
+
## Tests
|
155 |
+
|
156 |
+
To execute all tests, run:
|
157 |
+
|
158 |
+
$./setup.py test
|
159 |
+
|
160 |
+
in the current directory.
|
161 |
+
|
162 |
+
For the more fine-grained running of tests or doctests, use `bin/test`
|
163 |
+
or respectively `bin/doctest`. The master branch is automatically tested
|
164 |
+
by GitHub Actions.
|
165 |
+
|
166 |
+
To test pull requests, use
|
167 |
+
[sympy-bot](https://github.com/sympy/sympy-bot).
|
168 |
+
|
169 |
+
## Regenerate Experimental <span class="title-ref">LaTeX</span> Parser/Lexer
|
170 |
+
|
171 |
+
The parser and lexer were generated with the [ANTLR4](http://antlr4.org)
|
172 |
+
toolchain in `sympy/parsing/latex/_antlr` and checked into the repo.
|
173 |
+
Presently, most users should not need to regenerate these files, but
|
174 |
+
if you plan to work on this feature, you will need the `antlr4`
|
175 |
+
command-line tool (and you must ensure that it is in your `PATH`).
|
176 |
+
One way to get it is:
|
177 |
+
|
178 |
+
$ conda install -c conda-forge antlr=4.11.1
|
179 |
+
|
180 |
+
Alternatively, follow the instructions on the ANTLR website and download
|
181 |
+
the `antlr-4.11.1-complete.jar`. Then export the `CLASSPATH` as instructed
|
182 |
+
and instead of creating `antlr4` as an alias, make it an executable file
|
183 |
+
with the following contents:
|
184 |
+
``` bash
|
185 |
+
#!/bin/bash
|
186 |
+
java -jar /usr/local/lib/antlr-4.11.1-complete.jar "$@"
|
187 |
+
```
|
188 |
+
|
189 |
+
After making changes to `sympy/parsing/latex/LaTeX.g4`, run:
|
190 |
+
|
191 |
+
$ ./setup.py antlr
|
192 |
+
|
193 |
+
## Clean
|
194 |
+
|
195 |
+
To clean everything (thus getting the same tree as in the repository):
|
196 |
+
|
197 |
+
$ git clean -Xdf
|
198 |
+
|
199 |
+
which will clear everything ignored by `.gitignore`, and:
|
200 |
+
|
201 |
+
$ git clean -df
|
202 |
+
|
203 |
+
to clear all untracked files. You can revert the most recent changes in
|
204 |
+
git with:
|
205 |
+
|
206 |
+
$ git reset --hard
|
207 |
+
|
208 |
+
WARNING: The above commands will all clear changes you may have made,
|
209 |
+
and you will lose them forever. Be sure to check things with `git
|
210 |
+
status`, `git diff`, `git clean -Xn`, and `git clean -n` before doing any
|
211 |
+
of those.
|
212 |
+
|
213 |
+
## Bugs
|
214 |
+
|
215 |
+
Our issue tracker is at <https://github.com/sympy/sympy/issues>. Please
|
216 |
+
report any bugs that you find. Or, even better, fork the repository on
|
217 |
+
GitHub and create a pull request. We welcome all changes, big or small,
|
218 |
+
and we will help you make the pull request if you are new to git (just
|
219 |
+
ask on our mailing list or Gitter Channel). If you further have any queries, you can find answers
|
220 |
+
on Stack Overflow using the [sympy](https://stackoverflow.com/questions/tagged/sympy) tag.
|
221 |
+
|
222 |
+
## Brief History
|
223 |
+
|
224 |
+
SymPy was started by Ondřej Čertík in 2005, he wrote some code during
|
225 |
+
the summer, then he wrote some more code during summer 2006. In February
|
226 |
+
2007, Fabian Pedregosa joined the project and helped fix many things,
|
227 |
+
contributed documentation, and made it alive again. 5 students (Mateusz
|
228 |
+
Paprocki, Brian Jorgensen, Jason Gedge, Robert Schwarz, and Chris Wu)
|
229 |
+
improved SymPy incredibly during summer 2007 as part of the Google
|
230 |
+
Summer of Code. Pearu Peterson joined the development during the summer
|
231 |
+
2007 and he has made SymPy much more competitive by rewriting the core
|
232 |
+
from scratch, which has made it from 10x to 100x faster. Jurjen N.E. Bos
|
233 |
+
has contributed pretty-printing and other patches. Fredrik Johansson has
|
234 |
+
written mpmath and contributed a lot of patches.
|
235 |
+
|
236 |
+
SymPy has participated in every Google Summer of Code since 2007. You
|
237 |
+
can see <https://github.com/sympy/sympy/wiki#google-summer-of-code> for
|
238 |
+
full details. Each year has improved SymPy by bounds. Most of SymPy's
|
239 |
+
development has come from Google Summer of Code students.
|
240 |
+
|
241 |
+
In 2011, Ondřej Čertík stepped down as lead developer, with Aaron
|
242 |
+
Meurer, who also started as a Google Summer of Code student, taking his
|
243 |
+
place. Ondřej Čertík is still active in the community but is too busy
|
244 |
+
with work and family to play a lead development role.
|
245 |
+
|
246 |
+
Since then, a lot more people have joined the development and some
|
247 |
+
people have also left. You can see the full list in doc/src/aboutus.rst,
|
248 |
+
or online at:
|
249 |
+
|
250 |
+
<https://docs.sympy.org/dev/aboutus.html#sympy-development-team>
|
251 |
+
|
252 |
+
The git history goes back to 2007 when development moved from svn to hg.
|
253 |
+
To see the history before that point, look at
|
254 |
+
<https://github.com/sympy/sympy-old>.
|
255 |
+
|
256 |
+
You can use git to see the biggest developers. The command:
|
257 |
+
|
258 |
+
$ git shortlog -ns
|
259 |
+
|
260 |
+
will show each developer, sorted by commits to the project. The command:
|
261 |
+
|
262 |
+
$ git shortlog -ns --since="1 year"
|
263 |
+
|
264 |
+
will show the top developers from the last year.
|
265 |
+
|
266 |
+
## Citation
|
267 |
+
|
268 |
+
To cite SymPy in publications use
|
269 |
+
|
270 |
+
> Meurer A, Smith CP, Paprocki M, Čertík O, Kirpichev SB, Rocklin M,
|
271 |
+
> Kumar A, Ivanov S, Moore JK, Singh S, Rathnayake T, Vig S, Granger BE,
|
272 |
+
> Muller RP, Bonazzi F, Gupta H, Vats S, Johansson F, Pedregosa F, Curry
|
273 |
+
> MJ, Terrel AR, Roučka Š, Saboo A, Fernando I, Kulal S, Cimrman R,
|
274 |
+
> Scopatz A. (2017) SymPy: symbolic computing in Python. *PeerJ Computer
|
275 |
+
> Science* 3:e103 <https://doi.org/10.7717/peerj-cs.103>
|
276 |
+
|
277 |
+
A BibTeX entry for LaTeX users is
|
278 |
+
|
279 |
+
``` bibtex
|
280 |
+
@article{10.7717/peerj-cs.103,
|
281 |
+
title = {SymPy: symbolic computing in Python},
|
282 |
+
author = {Meurer, Aaron and Smith, Christopher P. and Paprocki, Mateusz and \v{C}ert\'{i}k, Ond\v{r}ej and Kirpichev, Sergey B. and Rocklin, Matthew and Kumar, Amit and Ivanov, Sergiu and Moore, Jason K. and Singh, Sartaj and Rathnayake, Thilina and Vig, Sean and Granger, Brian E. and Muller, Richard P. and Bonazzi, Francesco and Gupta, Harsh and Vats, Shivam and Johansson, Fredrik and Pedregosa, Fabian and Curry, Matthew J. and Terrel, Andy R. and Rou\v{c}ka, \v{S}t\v{e}p\'{a}n and Saboo, Ashutosh and Fernando, Isuru and Kulal, Sumith and Cimrman, Robert and Scopatz, Anthony},
|
283 |
+
year = 2017,
|
284 |
+
month = Jan,
|
285 |
+
keywords = {Python, Computer algebra system, Symbolics},
|
286 |
+
abstract = {
|
287 |
+
SymPy is an open-source computer algebra system written in pure Python. It is built with a focus on extensibility and ease of use, through both interactive and programmatic applications. These characteristics have led SymPy to become a popular symbolic library for the scientific Python ecosystem. This paper presents the architecture of SymPy, a description of its features, and a discussion of select submodules. The supplementary material provides additional examples and further outlines details of the architecture and features of SymPy.
|
288 |
+
},
|
289 |
+
volume = 3,
|
290 |
+
pages = {e103},
|
291 |
+
journal = {PeerJ Computer Science},
|
292 |
+
issn = {2376-5992},
|
293 |
+
url = {https://doi.org/10.7717/peerj-cs.103},
|
294 |
+
doi = {10.7717/peerj-cs.103}
|
295 |
+
}
|
296 |
+
```
|
297 |
+
|
298 |
+
SymPy is BSD licensed, so you are free to use it whatever you like, be
|
299 |
+
it academic, commercial, creating forks or derivatives, as long as you
|
300 |
+
copy the BSD statement if you redistribute it (see the LICENSE file for
|
301 |
+
details). That said, although not required by the SymPy license, if it
|
302 |
+
is convenient for you, please cite SymPy when using it in your work and
|
303 |
+
also consider contributing all your changes back, so that we can
|
304 |
+
incorporate it and all of us will benefit in the end.
|
MLPY/Lib/site-packages/sympy-1.13.1.dist-info/RECORD
ADDED
The diff for this file is too large to render.
See raw diff
|
|
MLPY/Lib/site-packages/sympy-1.13.1.dist-info/WHEEL
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Wheel-Version: 1.0
|
2 |
+
Generator: setuptools (71.0.3)
|
3 |
+
Root-Is-Purelib: true
|
4 |
+
Tag: py3-none-any
|
5 |
+
|
MLPY/Lib/site-packages/sympy-1.13.1.dist-info/entry_points.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
[console_scripts]
|
2 |
+
isympy = isympy:main
|
MLPY/Lib/site-packages/sympy-1.13.1.dist-info/top_level.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
isympy
|
2 |
+
sympy
|
MLPY/Lib/site-packages/sympy/__init__.py
ADDED
@@ -0,0 +1,542 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
SymPy is a Python library for symbolic mathematics. It aims to become a
|
3 |
+
full-featured computer algebra system (CAS) while keeping the code as simple
|
4 |
+
as possible in order to be comprehensible and easily extensible. SymPy is
|
5 |
+
written entirely in Python. It depends on mpmath, and other external libraries
|
6 |
+
may be optionally for things like plotting support.
|
7 |
+
|
8 |
+
See the webpage for more information and documentation:
|
9 |
+
|
10 |
+
https://sympy.org
|
11 |
+
|
12 |
+
"""
|
13 |
+
|
14 |
+
|
15 |
+
import sys
|
16 |
+
if sys.version_info < (3, 8):
|
17 |
+
raise ImportError("Python version 3.8 or above is required for SymPy.")
|
18 |
+
del sys
|
19 |
+
|
20 |
+
|
21 |
+
try:
|
22 |
+
import mpmath
|
23 |
+
except ImportError:
|
24 |
+
raise ImportError("SymPy now depends on mpmath as an external library. "
|
25 |
+
"See https://docs.sympy.org/latest/install.html#mpmath for more information.")
|
26 |
+
|
27 |
+
del mpmath
|
28 |
+
|
29 |
+
from sympy.release import __version__
|
30 |
+
from sympy.core.cache import lazy_function
|
31 |
+
|
32 |
+
if 'dev' in __version__:
|
33 |
+
def enable_warnings():
|
34 |
+
import warnings
|
35 |
+
warnings.filterwarnings('default', '.*', DeprecationWarning, module='sympy.*')
|
36 |
+
del warnings
|
37 |
+
enable_warnings()
|
38 |
+
del enable_warnings
|
39 |
+
|
40 |
+
|
41 |
+
def __sympy_debug():
|
42 |
+
# helper function so we don't import os globally
|
43 |
+
import os
|
44 |
+
debug_str = os.getenv('SYMPY_DEBUG', 'False')
|
45 |
+
if debug_str in ('True', 'False'):
|
46 |
+
return eval(debug_str)
|
47 |
+
else:
|
48 |
+
raise RuntimeError("unrecognized value for SYMPY_DEBUG: %s" %
|
49 |
+
debug_str)
|
50 |
+
SYMPY_DEBUG = __sympy_debug() # type: bool
|
51 |
+
|
52 |
+
from .core import (sympify, SympifyError, cacheit, Basic, Atom,
|
53 |
+
preorder_traversal, S, Expr, AtomicExpr, UnevaluatedExpr, Symbol,
|
54 |
+
Wild, Dummy, symbols, var, Number, Float, Rational, Integer,
|
55 |
+
NumberSymbol, RealNumber, igcd, ilcm, seterr, E, I, nan, oo, pi, zoo,
|
56 |
+
AlgebraicNumber, comp, mod_inverse, Pow, integer_nthroot, integer_log,
|
57 |
+
trailing, Mul, prod, Add, Mod, Rel, Eq, Ne, Lt, Le, Gt, Ge, Equality,
|
58 |
+
GreaterThan, LessThan, Unequality, StrictGreaterThan, StrictLessThan,
|
59 |
+
vectorize, Lambda, WildFunction, Derivative, diff, FunctionClass,
|
60 |
+
Function, Subs, expand, PoleError, count_ops, expand_mul, expand_log,
|
61 |
+
expand_func, expand_trig, expand_complex, expand_multinomial, nfloat,
|
62 |
+
expand_power_base, expand_power_exp, arity, PrecisionExhausted, N,
|
63 |
+
evalf, Tuple, Dict, gcd_terms, factor_terms, factor_nc, evaluate,
|
64 |
+
Catalan, EulerGamma, GoldenRatio, TribonacciConstant, bottom_up, use,
|
65 |
+
postorder_traversal, default_sort_key, ordered, num_digits)
|
66 |
+
|
67 |
+
from .logic import (to_cnf, to_dnf, to_nnf, And, Or, Not, Xor, Nand, Nor,
|
68 |
+
Implies, Equivalent, ITE, POSform, SOPform, simplify_logic, bool_map,
|
69 |
+
true, false, satisfiable)
|
70 |
+
|
71 |
+
from .assumptions import (AppliedPredicate, Predicate, AssumptionsContext,
|
72 |
+
assuming, Q, ask, register_handler, remove_handler, refine)
|
73 |
+
|
74 |
+
from .polys import (Poly, PurePoly, poly_from_expr, parallel_poly_from_expr,
|
75 |
+
degree, total_degree, degree_list, LC, LM, LT, pdiv, prem, pquo,
|
76 |
+
pexquo, div, rem, quo, exquo, half_gcdex, gcdex, invert,
|
77 |
+
subresultants, resultant, discriminant, cofactors, gcd_list, gcd,
|
78 |
+
lcm_list, lcm, terms_gcd, trunc, monic, content, primitive, compose,
|
79 |
+
decompose, sturm, gff_list, gff, sqf_norm, sqf_part, sqf_list, sqf,
|
80 |
+
factor_list, factor, intervals, refine_root, count_roots, all_roots,
|
81 |
+
real_roots, nroots, ground_roots, nth_power_roots_poly, cancel,
|
82 |
+
reduced, groebner, is_zero_dimensional, GroebnerBasis, poly,
|
83 |
+
symmetrize, horner, interpolate, rational_interpolate, viete, together,
|
84 |
+
BasePolynomialError, ExactQuotientFailed, PolynomialDivisionFailed,
|
85 |
+
OperationNotSupported, HeuristicGCDFailed, HomomorphismFailed,
|
86 |
+
IsomorphismFailed, ExtraneousFactors, EvaluationFailed,
|
87 |
+
RefinementFailed, CoercionFailed, NotInvertible, NotReversible,
|
88 |
+
NotAlgebraic, DomainError, PolynomialError, UnificationFailed,
|
89 |
+
GeneratorsError, GeneratorsNeeded, ComputationFailed,
|
90 |
+
UnivariatePolynomialError, MultivariatePolynomialError,
|
91 |
+
PolificationFailed, OptionError, FlagError, minpoly,
|
92 |
+
minimal_polynomial, primitive_element, field_isomorphism,
|
93 |
+
to_number_field, isolate, round_two, prime_decomp, prime_valuation,
|
94 |
+
galois_group, itermonomials, Monomial, lex, grlex,
|
95 |
+
grevlex, ilex, igrlex, igrevlex, CRootOf, rootof, RootOf,
|
96 |
+
ComplexRootOf, RootSum, roots, Domain, FiniteField, IntegerRing,
|
97 |
+
RationalField, RealField, ComplexField, PythonFiniteField,
|
98 |
+
GMPYFiniteField, PythonIntegerRing, GMPYIntegerRing, PythonRational,
|
99 |
+
GMPYRationalField, AlgebraicField, PolynomialRing, FractionField,
|
100 |
+
ExpressionDomain, FF_python, FF_gmpy, ZZ_python, ZZ_gmpy, QQ_python,
|
101 |
+
QQ_gmpy, GF, FF, ZZ, QQ, ZZ_I, QQ_I, RR, CC, EX, EXRAW,
|
102 |
+
construct_domain, swinnerton_dyer_poly, cyclotomic_poly,
|
103 |
+
symmetric_poly, random_poly, interpolating_poly, jacobi_poly,
|
104 |
+
chebyshevt_poly, chebyshevu_poly, hermite_poly, hermite_prob_poly,
|
105 |
+
legendre_poly, laguerre_poly, apart, apart_list, assemble_partfrac_list,
|
106 |
+
Options, ring, xring, vring, sring, field, xfield, vfield, sfield)
|
107 |
+
|
108 |
+
from .series import (Order, O, limit, Limit, gruntz, series, approximants,
|
109 |
+
residue, EmptySequence, SeqPer, SeqFormula, sequence, SeqAdd, SeqMul,
|
110 |
+
fourier_series, fps, difference_delta, limit_seq)
|
111 |
+
|
112 |
+
from .functions import (factorial, factorial2, rf, ff, binomial,
|
113 |
+
RisingFactorial, FallingFactorial, subfactorial, carmichael,
|
114 |
+
fibonacci, lucas, motzkin, tribonacci, harmonic, bernoulli, bell, euler,
|
115 |
+
catalan, genocchi, andre, partition, divisor_sigma, legendre_symbol,
|
116 |
+
jacobi_symbol, kronecker_symbol, mobius, primenu, primeomega,
|
117 |
+
totient, reduced_totient, primepi, sqrt, root, Min, Max, Id,
|
118 |
+
real_root, Rem, cbrt, re, im, sign, Abs, conjugate, arg, polar_lift,
|
119 |
+
periodic_argument, unbranched_argument, principal_branch, transpose,
|
120 |
+
adjoint, polarify, unpolarify, sin, cos, tan, sec, csc, cot, sinc,
|
121 |
+
asin, acos, atan, asec, acsc, acot, atan2, exp_polar, exp, ln, log,
|
122 |
+
LambertW, sinh, cosh, tanh, coth, sech, csch, asinh, acosh, atanh,
|
123 |
+
acoth, asech, acsch, floor, ceiling, frac, Piecewise, piecewise_fold,
|
124 |
+
piecewise_exclusive, erf, erfc, erfi, erf2, erfinv, erfcinv, erf2inv,
|
125 |
+
Ei, expint, E1, li, Li, Si, Ci, Shi, Chi, fresnels, fresnelc, gamma,
|
126 |
+
lowergamma, uppergamma, polygamma, loggamma, digamma, trigamma,
|
127 |
+
multigamma, dirichlet_eta, zeta, lerchphi, polylog, stieltjes, Eijk,
|
128 |
+
LeviCivita, KroneckerDelta, SingularityFunction, DiracDelta, Heaviside,
|
129 |
+
bspline_basis, bspline_basis_set, interpolating_spline, besselj,
|
130 |
+
bessely, besseli, besselk, hankel1, hankel2, jn, yn, jn_zeros, hn1,
|
131 |
+
hn2, airyai, airybi, airyaiprime, airybiprime, marcumq, hyper,
|
132 |
+
meijerg, appellf1, legendre, assoc_legendre, hermite, hermite_prob,
|
133 |
+
chebyshevt, chebyshevu, chebyshevu_root, chebyshevt_root, laguerre,
|
134 |
+
assoc_laguerre, gegenbauer, jacobi, jacobi_normalized, Ynm, Ynm_c,
|
135 |
+
Znm, elliptic_k, elliptic_f, elliptic_e, elliptic_pi, beta, mathieus,
|
136 |
+
mathieuc, mathieusprime, mathieucprime, riemann_xi, betainc, betainc_regularized)
|
137 |
+
|
138 |
+
from .ntheory import (nextprime, prevprime, prime, primerange,
|
139 |
+
randprime, Sieve, sieve, primorial, cycle_length, composite,
|
140 |
+
compositepi, isprime, divisors, proper_divisors, factorint,
|
141 |
+
multiplicity, perfect_power, pollard_pm1, pollard_rho, primefactors,
|
142 |
+
divisor_count, proper_divisor_count,
|
143 |
+
factorrat,
|
144 |
+
mersenne_prime_exponent, is_perfect, is_mersenne_prime, is_abundant,
|
145 |
+
is_deficient, is_amicable, is_carmichael, abundance, npartitions, is_primitive_root,
|
146 |
+
is_quad_residue, n_order, sqrt_mod,
|
147 |
+
quadratic_residues, primitive_root, nthroot_mod, is_nthpow_residue,
|
148 |
+
sqrt_mod_iter, discrete_log, quadratic_congruence,
|
149 |
+
binomial_coefficients, binomial_coefficients_list,
|
150 |
+
multinomial_coefficients, continued_fraction_periodic,
|
151 |
+
continued_fraction_iterator, continued_fraction_reduce,
|
152 |
+
continued_fraction_convergents, continued_fraction, egyptian_fraction)
|
153 |
+
|
154 |
+
from .concrete import product, Product, summation, Sum
|
155 |
+
|
156 |
+
from .discrete import (fft, ifft, ntt, intt, fwht, ifwht, mobius_transform,
|
157 |
+
inverse_mobius_transform, convolution, covering_product,
|
158 |
+
intersecting_product)
|
159 |
+
|
160 |
+
from .simplify import (simplify, hypersimp, hypersimilar, logcombine,
|
161 |
+
separatevars, posify, besselsimp, kroneckersimp, signsimp,
|
162 |
+
nsimplify, FU, fu, sqrtdenest, cse, epath, EPath, hyperexpand,
|
163 |
+
collect, rcollect, radsimp, collect_const, fraction, numer, denom,
|
164 |
+
trigsimp, exptrigsimp, powsimp, powdenest, combsimp, gammasimp,
|
165 |
+
ratsimp, ratsimpmodprime)
|
166 |
+
|
167 |
+
from .sets import (Set, Interval, Union, EmptySet, FiniteSet, ProductSet,
|
168 |
+
Intersection, DisjointUnion, imageset, Complement, SymmetricDifference, ImageSet,
|
169 |
+
Range, ComplexRegion, Complexes, Reals, Contains, ConditionSet, Ordinal,
|
170 |
+
OmegaPower, ord0, PowerSet, Naturals, Naturals0, UniversalSet,
|
171 |
+
Integers, Rationals)
|
172 |
+
|
173 |
+
from .solvers import (solve, solve_linear_system, solve_linear_system_LU,
|
174 |
+
solve_undetermined_coeffs, nsolve, solve_linear, checksol, det_quick,
|
175 |
+
inv_quick, check_assumptions, failing_assumptions, diophantine,
|
176 |
+
rsolve, rsolve_poly, rsolve_ratio, rsolve_hyper, checkodesol,
|
177 |
+
classify_ode, dsolve, homogeneous_order, solve_poly_system,
|
178 |
+
solve_triangulated, pde_separate, pde_separate_add, pde_separate_mul,
|
179 |
+
pdsolve, classify_pde, checkpdesol, ode_order, reduce_inequalities,
|
180 |
+
reduce_abs_inequality, reduce_abs_inequalities, solve_poly_inequality,
|
181 |
+
solve_rational_inequalities, solve_univariate_inequality, decompogen,
|
182 |
+
solveset, linsolve, linear_eq_to_matrix, nonlinsolve, substitution)
|
183 |
+
|
184 |
+
from .matrices import (ShapeError, NonSquareMatrixError, GramSchmidt,
|
185 |
+
casoratian, diag, eye, hessian, jordan_cell, list2numpy, matrix2numpy,
|
186 |
+
matrix_multiply_elementwise, ones, randMatrix, rot_axis1, rot_axis2,
|
187 |
+
rot_axis3, symarray, wronskian, zeros, MutableDenseMatrix,
|
188 |
+
DeferredVector, MatrixBase, Matrix, MutableMatrix,
|
189 |
+
MutableSparseMatrix, banded, ImmutableDenseMatrix,
|
190 |
+
ImmutableSparseMatrix, ImmutableMatrix, SparseMatrix, MatrixSlice,
|
191 |
+
BlockDiagMatrix, BlockMatrix, FunctionMatrix, Identity, Inverse,
|
192 |
+
MatAdd, MatMul, MatPow, MatrixExpr, MatrixSymbol, Trace, Transpose,
|
193 |
+
ZeroMatrix, OneMatrix, blockcut, block_collapse, matrix_symbols,
|
194 |
+
Adjoint, hadamard_product, HadamardProduct, HadamardPower,
|
195 |
+
Determinant, det, diagonalize_vector, DiagMatrix, DiagonalMatrix,
|
196 |
+
DiagonalOf, trace, DotProduct, kronecker_product, KroneckerProduct,
|
197 |
+
PermutationMatrix, MatrixPermute, Permanent, per, rot_ccw_axis1,
|
198 |
+
rot_ccw_axis2, rot_ccw_axis3, rot_givens)
|
199 |
+
|
200 |
+
from .geometry import (Point, Point2D, Point3D, Line, Ray, Segment, Line2D,
|
201 |
+
Segment2D, Ray2D, Line3D, Segment3D, Ray3D, Plane, Ellipse, Circle,
|
202 |
+
Polygon, RegularPolygon, Triangle, rad, deg, are_similar, centroid,
|
203 |
+
convex_hull, idiff, intersection, closest_points, farthest_points,
|
204 |
+
GeometryError, Curve, Parabola)
|
205 |
+
|
206 |
+
from .utilities import (flatten, group, take, subsets, variations,
|
207 |
+
numbered_symbols, cartes, capture, dict_merge, prefixes, postfixes,
|
208 |
+
sift, topological_sort, unflatten, has_dups, has_variety, reshape,
|
209 |
+
rotations, filldedent, lambdify,
|
210 |
+
threaded, xthreaded, public, memoize_property, timed)
|
211 |
+
|
212 |
+
from .integrals import (integrate, Integral, line_integrate, mellin_transform,
|
213 |
+
inverse_mellin_transform, MellinTransform, InverseMellinTransform,
|
214 |
+
laplace_transform, laplace_correspondence, laplace_initial_conds,
|
215 |
+
inverse_laplace_transform, LaplaceTransform,
|
216 |
+
InverseLaplaceTransform, fourier_transform, inverse_fourier_transform,
|
217 |
+
FourierTransform, InverseFourierTransform, sine_transform,
|
218 |
+
inverse_sine_transform, SineTransform, InverseSineTransform,
|
219 |
+
cosine_transform, inverse_cosine_transform, CosineTransform,
|
220 |
+
InverseCosineTransform, hankel_transform, inverse_hankel_transform,
|
221 |
+
HankelTransform, InverseHankelTransform, singularityintegrate)
|
222 |
+
|
223 |
+
from .tensor import (IndexedBase, Idx, Indexed, get_contraction_structure,
|
224 |
+
get_indices, shape, MutableDenseNDimArray, ImmutableDenseNDimArray,
|
225 |
+
MutableSparseNDimArray, ImmutableSparseNDimArray, NDimArray,
|
226 |
+
tensorproduct, tensorcontraction, tensordiagonal, derive_by_array,
|
227 |
+
permutedims, Array, DenseNDimArray, SparseNDimArray)
|
228 |
+
|
229 |
+
from .parsing import parse_expr
|
230 |
+
|
231 |
+
from .calculus import (euler_equations, singularities, is_increasing,
|
232 |
+
is_strictly_increasing, is_decreasing, is_strictly_decreasing,
|
233 |
+
is_monotonic, finite_diff_weights, apply_finite_diff,
|
234 |
+
differentiate_finite, periodicity, not_empty_in, AccumBounds,
|
235 |
+
is_convex, stationary_points, minimum, maximum)
|
236 |
+
|
237 |
+
from .algebras import Quaternion
|
238 |
+
|
239 |
+
from .printing import (pager_print, pretty, pretty_print, pprint,
|
240 |
+
pprint_use_unicode, pprint_try_use_unicode, latex, print_latex,
|
241 |
+
multiline_latex, mathml, print_mathml, python, print_python, pycode,
|
242 |
+
ccode, print_ccode, smtlib_code, glsl_code, print_glsl, cxxcode, fcode,
|
243 |
+
print_fcode, rcode, print_rcode, jscode, print_jscode, julia_code,
|
244 |
+
mathematica_code, octave_code, rust_code, print_gtk, preview, srepr,
|
245 |
+
print_tree, StrPrinter, sstr, sstrrepr, TableForm, dotprint,
|
246 |
+
maple_code, print_maple_code)
|
247 |
+
|
248 |
+
test = lazy_function('sympy.testing.runtests_pytest', 'test')
|
249 |
+
doctest = lazy_function('sympy.testing.runtests', 'doctest')
|
250 |
+
|
251 |
+
# This module causes conflicts with other modules:
|
252 |
+
# from .stats import *
|
253 |
+
# Adds about .04-.05 seconds of import time
|
254 |
+
# from combinatorics import *
|
255 |
+
# This module is slow to import:
|
256 |
+
#from physics import units
|
257 |
+
from .plotting import plot, textplot, plot_backends, plot_implicit, plot_parametric
|
258 |
+
from .interactive import init_session, init_printing, interactive_traversal
|
259 |
+
|
260 |
+
evalf._create_evalf_table()
|
261 |
+
|
262 |
+
__all__ = [
|
263 |
+
'__version__',
|
264 |
+
|
265 |
+
# sympy.core
|
266 |
+
'sympify', 'SympifyError', 'cacheit', 'Basic', 'Atom',
|
267 |
+
'preorder_traversal', 'S', 'Expr', 'AtomicExpr', 'UnevaluatedExpr',
|
268 |
+
'Symbol', 'Wild', 'Dummy', 'symbols', 'var', 'Number', 'Float',
|
269 |
+
'Rational', 'Integer', 'NumberSymbol', 'RealNumber', 'igcd', 'ilcm',
|
270 |
+
'seterr', 'E', 'I', 'nan', 'oo', 'pi', 'zoo', 'AlgebraicNumber', 'comp',
|
271 |
+
'mod_inverse', 'Pow', 'integer_nthroot', 'integer_log', 'trailing', 'Mul', 'prod',
|
272 |
+
'Add', 'Mod', 'Rel', 'Eq', 'Ne', 'Lt', 'Le', 'Gt', 'Ge', 'Equality',
|
273 |
+
'GreaterThan', 'LessThan', 'Unequality', 'StrictGreaterThan',
|
274 |
+
'StrictLessThan', 'vectorize', 'Lambda', 'WildFunction', 'Derivative',
|
275 |
+
'diff', 'FunctionClass', 'Function', 'Subs', 'expand', 'PoleError',
|
276 |
+
'count_ops', 'expand_mul', 'expand_log', 'expand_func', 'expand_trig',
|
277 |
+
'expand_complex', 'expand_multinomial', 'nfloat', 'expand_power_base',
|
278 |
+
'expand_power_exp', 'arity', 'PrecisionExhausted', 'N', 'evalf', 'Tuple',
|
279 |
+
'Dict', 'gcd_terms', 'factor_terms', 'factor_nc', 'evaluate', 'Catalan',
|
280 |
+
'EulerGamma', 'GoldenRatio', 'TribonacciConstant', 'bottom_up', 'use',
|
281 |
+
'postorder_traversal', 'default_sort_key', 'ordered', 'num_digits',
|
282 |
+
|
283 |
+
# sympy.logic
|
284 |
+
'to_cnf', 'to_dnf', 'to_nnf', 'And', 'Or', 'Not', 'Xor', 'Nand', 'Nor',
|
285 |
+
'Implies', 'Equivalent', 'ITE', 'POSform', 'SOPform', 'simplify_logic',
|
286 |
+
'bool_map', 'true', 'false', 'satisfiable',
|
287 |
+
|
288 |
+
# sympy.assumptions
|
289 |
+
'AppliedPredicate', 'Predicate', 'AssumptionsContext', 'assuming', 'Q',
|
290 |
+
'ask', 'register_handler', 'remove_handler', 'refine',
|
291 |
+
|
292 |
+
# sympy.polys
|
293 |
+
'Poly', 'PurePoly', 'poly_from_expr', 'parallel_poly_from_expr', 'degree',
|
294 |
+
'total_degree', 'degree_list', 'LC', 'LM', 'LT', 'pdiv', 'prem', 'pquo',
|
295 |
+
'pexquo', 'div', 'rem', 'quo', 'exquo', 'half_gcdex', 'gcdex', 'invert',
|
296 |
+
'subresultants', 'resultant', 'discriminant', 'cofactors', 'gcd_list',
|
297 |
+
'gcd', 'lcm_list', 'lcm', 'terms_gcd', 'trunc', 'monic', 'content',
|
298 |
+
'primitive', 'compose', 'decompose', 'sturm', 'gff_list', 'gff',
|
299 |
+
'sqf_norm', 'sqf_part', 'sqf_list', 'sqf', 'factor_list', 'factor',
|
300 |
+
'intervals', 'refine_root', 'count_roots', 'all_roots', 'real_roots',
|
301 |
+
'nroots', 'ground_roots', 'nth_power_roots_poly', 'cancel', 'reduced',
|
302 |
+
'groebner', 'is_zero_dimensional', 'GroebnerBasis', 'poly', 'symmetrize',
|
303 |
+
'horner', 'interpolate', 'rational_interpolate', 'viete', 'together',
|
304 |
+
'BasePolynomialError', 'ExactQuotientFailed', 'PolynomialDivisionFailed',
|
305 |
+
'OperationNotSupported', 'HeuristicGCDFailed', 'HomomorphismFailed',
|
306 |
+
'IsomorphismFailed', 'ExtraneousFactors', 'EvaluationFailed',
|
307 |
+
'RefinementFailed', 'CoercionFailed', 'NotInvertible', 'NotReversible',
|
308 |
+
'NotAlgebraic', 'DomainError', 'PolynomialError', 'UnificationFailed',
|
309 |
+
'GeneratorsError', 'GeneratorsNeeded', 'ComputationFailed',
|
310 |
+
'UnivariatePolynomialError', 'MultivariatePolynomialError',
|
311 |
+
'PolificationFailed', 'OptionError', 'FlagError', 'minpoly',
|
312 |
+
'minimal_polynomial', 'primitive_element', 'field_isomorphism',
|
313 |
+
'to_number_field', 'isolate', 'round_two', 'prime_decomp',
|
314 |
+
'prime_valuation', 'galois_group', 'itermonomials', 'Monomial', 'lex', 'grlex',
|
315 |
+
'grevlex', 'ilex', 'igrlex', 'igrevlex', 'CRootOf', 'rootof', 'RootOf',
|
316 |
+
'ComplexRootOf', 'RootSum', 'roots', 'Domain', 'FiniteField',
|
317 |
+
'IntegerRing', 'RationalField', 'RealField', 'ComplexField',
|
318 |
+
'PythonFiniteField', 'GMPYFiniteField', 'PythonIntegerRing',
|
319 |
+
'GMPYIntegerRing', 'PythonRational', 'GMPYRationalField',
|
320 |
+
'AlgebraicField', 'PolynomialRing', 'FractionField', 'ExpressionDomain',
|
321 |
+
'FF_python', 'FF_gmpy', 'ZZ_python', 'ZZ_gmpy', 'QQ_python', 'QQ_gmpy',
|
322 |
+
'GF', 'FF', 'ZZ', 'QQ', 'ZZ_I', 'QQ_I', 'RR', 'CC', 'EX', 'EXRAW',
|
323 |
+
'construct_domain', 'swinnerton_dyer_poly', 'cyclotomic_poly',
|
324 |
+
'symmetric_poly', 'random_poly', 'interpolating_poly', 'jacobi_poly',
|
325 |
+
'chebyshevt_poly', 'chebyshevu_poly', 'hermite_poly', 'hermite_prob_poly',
|
326 |
+
'legendre_poly', 'laguerre_poly', 'apart', 'apart_list', 'assemble_partfrac_list',
|
327 |
+
'Options', 'ring', 'xring', 'vring', 'sring', 'field', 'xfield', 'vfield',
|
328 |
+
'sfield',
|
329 |
+
|
330 |
+
# sympy.series
|
331 |
+
'Order', 'O', 'limit', 'Limit', 'gruntz', 'series', 'approximants',
|
332 |
+
'residue', 'EmptySequence', 'SeqPer', 'SeqFormula', 'sequence', 'SeqAdd',
|
333 |
+
'SeqMul', 'fourier_series', 'fps', 'difference_delta', 'limit_seq',
|
334 |
+
|
335 |
+
# sympy.functions
|
336 |
+
'factorial', 'factorial2', 'rf', 'ff', 'binomial', 'RisingFactorial',
|
337 |
+
'FallingFactorial', 'subfactorial', 'carmichael', 'fibonacci', 'lucas',
|
338 |
+
'motzkin', 'tribonacci', 'harmonic', 'bernoulli', 'bell', 'euler', 'catalan',
|
339 |
+
'genocchi', 'andre', 'partition', 'divisor_sigma', 'legendre_symbol', 'jacobi_symbol',
|
340 |
+
'kronecker_symbol', 'mobius', 'primenu', 'primeomega', 'totient', 'primepi',
|
341 |
+
'reduced_totient', 'sqrt', 'root', 'Min', 'Max', 'Id', 'real_root',
|
342 |
+
'Rem', 'cbrt', 're', 'im', 'sign', 'Abs', 'conjugate', 'arg', 'polar_lift',
|
343 |
+
'periodic_argument', 'unbranched_argument', 'principal_branch',
|
344 |
+
'transpose', 'adjoint', 'polarify', 'unpolarify', 'sin', 'cos', 'tan',
|
345 |
+
'sec', 'csc', 'cot', 'sinc', 'asin', 'acos', 'atan', 'asec', 'acsc',
|
346 |
+
'acot', 'atan2', 'exp_polar', 'exp', 'ln', 'log', 'LambertW', 'sinh',
|
347 |
+
'cosh', 'tanh', 'coth', 'sech', 'csch', 'asinh', 'acosh', 'atanh',
|
348 |
+
'acoth', 'asech', 'acsch', 'floor', 'ceiling', 'frac', 'Piecewise',
|
349 |
+
'piecewise_fold', 'piecewise_exclusive', 'erf', 'erfc', 'erfi', 'erf2',
|
350 |
+
'erfinv', 'erfcinv', 'erf2inv', 'Ei', 'expint', 'E1', 'li', 'Li', 'Si',
|
351 |
+
'Ci', 'Shi', 'Chi', 'fresnels', 'fresnelc', 'gamma', 'lowergamma',
|
352 |
+
'uppergamma', 'polygamma', 'loggamma', 'digamma', 'trigamma', 'multigamma',
|
353 |
+
'dirichlet_eta', 'zeta', 'lerchphi', 'polylog', 'stieltjes', 'Eijk', 'LeviCivita',
|
354 |
+
'KroneckerDelta', 'SingularityFunction', 'DiracDelta', 'Heaviside',
|
355 |
+
'bspline_basis', 'bspline_basis_set', 'interpolating_spline', 'besselj',
|
356 |
+
'bessely', 'besseli', 'besselk', 'hankel1', 'hankel2', 'jn', 'yn',
|
357 |
+
'jn_zeros', 'hn1', 'hn2', 'airyai', 'airybi', 'airyaiprime',
|
358 |
+
'airybiprime', 'marcumq', 'hyper', 'meijerg', 'appellf1', 'legendre',
|
359 |
+
'assoc_legendre', 'hermite', 'hermite_prob', 'chebyshevt', 'chebyshevu',
|
360 |
+
'chebyshevu_root', 'chebyshevt_root', 'laguerre', 'assoc_laguerre',
|
361 |
+
'gegenbauer', 'jacobi', 'jacobi_normalized', 'Ynm', 'Ynm_c', 'Znm',
|
362 |
+
'elliptic_k', 'elliptic_f', 'elliptic_e', 'elliptic_pi', 'beta',
|
363 |
+
'mathieus', 'mathieuc', 'mathieusprime', 'mathieucprime', 'riemann_xi','betainc',
|
364 |
+
'betainc_regularized',
|
365 |
+
|
366 |
+
# sympy.ntheory
|
367 |
+
'nextprime', 'prevprime', 'prime', 'primerange', 'randprime',
|
368 |
+
'Sieve', 'sieve', 'primorial', 'cycle_length', 'composite', 'compositepi',
|
369 |
+
'isprime', 'divisors', 'proper_divisors', 'factorint', 'multiplicity',
|
370 |
+
'perfect_power', 'pollard_pm1', 'pollard_rho', 'primefactors',
|
371 |
+
'divisor_count', 'proper_divisor_count',
|
372 |
+
'factorrat',
|
373 |
+
'mersenne_prime_exponent', 'is_perfect', 'is_mersenne_prime',
|
374 |
+
'is_abundant', 'is_deficient', 'is_amicable', 'is_carmichael', 'abundance',
|
375 |
+
'npartitions',
|
376 |
+
'is_primitive_root', 'is_quad_residue',
|
377 |
+
'n_order', 'sqrt_mod', 'quadratic_residues',
|
378 |
+
'primitive_root', 'nthroot_mod', 'is_nthpow_residue', 'sqrt_mod_iter',
|
379 |
+
'discrete_log', 'quadratic_congruence', 'binomial_coefficients',
|
380 |
+
'binomial_coefficients_list', 'multinomial_coefficients',
|
381 |
+
'continued_fraction_periodic', 'continued_fraction_iterator',
|
382 |
+
'continued_fraction_reduce', 'continued_fraction_convergents',
|
383 |
+
'continued_fraction', 'egyptian_fraction',
|
384 |
+
|
385 |
+
# sympy.concrete
|
386 |
+
'product', 'Product', 'summation', 'Sum',
|
387 |
+
|
388 |
+
# sympy.discrete
|
389 |
+
'fft', 'ifft', 'ntt', 'intt', 'fwht', 'ifwht', 'mobius_transform',
|
390 |
+
'inverse_mobius_transform', 'convolution', 'covering_product',
|
391 |
+
'intersecting_product',
|
392 |
+
|
393 |
+
# sympy.simplify
|
394 |
+
'simplify', 'hypersimp', 'hypersimilar', 'logcombine', 'separatevars',
|
395 |
+
'posify', 'besselsimp', 'kroneckersimp', 'signsimp',
|
396 |
+
'nsimplify', 'FU', 'fu', 'sqrtdenest', 'cse', 'epath', 'EPath',
|
397 |
+
'hyperexpand', 'collect', 'rcollect', 'radsimp', 'collect_const',
|
398 |
+
'fraction', 'numer', 'denom', 'trigsimp', 'exptrigsimp', 'powsimp',
|
399 |
+
'powdenest', 'combsimp', 'gammasimp', 'ratsimp', 'ratsimpmodprime',
|
400 |
+
|
401 |
+
# sympy.sets
|
402 |
+
'Set', 'Interval', 'Union', 'EmptySet', 'FiniteSet', 'ProductSet',
|
403 |
+
'Intersection', 'imageset', 'DisjointUnion', 'Complement', 'SymmetricDifference',
|
404 |
+
'ImageSet', 'Range', 'ComplexRegion', 'Reals', 'Contains', 'ConditionSet',
|
405 |
+
'Ordinal', 'OmegaPower', 'ord0', 'PowerSet', 'Naturals',
|
406 |
+
'Naturals0', 'UniversalSet', 'Integers', 'Rationals', 'Complexes',
|
407 |
+
|
408 |
+
# sympy.solvers
|
409 |
+
'solve', 'solve_linear_system', 'solve_linear_system_LU',
|
410 |
+
'solve_undetermined_coeffs', 'nsolve', 'solve_linear', 'checksol',
|
411 |
+
'det_quick', 'inv_quick', 'check_assumptions', 'failing_assumptions',
|
412 |
+
'diophantine', 'rsolve', 'rsolve_poly', 'rsolve_ratio', 'rsolve_hyper',
|
413 |
+
'checkodesol', 'classify_ode', 'dsolve', 'homogeneous_order',
|
414 |
+
'solve_poly_system', 'solve_triangulated', 'pde_separate',
|
415 |
+
'pde_separate_add', 'pde_separate_mul', 'pdsolve', 'classify_pde',
|
416 |
+
'checkpdesol', 'ode_order', 'reduce_inequalities',
|
417 |
+
'reduce_abs_inequality', 'reduce_abs_inequalities',
|
418 |
+
'solve_poly_inequality', 'solve_rational_inequalities',
|
419 |
+
'solve_univariate_inequality', 'decompogen', 'solveset', 'linsolve',
|
420 |
+
'linear_eq_to_matrix', 'nonlinsolve', 'substitution',
|
421 |
+
|
422 |
+
# sympy.matrices
|
423 |
+
'ShapeError', 'NonSquareMatrixError', 'GramSchmidt', 'casoratian', 'diag',
|
424 |
+
'eye', 'hessian', 'jordan_cell', 'list2numpy', 'matrix2numpy',
|
425 |
+
'matrix_multiply_elementwise', 'ones', 'randMatrix', 'rot_axis1',
|
426 |
+
'rot_axis2', 'rot_axis3', 'symarray', 'wronskian', 'zeros',
|
427 |
+
'MutableDenseMatrix', 'DeferredVector', 'MatrixBase', 'Matrix',
|
428 |
+
'MutableMatrix', 'MutableSparseMatrix', 'banded', 'ImmutableDenseMatrix',
|
429 |
+
'ImmutableSparseMatrix', 'ImmutableMatrix', 'SparseMatrix', 'MatrixSlice',
|
430 |
+
'BlockDiagMatrix', 'BlockMatrix', 'FunctionMatrix', 'Identity', 'Inverse',
|
431 |
+
'MatAdd', 'MatMul', 'MatPow', 'MatrixExpr', 'MatrixSymbol', 'Trace',
|
432 |
+
'Transpose', 'ZeroMatrix', 'OneMatrix', 'blockcut', 'block_collapse',
|
433 |
+
'matrix_symbols', 'Adjoint', 'hadamard_product', 'HadamardProduct',
|
434 |
+
'HadamardPower', 'Determinant', 'det', 'diagonalize_vector', 'DiagMatrix',
|
435 |
+
'DiagonalMatrix', 'DiagonalOf', 'trace', 'DotProduct',
|
436 |
+
'kronecker_product', 'KroneckerProduct', 'PermutationMatrix',
|
437 |
+
'MatrixPermute', 'Permanent', 'per', 'rot_ccw_axis1', 'rot_ccw_axis2',
|
438 |
+
'rot_ccw_axis3', 'rot_givens',
|
439 |
+
|
440 |
+
# sympy.geometry
|
441 |
+
'Point', 'Point2D', 'Point3D', 'Line', 'Ray', 'Segment', 'Line2D',
|
442 |
+
'Segment2D', 'Ray2D', 'Line3D', 'Segment3D', 'Ray3D', 'Plane', 'Ellipse',
|
443 |
+
'Circle', 'Polygon', 'RegularPolygon', 'Triangle', 'rad', 'deg',
|
444 |
+
'are_similar', 'centroid', 'convex_hull', 'idiff', 'intersection',
|
445 |
+
'closest_points', 'farthest_points', 'GeometryError', 'Curve', 'Parabola',
|
446 |
+
|
447 |
+
# sympy.utilities
|
448 |
+
'flatten', 'group', 'take', 'subsets', 'variations', 'numbered_symbols',
|
449 |
+
'cartes', 'capture', 'dict_merge', 'prefixes', 'postfixes', 'sift',
|
450 |
+
'topological_sort', 'unflatten', 'has_dups', 'has_variety', 'reshape',
|
451 |
+
'rotations', 'filldedent', 'lambdify', 'threaded', 'xthreaded',
|
452 |
+
'public', 'memoize_property', 'timed',
|
453 |
+
|
454 |
+
# sympy.integrals
|
455 |
+
'integrate', 'Integral', 'line_integrate', 'mellin_transform',
|
456 |
+
'inverse_mellin_transform', 'MellinTransform', 'InverseMellinTransform',
|
457 |
+
'laplace_transform', 'inverse_laplace_transform', 'LaplaceTransform',
|
458 |
+
'laplace_correspondence', 'laplace_initial_conds',
|
459 |
+
'InverseLaplaceTransform', 'fourier_transform',
|
460 |
+
'inverse_fourier_transform', 'FourierTransform',
|
461 |
+
'InverseFourierTransform', 'sine_transform', 'inverse_sine_transform',
|
462 |
+
'SineTransform', 'InverseSineTransform', 'cosine_transform',
|
463 |
+
'inverse_cosine_transform', 'CosineTransform', 'InverseCosineTransform',
|
464 |
+
'hankel_transform', 'inverse_hankel_transform', 'HankelTransform',
|
465 |
+
'InverseHankelTransform', 'singularityintegrate',
|
466 |
+
|
467 |
+
# sympy.tensor
|
468 |
+
'IndexedBase', 'Idx', 'Indexed', 'get_contraction_structure',
|
469 |
+
'get_indices', 'shape', 'MutableDenseNDimArray', 'ImmutableDenseNDimArray',
|
470 |
+
'MutableSparseNDimArray', 'ImmutableSparseNDimArray', 'NDimArray',
|
471 |
+
'tensorproduct', 'tensorcontraction', 'tensordiagonal', 'derive_by_array',
|
472 |
+
'permutedims', 'Array', 'DenseNDimArray', 'SparseNDimArray',
|
473 |
+
|
474 |
+
# sympy.parsing
|
475 |
+
'parse_expr',
|
476 |
+
|
477 |
+
# sympy.calculus
|
478 |
+
'euler_equations', 'singularities', 'is_increasing',
|
479 |
+
'is_strictly_increasing', 'is_decreasing', 'is_strictly_decreasing',
|
480 |
+
'is_monotonic', 'finite_diff_weights', 'apply_finite_diff',
|
481 |
+
'differentiate_finite', 'periodicity', 'not_empty_in',
|
482 |
+
'AccumBounds', 'is_convex', 'stationary_points', 'minimum', 'maximum',
|
483 |
+
|
484 |
+
# sympy.algebras
|
485 |
+
'Quaternion',
|
486 |
+
|
487 |
+
# sympy.printing
|
488 |
+
'pager_print', 'pretty', 'pretty_print', 'pprint', 'pprint_use_unicode',
|
489 |
+
'pprint_try_use_unicode', 'latex', 'print_latex', 'multiline_latex',
|
490 |
+
'mathml', 'print_mathml', 'python', 'print_python', 'pycode', 'ccode',
|
491 |
+
'print_ccode', 'smtlib_code', 'glsl_code', 'print_glsl', 'cxxcode', 'fcode',
|
492 |
+
'print_fcode', 'rcode', 'print_rcode', 'jscode', 'print_jscode',
|
493 |
+
'julia_code', 'mathematica_code', 'octave_code', 'rust_code', 'print_gtk',
|
494 |
+
'preview', 'srepr', 'print_tree', 'StrPrinter', 'sstr', 'sstrrepr',
|
495 |
+
'TableForm', 'dotprint', 'maple_code', 'print_maple_code',
|
496 |
+
|
497 |
+
# sympy.plotting
|
498 |
+
'plot', 'textplot', 'plot_backends', 'plot_implicit', 'plot_parametric',
|
499 |
+
|
500 |
+
# sympy.interactive
|
501 |
+
'init_session', 'init_printing', 'interactive_traversal',
|
502 |
+
|
503 |
+
# sympy.testing
|
504 |
+
'test', 'doctest',
|
505 |
+
]
|
506 |
+
|
507 |
+
|
508 |
+
#===========================================================================#
|
509 |
+
# #
|
510 |
+
# XXX: The names below were importable before SymPy 1.6 using #
|
511 |
+
# #
|
512 |
+
# from sympy import * #
|
513 |
+
# #
|
514 |
+
# This happened implicitly because there was no __all__ defined in this #
|
515 |
+
# __init__.py file. Not every package is imported. The list matches what #
|
516 |
+
# would have been imported before. It is possible that these packages will #
|
517 |
+
# not be imported by a star-import from sympy in future. #
|
518 |
+
# #
|
519 |
+
#===========================================================================#
|
520 |
+
|
521 |
+
|
522 |
+
__all__.extend((
|
523 |
+
'algebras',
|
524 |
+
'assumptions',
|
525 |
+
'calculus',
|
526 |
+
'concrete',
|
527 |
+
'discrete',
|
528 |
+
'external',
|
529 |
+
'functions',
|
530 |
+
'geometry',
|
531 |
+
'interactive',
|
532 |
+
'multipledispatch',
|
533 |
+
'ntheory',
|
534 |
+
'parsing',
|
535 |
+
'plotting',
|
536 |
+
'polys',
|
537 |
+
'printing',
|
538 |
+
'release',
|
539 |
+
'strategies',
|
540 |
+
'tensor',
|
541 |
+
'utilities',
|
542 |
+
))
|
MLPY/Lib/site-packages/sympy/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (28.3 kB). View file
|
|
MLPY/Lib/site-packages/sympy/__pycache__/abc.cpython-39.pyc
ADDED
Binary file (3.5 kB). View file
|
|
MLPY/Lib/site-packages/sympy/__pycache__/conftest.cpython-39.pyc
ADDED
Binary file (2.9 kB). View file
|
|
MLPY/Lib/site-packages/sympy/__pycache__/galgebra.cpython-39.pyc
ADDED
Binary file (259 Bytes). View file
|
|
MLPY/Lib/site-packages/sympy/__pycache__/release.cpython-39.pyc
ADDED
Binary file (163 Bytes). View file
|
|
MLPY/Lib/site-packages/sympy/__pycache__/this.cpython-39.pyc
ADDED
Binary file (702 Bytes). View file
|
|
MLPY/Lib/site-packages/sympy/abc.py
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
This module exports all latin and greek letters as Symbols, so you can
|
3 |
+
conveniently do
|
4 |
+
|
5 |
+
>>> from sympy.abc import x, y
|
6 |
+
|
7 |
+
instead of the slightly more clunky-looking
|
8 |
+
|
9 |
+
>>> from sympy import symbols
|
10 |
+
>>> x, y = symbols('x y')
|
11 |
+
|
12 |
+
Caveats
|
13 |
+
=======
|
14 |
+
|
15 |
+
1. As of the time of writing this, the names ``O``, ``S``, ``I``, ``N``,
|
16 |
+
``E``, and ``Q`` are colliding with names defined in SymPy. If you import them
|
17 |
+
from both ``sympy.abc`` and ``sympy``, the second import will "win".
|
18 |
+
This is an issue only for * imports, which should only be used for short-lived
|
19 |
+
code such as interactive sessions and throwaway scripts that do not survive
|
20 |
+
until the next SymPy upgrade, where ``sympy`` may contain a different set of
|
21 |
+
names.
|
22 |
+
|
23 |
+
2. This module does not define symbol names on demand, i.e.
|
24 |
+
``from sympy.abc import foo`` will be reported as an error because
|
25 |
+
``sympy.abc`` does not contain the name ``foo``. To get a symbol named ``foo``,
|
26 |
+
you still need to use ``Symbol('foo')`` or ``symbols('foo')``.
|
27 |
+
You can freely mix usage of ``sympy.abc`` and ``Symbol``/``symbols``, though
|
28 |
+
sticking with one and only one way to get the symbols does tend to make the code
|
29 |
+
more readable.
|
30 |
+
|
31 |
+
The module also defines some special names to help detect which names clash
|
32 |
+
with the default SymPy namespace.
|
33 |
+
|
34 |
+
``_clash1`` defines all the single letter variables that clash with
|
35 |
+
SymPy objects; ``_clash2`` defines the multi-letter clashing symbols;
|
36 |
+
and ``_clash`` is the union of both. These can be passed for ``locals``
|
37 |
+
during sympification if one desires Symbols rather than the non-Symbol
|
38 |
+
objects for those names.
|
39 |
+
|
40 |
+
Examples
|
41 |
+
========
|
42 |
+
|
43 |
+
>>> from sympy import S
|
44 |
+
>>> from sympy.abc import _clash1, _clash2, _clash
|
45 |
+
>>> S("Q & C", locals=_clash1)
|
46 |
+
C & Q
|
47 |
+
>>> S('pi(x)', locals=_clash2)
|
48 |
+
pi(x)
|
49 |
+
>>> S('pi(C, Q)', locals=_clash)
|
50 |
+
pi(C, Q)
|
51 |
+
|
52 |
+
"""
|
53 |
+
|
54 |
+
from typing import Any, Dict as tDict
|
55 |
+
|
56 |
+
import string
|
57 |
+
|
58 |
+
from .core import Symbol, symbols
|
59 |
+
from .core.alphabets import greeks
|
60 |
+
from sympy.parsing.sympy_parser import null
|
61 |
+
|
62 |
+
##### Symbol definitions #####
|
63 |
+
|
64 |
+
# Implementation note: The easiest way to avoid typos in the symbols()
|
65 |
+
# parameter is to copy it from the left-hand side of the assignment.
|
66 |
+
|
67 |
+
a, b, c, d, e, f, g, h, i, j = symbols('a, b, c, d, e, f, g, h, i, j')
|
68 |
+
k, l, m, n, o, p, q, r, s, t = symbols('k, l, m, n, o, p, q, r, s, t')
|
69 |
+
u, v, w, x, y, z = symbols('u, v, w, x, y, z')
|
70 |
+
|
71 |
+
A, B, C, D, E, F, G, H, I, J = symbols('A, B, C, D, E, F, G, H, I, J')
|
72 |
+
K, L, M, N, O, P, Q, R, S, T = symbols('K, L, M, N, O, P, Q, R, S, T')
|
73 |
+
U, V, W, X, Y, Z = symbols('U, V, W, X, Y, Z')
|
74 |
+
|
75 |
+
alpha, beta, gamma, delta = symbols('alpha, beta, gamma, delta')
|
76 |
+
epsilon, zeta, eta, theta = symbols('epsilon, zeta, eta, theta')
|
77 |
+
iota, kappa, lamda, mu = symbols('iota, kappa, lamda, mu')
|
78 |
+
nu, xi, omicron, pi = symbols('nu, xi, omicron, pi')
|
79 |
+
rho, sigma, tau, upsilon = symbols('rho, sigma, tau, upsilon')
|
80 |
+
phi, chi, psi, omega = symbols('phi, chi, psi, omega')
|
81 |
+
|
82 |
+
|
83 |
+
##### Clashing-symbols diagnostics #####
|
84 |
+
|
85 |
+
# We want to know which names in SymPy collide with those in here.
|
86 |
+
# This is mostly for diagnosing SymPy's namespace during SymPy development.
|
87 |
+
|
88 |
+
_latin = list(string.ascii_letters)
|
89 |
+
# QOSINE should not be imported as they clash; gamma, pi and zeta clash, too
|
90 |
+
_greek = list(greeks) # make a copy, so we can mutate it
|
91 |
+
# Note: We import lamda since lambda is a reserved keyword in Python
|
92 |
+
_greek.remove("lambda")
|
93 |
+
_greek.append("lamda")
|
94 |
+
|
95 |
+
ns: tDict[str, Any] = {}
|
96 |
+
exec('from sympy import *', ns)
|
97 |
+
_clash1: tDict[str, Any] = {}
|
98 |
+
_clash2: tDict[str, Any] = {}
|
99 |
+
while ns:
|
100 |
+
_k, _ = ns.popitem()
|
101 |
+
if _k in _greek:
|
102 |
+
_clash2[_k] = null
|
103 |
+
_greek.remove(_k)
|
104 |
+
elif _k in _latin:
|
105 |
+
_clash1[_k] = null
|
106 |
+
_latin.remove(_k)
|
107 |
+
_clash = {}
|
108 |
+
_clash.update(_clash1)
|
109 |
+
_clash.update(_clash2)
|
110 |
+
|
111 |
+
del _latin, _greek, Symbol, _k, null
|
MLPY/Lib/site-packages/sympy/algebras/__init__.py
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
from .quaternion import Quaternion
|
2 |
+
|
3 |
+
__all__ = ["Quaternion",]
|
MLPY/Lib/site-packages/sympy/algebras/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (218 Bytes). View file
|
|
MLPY/Lib/site-packages/sympy/algebras/__pycache__/quaternion.cpython-39.pyc
ADDED
Binary file (47.3 kB). View file
|
|
MLPY/Lib/site-packages/sympy/algebras/quaternion.py
ADDED
@@ -0,0 +1,1667 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sympy.core.numbers import Rational
|
2 |
+
from sympy.core.singleton import S
|
3 |
+
from sympy.core.relational import is_eq
|
4 |
+
from sympy.functions.elementary.complexes import (conjugate, im, re, sign)
|
5 |
+
from sympy.functions.elementary.exponential import (exp, log as ln)
|
6 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
7 |
+
from sympy.functions.elementary.trigonometric import (acos, asin, atan2)
|
8 |
+
from sympy.functions.elementary.trigonometric import (cos, sin)
|
9 |
+
from sympy.simplify.trigsimp import trigsimp
|
10 |
+
from sympy.integrals.integrals import integrate
|
11 |
+
from sympy.matrices.dense import MutableDenseMatrix as Matrix
|
12 |
+
from sympy.core.sympify import sympify, _sympify
|
13 |
+
from sympy.core.expr import Expr
|
14 |
+
from sympy.core.logic import fuzzy_not, fuzzy_or
|
15 |
+
from sympy.utilities.misc import as_int
|
16 |
+
|
17 |
+
from mpmath.libmp.libmpf import prec_to_dps
|
18 |
+
|
19 |
+
|
20 |
+
def _check_norm(elements, norm):
|
21 |
+
"""validate if input norm is consistent"""
|
22 |
+
if norm is not None and norm.is_number:
|
23 |
+
if norm.is_positive is False:
|
24 |
+
raise ValueError("Input norm must be positive.")
|
25 |
+
|
26 |
+
numerical = all(i.is_number and i.is_real is True for i in elements)
|
27 |
+
if numerical and is_eq(norm**2, sum(i**2 for i in elements)) is False:
|
28 |
+
raise ValueError("Incompatible value for norm.")
|
29 |
+
|
30 |
+
|
31 |
+
def _is_extrinsic(seq):
|
32 |
+
"""validate seq and return True if seq is lowercase and False if uppercase"""
|
33 |
+
if type(seq) != str:
|
34 |
+
raise ValueError('Expected seq to be a string.')
|
35 |
+
if len(seq) != 3:
|
36 |
+
raise ValueError("Expected 3 axes, got `{}`.".format(seq))
|
37 |
+
|
38 |
+
intrinsic = seq.isupper()
|
39 |
+
extrinsic = seq.islower()
|
40 |
+
if not (intrinsic or extrinsic):
|
41 |
+
raise ValueError("seq must either be fully uppercase (for extrinsic "
|
42 |
+
"rotations), or fully lowercase, for intrinsic "
|
43 |
+
"rotations).")
|
44 |
+
|
45 |
+
i, j, k = seq.lower()
|
46 |
+
if (i == j) or (j == k):
|
47 |
+
raise ValueError("Consecutive axes must be different")
|
48 |
+
|
49 |
+
bad = set(seq) - set('xyzXYZ')
|
50 |
+
if bad:
|
51 |
+
raise ValueError("Expected axes from `seq` to be from "
|
52 |
+
"['x', 'y', 'z'] or ['X', 'Y', 'Z'], "
|
53 |
+
"got {}".format(''.join(bad)))
|
54 |
+
|
55 |
+
return extrinsic
|
56 |
+
|
57 |
+
|
58 |
+
class Quaternion(Expr):
|
59 |
+
"""Provides basic quaternion operations.
|
60 |
+
Quaternion objects can be instantiated as ``Quaternion(a, b, c, d)``
|
61 |
+
as in $q = a + bi + cj + dk$.
|
62 |
+
|
63 |
+
Parameters
|
64 |
+
==========
|
65 |
+
|
66 |
+
norm : None or number
|
67 |
+
Pre-defined quaternion norm. If a value is given, Quaternion.norm
|
68 |
+
returns this pre-defined value instead of calculating the norm
|
69 |
+
|
70 |
+
Examples
|
71 |
+
========
|
72 |
+
|
73 |
+
>>> from sympy import Quaternion
|
74 |
+
>>> q = Quaternion(1, 2, 3, 4)
|
75 |
+
>>> q
|
76 |
+
1 + 2*i + 3*j + 4*k
|
77 |
+
|
78 |
+
Quaternions over complex fields can be defined as:
|
79 |
+
|
80 |
+
>>> from sympy import Quaternion
|
81 |
+
>>> from sympy import symbols, I
|
82 |
+
>>> x = symbols('x')
|
83 |
+
>>> q1 = Quaternion(x, x**3, x, x**2, real_field = False)
|
84 |
+
>>> q2 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False)
|
85 |
+
>>> q1
|
86 |
+
x + x**3*i + x*j + x**2*k
|
87 |
+
>>> q2
|
88 |
+
(3 + 4*I) + (2 + 5*I)*i + 0*j + (7 + 8*I)*k
|
89 |
+
|
90 |
+
Defining symbolic unit quaternions:
|
91 |
+
|
92 |
+
>>> from sympy import Quaternion
|
93 |
+
>>> from sympy.abc import w, x, y, z
|
94 |
+
>>> q = Quaternion(w, x, y, z, norm=1)
|
95 |
+
>>> q
|
96 |
+
w + x*i + y*j + z*k
|
97 |
+
>>> q.norm()
|
98 |
+
1
|
99 |
+
|
100 |
+
References
|
101 |
+
==========
|
102 |
+
|
103 |
+
.. [1] https://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/
|
104 |
+
.. [2] https://en.wikipedia.org/wiki/Quaternion
|
105 |
+
|
106 |
+
"""
|
107 |
+
_op_priority = 11.0
|
108 |
+
|
109 |
+
is_commutative = False
|
110 |
+
|
111 |
+
def __new__(cls, a=0, b=0, c=0, d=0, real_field=True, norm=None):
|
112 |
+
a, b, c, d = map(sympify, (a, b, c, d))
|
113 |
+
|
114 |
+
if any(i.is_commutative is False for i in [a, b, c, d]):
|
115 |
+
raise ValueError("arguments have to be commutative")
|
116 |
+
obj = super().__new__(cls, a, b, c, d)
|
117 |
+
obj._real_field = real_field
|
118 |
+
obj.set_norm(norm)
|
119 |
+
return obj
|
120 |
+
|
121 |
+
def set_norm(self, norm):
|
122 |
+
"""Sets norm of an already instantiated quaternion.
|
123 |
+
|
124 |
+
Parameters
|
125 |
+
==========
|
126 |
+
|
127 |
+
norm : None or number
|
128 |
+
Pre-defined quaternion norm. If a value is given, Quaternion.norm
|
129 |
+
returns this pre-defined value instead of calculating the norm
|
130 |
+
|
131 |
+
Examples
|
132 |
+
========
|
133 |
+
|
134 |
+
>>> from sympy import Quaternion
|
135 |
+
>>> from sympy.abc import a, b, c, d
|
136 |
+
>>> q = Quaternion(a, b, c, d)
|
137 |
+
>>> q.norm()
|
138 |
+
sqrt(a**2 + b**2 + c**2 + d**2)
|
139 |
+
|
140 |
+
Setting the norm:
|
141 |
+
|
142 |
+
>>> q.set_norm(1)
|
143 |
+
>>> q.norm()
|
144 |
+
1
|
145 |
+
|
146 |
+
Removing set norm:
|
147 |
+
|
148 |
+
>>> q.set_norm(None)
|
149 |
+
>>> q.norm()
|
150 |
+
sqrt(a**2 + b**2 + c**2 + d**2)
|
151 |
+
|
152 |
+
"""
|
153 |
+
norm = sympify(norm)
|
154 |
+
_check_norm(self.args, norm)
|
155 |
+
self._norm = norm
|
156 |
+
|
157 |
+
@property
|
158 |
+
def a(self):
|
159 |
+
return self.args[0]
|
160 |
+
|
161 |
+
@property
|
162 |
+
def b(self):
|
163 |
+
return self.args[1]
|
164 |
+
|
165 |
+
@property
|
166 |
+
def c(self):
|
167 |
+
return self.args[2]
|
168 |
+
|
169 |
+
@property
|
170 |
+
def d(self):
|
171 |
+
return self.args[3]
|
172 |
+
|
173 |
+
@property
|
174 |
+
def real_field(self):
|
175 |
+
return self._real_field
|
176 |
+
|
177 |
+
@property
|
178 |
+
def product_matrix_left(self):
|
179 |
+
r"""Returns 4 x 4 Matrix equivalent to a Hamilton product from the
|
180 |
+
left. This can be useful when treating quaternion elements as column
|
181 |
+
vectors. Given a quaternion $q = a + bi + cj + dk$ where a, b, c and d
|
182 |
+
are real numbers, the product matrix from the left is:
|
183 |
+
|
184 |
+
.. math::
|
185 |
+
|
186 |
+
M = \begin{bmatrix} a &-b &-c &-d \\
|
187 |
+
b & a &-d & c \\
|
188 |
+
c & d & a &-b \\
|
189 |
+
d &-c & b & a \end{bmatrix}
|
190 |
+
|
191 |
+
Examples
|
192 |
+
========
|
193 |
+
|
194 |
+
>>> from sympy import Quaternion
|
195 |
+
>>> from sympy.abc import a, b, c, d
|
196 |
+
>>> q1 = Quaternion(1, 0, 0, 1)
|
197 |
+
>>> q2 = Quaternion(a, b, c, d)
|
198 |
+
>>> q1.product_matrix_left
|
199 |
+
Matrix([
|
200 |
+
[1, 0, 0, -1],
|
201 |
+
[0, 1, -1, 0],
|
202 |
+
[0, 1, 1, 0],
|
203 |
+
[1, 0, 0, 1]])
|
204 |
+
|
205 |
+
>>> q1.product_matrix_left * q2.to_Matrix()
|
206 |
+
Matrix([
|
207 |
+
[a - d],
|
208 |
+
[b - c],
|
209 |
+
[b + c],
|
210 |
+
[a + d]])
|
211 |
+
|
212 |
+
This is equivalent to:
|
213 |
+
|
214 |
+
>>> (q1 * q2).to_Matrix()
|
215 |
+
Matrix([
|
216 |
+
[a - d],
|
217 |
+
[b - c],
|
218 |
+
[b + c],
|
219 |
+
[a + d]])
|
220 |
+
"""
|
221 |
+
return Matrix([
|
222 |
+
[self.a, -self.b, -self.c, -self.d],
|
223 |
+
[self.b, self.a, -self.d, self.c],
|
224 |
+
[self.c, self.d, self.a, -self.b],
|
225 |
+
[self.d, -self.c, self.b, self.a]])
|
226 |
+
|
227 |
+
@property
|
228 |
+
def product_matrix_right(self):
|
229 |
+
r"""Returns 4 x 4 Matrix equivalent to a Hamilton product from the
|
230 |
+
right. This can be useful when treating quaternion elements as column
|
231 |
+
vectors. Given a quaternion $q = a + bi + cj + dk$ where a, b, c and d
|
232 |
+
are real numbers, the product matrix from the left is:
|
233 |
+
|
234 |
+
.. math::
|
235 |
+
|
236 |
+
M = \begin{bmatrix} a &-b &-c &-d \\
|
237 |
+
b & a & d &-c \\
|
238 |
+
c &-d & a & b \\
|
239 |
+
d & c &-b & a \end{bmatrix}
|
240 |
+
|
241 |
+
|
242 |
+
Examples
|
243 |
+
========
|
244 |
+
|
245 |
+
>>> from sympy import Quaternion
|
246 |
+
>>> from sympy.abc import a, b, c, d
|
247 |
+
>>> q1 = Quaternion(a, b, c, d)
|
248 |
+
>>> q2 = Quaternion(1, 0, 0, 1)
|
249 |
+
>>> q2.product_matrix_right
|
250 |
+
Matrix([
|
251 |
+
[1, 0, 0, -1],
|
252 |
+
[0, 1, 1, 0],
|
253 |
+
[0, -1, 1, 0],
|
254 |
+
[1, 0, 0, 1]])
|
255 |
+
|
256 |
+
Note the switched arguments: the matrix represents the quaternion on
|
257 |
+
the right, but is still considered as a matrix multiplication from the
|
258 |
+
left.
|
259 |
+
|
260 |
+
>>> q2.product_matrix_right * q1.to_Matrix()
|
261 |
+
Matrix([
|
262 |
+
[ a - d],
|
263 |
+
[ b + c],
|
264 |
+
[-b + c],
|
265 |
+
[ a + d]])
|
266 |
+
|
267 |
+
This is equivalent to:
|
268 |
+
|
269 |
+
>>> (q1 * q2).to_Matrix()
|
270 |
+
Matrix([
|
271 |
+
[ a - d],
|
272 |
+
[ b + c],
|
273 |
+
[-b + c],
|
274 |
+
[ a + d]])
|
275 |
+
"""
|
276 |
+
return Matrix([
|
277 |
+
[self.a, -self.b, -self.c, -self.d],
|
278 |
+
[self.b, self.a, self.d, -self.c],
|
279 |
+
[self.c, -self.d, self.a, self.b],
|
280 |
+
[self.d, self.c, -self.b, self.a]])
|
281 |
+
|
282 |
+
def to_Matrix(self, vector_only=False):
|
283 |
+
"""Returns elements of quaternion as a column vector.
|
284 |
+
By default, a ``Matrix`` of length 4 is returned, with the real part as the
|
285 |
+
first element.
|
286 |
+
If ``vector_only`` is ``True``, returns only imaginary part as a Matrix of
|
287 |
+
length 3.
|
288 |
+
|
289 |
+
Parameters
|
290 |
+
==========
|
291 |
+
|
292 |
+
vector_only : bool
|
293 |
+
If True, only imaginary part is returned.
|
294 |
+
Default value: False
|
295 |
+
|
296 |
+
Returns
|
297 |
+
=======
|
298 |
+
|
299 |
+
Matrix
|
300 |
+
A column vector constructed by the elements of the quaternion.
|
301 |
+
|
302 |
+
Examples
|
303 |
+
========
|
304 |
+
|
305 |
+
>>> from sympy import Quaternion
|
306 |
+
>>> from sympy.abc import a, b, c, d
|
307 |
+
>>> q = Quaternion(a, b, c, d)
|
308 |
+
>>> q
|
309 |
+
a + b*i + c*j + d*k
|
310 |
+
|
311 |
+
>>> q.to_Matrix()
|
312 |
+
Matrix([
|
313 |
+
[a],
|
314 |
+
[b],
|
315 |
+
[c],
|
316 |
+
[d]])
|
317 |
+
|
318 |
+
|
319 |
+
>>> q.to_Matrix(vector_only=True)
|
320 |
+
Matrix([
|
321 |
+
[b],
|
322 |
+
[c],
|
323 |
+
[d]])
|
324 |
+
|
325 |
+
"""
|
326 |
+
if vector_only:
|
327 |
+
return Matrix(self.args[1:])
|
328 |
+
else:
|
329 |
+
return Matrix(self.args)
|
330 |
+
|
331 |
+
@classmethod
|
332 |
+
def from_Matrix(cls, elements):
|
333 |
+
"""Returns quaternion from elements of a column vector`.
|
334 |
+
If vector_only is True, returns only imaginary part as a Matrix of
|
335 |
+
length 3.
|
336 |
+
|
337 |
+
Parameters
|
338 |
+
==========
|
339 |
+
|
340 |
+
elements : Matrix, list or tuple of length 3 or 4. If length is 3,
|
341 |
+
assume real part is zero.
|
342 |
+
Default value: False
|
343 |
+
|
344 |
+
Returns
|
345 |
+
=======
|
346 |
+
|
347 |
+
Quaternion
|
348 |
+
A quaternion created from the input elements.
|
349 |
+
|
350 |
+
Examples
|
351 |
+
========
|
352 |
+
|
353 |
+
>>> from sympy import Quaternion
|
354 |
+
>>> from sympy.abc import a, b, c, d
|
355 |
+
>>> q = Quaternion.from_Matrix([a, b, c, d])
|
356 |
+
>>> q
|
357 |
+
a + b*i + c*j + d*k
|
358 |
+
|
359 |
+
>>> q = Quaternion.from_Matrix([b, c, d])
|
360 |
+
>>> q
|
361 |
+
0 + b*i + c*j + d*k
|
362 |
+
|
363 |
+
"""
|
364 |
+
length = len(elements)
|
365 |
+
if length != 3 and length != 4:
|
366 |
+
raise ValueError("Input elements must have length 3 or 4, got {} "
|
367 |
+
"elements".format(length))
|
368 |
+
|
369 |
+
if length == 3:
|
370 |
+
return Quaternion(0, *elements)
|
371 |
+
else:
|
372 |
+
return Quaternion(*elements)
|
373 |
+
|
374 |
+
@classmethod
|
375 |
+
def from_euler(cls, angles, seq):
|
376 |
+
"""Returns quaternion equivalent to rotation represented by the Euler
|
377 |
+
angles, in the sequence defined by ``seq``.
|
378 |
+
|
379 |
+
Parameters
|
380 |
+
==========
|
381 |
+
|
382 |
+
angles : list, tuple or Matrix of 3 numbers
|
383 |
+
The Euler angles (in radians).
|
384 |
+
seq : string of length 3
|
385 |
+
Represents the sequence of rotations.
|
386 |
+
For extrinsic rotations, seq must be all lowercase and its elements
|
387 |
+
must be from the set ``{'x', 'y', 'z'}``
|
388 |
+
For intrinsic rotations, seq must be all uppercase and its elements
|
389 |
+
must be from the set ``{'X', 'Y', 'Z'}``
|
390 |
+
|
391 |
+
Returns
|
392 |
+
=======
|
393 |
+
|
394 |
+
Quaternion
|
395 |
+
The normalized rotation quaternion calculated from the Euler angles
|
396 |
+
in the given sequence.
|
397 |
+
|
398 |
+
Examples
|
399 |
+
========
|
400 |
+
|
401 |
+
>>> from sympy import Quaternion
|
402 |
+
>>> from sympy import pi
|
403 |
+
>>> q = Quaternion.from_euler([pi/2, 0, 0], 'xyz')
|
404 |
+
>>> q
|
405 |
+
sqrt(2)/2 + sqrt(2)/2*i + 0*j + 0*k
|
406 |
+
|
407 |
+
>>> q = Quaternion.from_euler([0, pi/2, pi] , 'zyz')
|
408 |
+
>>> q
|
409 |
+
0 + (-sqrt(2)/2)*i + 0*j + sqrt(2)/2*k
|
410 |
+
|
411 |
+
>>> q = Quaternion.from_euler([0, pi/2, pi] , 'ZYZ')
|
412 |
+
>>> q
|
413 |
+
0 + sqrt(2)/2*i + 0*j + sqrt(2)/2*k
|
414 |
+
|
415 |
+
"""
|
416 |
+
|
417 |
+
if len(angles) != 3:
|
418 |
+
raise ValueError("3 angles must be given.")
|
419 |
+
|
420 |
+
extrinsic = _is_extrinsic(seq)
|
421 |
+
i, j, k = seq.lower()
|
422 |
+
|
423 |
+
# get elementary basis vectors
|
424 |
+
ei = [1 if n == i else 0 for n in 'xyz']
|
425 |
+
ej = [1 if n == j else 0 for n in 'xyz']
|
426 |
+
ek = [1 if n == k else 0 for n in 'xyz']
|
427 |
+
|
428 |
+
# calculate distinct quaternions
|
429 |
+
qi = cls.from_axis_angle(ei, angles[0])
|
430 |
+
qj = cls.from_axis_angle(ej, angles[1])
|
431 |
+
qk = cls.from_axis_angle(ek, angles[2])
|
432 |
+
|
433 |
+
if extrinsic:
|
434 |
+
return trigsimp(qk * qj * qi)
|
435 |
+
else:
|
436 |
+
return trigsimp(qi * qj * qk)
|
437 |
+
|
438 |
+
def to_euler(self, seq, angle_addition=True, avoid_square_root=False):
|
439 |
+
r"""Returns Euler angles representing same rotation as the quaternion,
|
440 |
+
in the sequence given by ``seq``. This implements the method described
|
441 |
+
in [1]_.
|
442 |
+
|
443 |
+
For degenerate cases (gymbal lock cases), the third angle is
|
444 |
+
set to zero.
|
445 |
+
|
446 |
+
Parameters
|
447 |
+
==========
|
448 |
+
|
449 |
+
seq : string of length 3
|
450 |
+
Represents the sequence of rotations.
|
451 |
+
For extrinsic rotations, seq must be all lowercase and its elements
|
452 |
+
must be from the set ``{'x', 'y', 'z'}``
|
453 |
+
For intrinsic rotations, seq must be all uppercase and its elements
|
454 |
+
must be from the set ``{'X', 'Y', 'Z'}``
|
455 |
+
|
456 |
+
angle_addition : bool
|
457 |
+
When True, first and third angles are given as an addition and
|
458 |
+
subtraction of two simpler ``atan2`` expressions. When False, the
|
459 |
+
first and third angles are each given by a single more complicated
|
460 |
+
``atan2`` expression. This equivalent expression is given by:
|
461 |
+
|
462 |
+
.. math::
|
463 |
+
|
464 |
+
\operatorname{atan_2} (b,a) \pm \operatorname{atan_2} (d,c) =
|
465 |
+
\operatorname{atan_2} (bc\pm ad, ac\mp bd)
|
466 |
+
|
467 |
+
Default value: True
|
468 |
+
|
469 |
+
avoid_square_root : bool
|
470 |
+
When True, the second angle is calculated with an expression based
|
471 |
+
on ``acos``, which is slightly more complicated but avoids a square
|
472 |
+
root. When False, second angle is calculated with ``atan2``, which
|
473 |
+
is simpler and can be better for numerical reasons (some
|
474 |
+
numerical implementations of ``acos`` have problems near zero).
|
475 |
+
Default value: False
|
476 |
+
|
477 |
+
|
478 |
+
Returns
|
479 |
+
=======
|
480 |
+
|
481 |
+
Tuple
|
482 |
+
The Euler angles calculated from the quaternion
|
483 |
+
|
484 |
+
Examples
|
485 |
+
========
|
486 |
+
|
487 |
+
>>> from sympy import Quaternion
|
488 |
+
>>> from sympy.abc import a, b, c, d
|
489 |
+
>>> euler = Quaternion(a, b, c, d).to_euler('zyz')
|
490 |
+
>>> euler
|
491 |
+
(-atan2(-b, c) + atan2(d, a),
|
492 |
+
2*atan2(sqrt(b**2 + c**2), sqrt(a**2 + d**2)),
|
493 |
+
atan2(-b, c) + atan2(d, a))
|
494 |
+
|
495 |
+
|
496 |
+
References
|
497 |
+
==========
|
498 |
+
|
499 |
+
.. [1] https://doi.org/10.1371/journal.pone.0276302
|
500 |
+
|
501 |
+
"""
|
502 |
+
if self.is_zero_quaternion():
|
503 |
+
raise ValueError('Cannot convert a quaternion with norm 0.')
|
504 |
+
|
505 |
+
angles = [0, 0, 0]
|
506 |
+
|
507 |
+
extrinsic = _is_extrinsic(seq)
|
508 |
+
i, j, k = seq.lower()
|
509 |
+
|
510 |
+
# get index corresponding to elementary basis vectors
|
511 |
+
i = 'xyz'.index(i) + 1
|
512 |
+
j = 'xyz'.index(j) + 1
|
513 |
+
k = 'xyz'.index(k) + 1
|
514 |
+
|
515 |
+
if not extrinsic:
|
516 |
+
i, k = k, i
|
517 |
+
|
518 |
+
# check if sequence is symmetric
|
519 |
+
symmetric = i == k
|
520 |
+
if symmetric:
|
521 |
+
k = 6 - i - j
|
522 |
+
|
523 |
+
# parity of the permutation
|
524 |
+
sign = (i - j) * (j - k) * (k - i) // 2
|
525 |
+
|
526 |
+
# permutate elements
|
527 |
+
elements = [self.a, self.b, self.c, self.d]
|
528 |
+
a = elements[0]
|
529 |
+
b = elements[i]
|
530 |
+
c = elements[j]
|
531 |
+
d = elements[k] * sign
|
532 |
+
|
533 |
+
if not symmetric:
|
534 |
+
a, b, c, d = a - c, b + d, c + a, d - b
|
535 |
+
|
536 |
+
if avoid_square_root:
|
537 |
+
if symmetric:
|
538 |
+
n2 = self.norm()**2
|
539 |
+
angles[1] = acos((a * a + b * b - c * c - d * d) / n2)
|
540 |
+
else:
|
541 |
+
n2 = 2 * self.norm()**2
|
542 |
+
angles[1] = asin((c * c + d * d - a * a - b * b) / n2)
|
543 |
+
else:
|
544 |
+
angles[1] = 2 * atan2(sqrt(c * c + d * d), sqrt(a * a + b * b))
|
545 |
+
if not symmetric:
|
546 |
+
angles[1] -= S.Pi / 2
|
547 |
+
|
548 |
+
# Check for singularities in numerical cases
|
549 |
+
case = 0
|
550 |
+
if is_eq(c, S.Zero) and is_eq(d, S.Zero):
|
551 |
+
case = 1
|
552 |
+
if is_eq(a, S.Zero) and is_eq(b, S.Zero):
|
553 |
+
case = 2
|
554 |
+
|
555 |
+
if case == 0:
|
556 |
+
if angle_addition:
|
557 |
+
angles[0] = atan2(b, a) + atan2(d, c)
|
558 |
+
angles[2] = atan2(b, a) - atan2(d, c)
|
559 |
+
else:
|
560 |
+
angles[0] = atan2(b*c + a*d, a*c - b*d)
|
561 |
+
angles[2] = atan2(b*c - a*d, a*c + b*d)
|
562 |
+
|
563 |
+
else: # any degenerate case
|
564 |
+
angles[2 * (not extrinsic)] = S.Zero
|
565 |
+
if case == 1:
|
566 |
+
angles[2 * extrinsic] = 2 * atan2(b, a)
|
567 |
+
else:
|
568 |
+
angles[2 * extrinsic] = 2 * atan2(d, c)
|
569 |
+
angles[2 * extrinsic] *= (-1 if extrinsic else 1)
|
570 |
+
|
571 |
+
# for Tait-Bryan angles
|
572 |
+
if not symmetric:
|
573 |
+
angles[0] *= sign
|
574 |
+
|
575 |
+
if extrinsic:
|
576 |
+
return tuple(angles[::-1])
|
577 |
+
else:
|
578 |
+
return tuple(angles)
|
579 |
+
|
580 |
+
@classmethod
|
581 |
+
def from_axis_angle(cls, vector, angle):
|
582 |
+
"""Returns a rotation quaternion given the axis and the angle of rotation.
|
583 |
+
|
584 |
+
Parameters
|
585 |
+
==========
|
586 |
+
|
587 |
+
vector : tuple of three numbers
|
588 |
+
The vector representation of the given axis.
|
589 |
+
angle : number
|
590 |
+
The angle by which axis is rotated (in radians).
|
591 |
+
|
592 |
+
Returns
|
593 |
+
=======
|
594 |
+
|
595 |
+
Quaternion
|
596 |
+
The normalized rotation quaternion calculated from the given axis and the angle of rotation.
|
597 |
+
|
598 |
+
Examples
|
599 |
+
========
|
600 |
+
|
601 |
+
>>> from sympy import Quaternion
|
602 |
+
>>> from sympy import pi, sqrt
|
603 |
+
>>> q = Quaternion.from_axis_angle((sqrt(3)/3, sqrt(3)/3, sqrt(3)/3), 2*pi/3)
|
604 |
+
>>> q
|
605 |
+
1/2 + 1/2*i + 1/2*j + 1/2*k
|
606 |
+
|
607 |
+
"""
|
608 |
+
(x, y, z) = vector
|
609 |
+
norm = sqrt(x**2 + y**2 + z**2)
|
610 |
+
(x, y, z) = (x / norm, y / norm, z / norm)
|
611 |
+
s = sin(angle * S.Half)
|
612 |
+
a = cos(angle * S.Half)
|
613 |
+
b = x * s
|
614 |
+
c = y * s
|
615 |
+
d = z * s
|
616 |
+
|
617 |
+
# note that this quaternion is already normalized by construction:
|
618 |
+
# c^2 + (s*x)^2 + (s*y)^2 + (s*z)^2 = c^2 + s^2*(x^2 + y^2 + z^2) = c^2 + s^2 * 1 = c^2 + s^2 = 1
|
619 |
+
# so, what we return is a normalized quaternion
|
620 |
+
|
621 |
+
return cls(a, b, c, d)
|
622 |
+
|
623 |
+
@classmethod
|
624 |
+
def from_rotation_matrix(cls, M):
|
625 |
+
"""Returns the equivalent quaternion of a matrix. The quaternion will be normalized
|
626 |
+
only if the matrix is special orthogonal (orthogonal and det(M) = 1).
|
627 |
+
|
628 |
+
Parameters
|
629 |
+
==========
|
630 |
+
|
631 |
+
M : Matrix
|
632 |
+
Input matrix to be converted to equivalent quaternion. M must be special
|
633 |
+
orthogonal (orthogonal and det(M) = 1) for the quaternion to be normalized.
|
634 |
+
|
635 |
+
Returns
|
636 |
+
=======
|
637 |
+
|
638 |
+
Quaternion
|
639 |
+
The quaternion equivalent to given matrix.
|
640 |
+
|
641 |
+
Examples
|
642 |
+
========
|
643 |
+
|
644 |
+
>>> from sympy import Quaternion
|
645 |
+
>>> from sympy import Matrix, symbols, cos, sin, trigsimp
|
646 |
+
>>> x = symbols('x')
|
647 |
+
>>> M = Matrix([[cos(x), -sin(x), 0], [sin(x), cos(x), 0], [0, 0, 1]])
|
648 |
+
>>> q = trigsimp(Quaternion.from_rotation_matrix(M))
|
649 |
+
>>> q
|
650 |
+
sqrt(2)*sqrt(cos(x) + 1)/2 + 0*i + 0*j + sqrt(2 - 2*cos(x))*sign(sin(x))/2*k
|
651 |
+
|
652 |
+
"""
|
653 |
+
|
654 |
+
absQ = M.det()**Rational(1, 3)
|
655 |
+
|
656 |
+
a = sqrt(absQ + M[0, 0] + M[1, 1] + M[2, 2]) / 2
|
657 |
+
b = sqrt(absQ + M[0, 0] - M[1, 1] - M[2, 2]) / 2
|
658 |
+
c = sqrt(absQ - M[0, 0] + M[1, 1] - M[2, 2]) / 2
|
659 |
+
d = sqrt(absQ - M[0, 0] - M[1, 1] + M[2, 2]) / 2
|
660 |
+
|
661 |
+
b = b * sign(M[2, 1] - M[1, 2])
|
662 |
+
c = c * sign(M[0, 2] - M[2, 0])
|
663 |
+
d = d * sign(M[1, 0] - M[0, 1])
|
664 |
+
|
665 |
+
return Quaternion(a, b, c, d)
|
666 |
+
|
667 |
+
def __add__(self, other):
|
668 |
+
return self.add(other)
|
669 |
+
|
670 |
+
def __radd__(self, other):
|
671 |
+
return self.add(other)
|
672 |
+
|
673 |
+
def __sub__(self, other):
|
674 |
+
return self.add(other*-1)
|
675 |
+
|
676 |
+
def __mul__(self, other):
|
677 |
+
return self._generic_mul(self, _sympify(other))
|
678 |
+
|
679 |
+
def __rmul__(self, other):
|
680 |
+
return self._generic_mul(_sympify(other), self)
|
681 |
+
|
682 |
+
def __pow__(self, p):
|
683 |
+
return self.pow(p)
|
684 |
+
|
685 |
+
def __neg__(self):
|
686 |
+
return Quaternion(-self.a, -self.b, -self.c, -self.d)
|
687 |
+
|
688 |
+
def __truediv__(self, other):
|
689 |
+
return self * sympify(other)**-1
|
690 |
+
|
691 |
+
def __rtruediv__(self, other):
|
692 |
+
return sympify(other) * self**-1
|
693 |
+
|
694 |
+
def _eval_Integral(self, *args):
|
695 |
+
return self.integrate(*args)
|
696 |
+
|
697 |
+
def diff(self, *symbols, **kwargs):
|
698 |
+
kwargs.setdefault('evaluate', True)
|
699 |
+
return self.func(*[a.diff(*symbols, **kwargs) for a in self.args])
|
700 |
+
|
701 |
+
def add(self, other):
|
702 |
+
"""Adds quaternions.
|
703 |
+
|
704 |
+
Parameters
|
705 |
+
==========
|
706 |
+
|
707 |
+
other : Quaternion
|
708 |
+
The quaternion to add to current (self) quaternion.
|
709 |
+
|
710 |
+
Returns
|
711 |
+
=======
|
712 |
+
|
713 |
+
Quaternion
|
714 |
+
The resultant quaternion after adding self to other
|
715 |
+
|
716 |
+
Examples
|
717 |
+
========
|
718 |
+
|
719 |
+
>>> from sympy import Quaternion
|
720 |
+
>>> from sympy import symbols
|
721 |
+
>>> q1 = Quaternion(1, 2, 3, 4)
|
722 |
+
>>> q2 = Quaternion(5, 6, 7, 8)
|
723 |
+
>>> q1.add(q2)
|
724 |
+
6 + 8*i + 10*j + 12*k
|
725 |
+
>>> q1 + 5
|
726 |
+
6 + 2*i + 3*j + 4*k
|
727 |
+
>>> x = symbols('x', real = True)
|
728 |
+
>>> q1.add(x)
|
729 |
+
(x + 1) + 2*i + 3*j + 4*k
|
730 |
+
|
731 |
+
Quaternions over complex fields :
|
732 |
+
|
733 |
+
>>> from sympy import Quaternion
|
734 |
+
>>> from sympy import I
|
735 |
+
>>> q3 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False)
|
736 |
+
>>> q3.add(2 + 3*I)
|
737 |
+
(5 + 7*I) + (2 + 5*I)*i + 0*j + (7 + 8*I)*k
|
738 |
+
|
739 |
+
"""
|
740 |
+
q1 = self
|
741 |
+
q2 = sympify(other)
|
742 |
+
|
743 |
+
# If q2 is a number or a SymPy expression instead of a quaternion
|
744 |
+
if not isinstance(q2, Quaternion):
|
745 |
+
if q1.real_field and q2.is_complex:
|
746 |
+
return Quaternion(re(q2) + q1.a, im(q2) + q1.b, q1.c, q1.d)
|
747 |
+
elif q2.is_commutative:
|
748 |
+
return Quaternion(q1.a + q2, q1.b, q1.c, q1.d)
|
749 |
+
else:
|
750 |
+
raise ValueError("Only commutative expressions can be added with a Quaternion.")
|
751 |
+
|
752 |
+
return Quaternion(q1.a + q2.a, q1.b + q2.b, q1.c + q2.c, q1.d
|
753 |
+
+ q2.d)
|
754 |
+
|
755 |
+
def mul(self, other):
|
756 |
+
"""Multiplies quaternions.
|
757 |
+
|
758 |
+
Parameters
|
759 |
+
==========
|
760 |
+
|
761 |
+
other : Quaternion or symbol
|
762 |
+
The quaternion to multiply to current (self) quaternion.
|
763 |
+
|
764 |
+
Returns
|
765 |
+
=======
|
766 |
+
|
767 |
+
Quaternion
|
768 |
+
The resultant quaternion after multiplying self with other
|
769 |
+
|
770 |
+
Examples
|
771 |
+
========
|
772 |
+
|
773 |
+
>>> from sympy import Quaternion
|
774 |
+
>>> from sympy import symbols
|
775 |
+
>>> q1 = Quaternion(1, 2, 3, 4)
|
776 |
+
>>> q2 = Quaternion(5, 6, 7, 8)
|
777 |
+
>>> q1.mul(q2)
|
778 |
+
(-60) + 12*i + 30*j + 24*k
|
779 |
+
>>> q1.mul(2)
|
780 |
+
2 + 4*i + 6*j + 8*k
|
781 |
+
>>> x = symbols('x', real = True)
|
782 |
+
>>> q1.mul(x)
|
783 |
+
x + 2*x*i + 3*x*j + 4*x*k
|
784 |
+
|
785 |
+
Quaternions over complex fields :
|
786 |
+
|
787 |
+
>>> from sympy import Quaternion
|
788 |
+
>>> from sympy import I
|
789 |
+
>>> q3 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False)
|
790 |
+
>>> q3.mul(2 + 3*I)
|
791 |
+
(2 + 3*I)*(3 + 4*I) + (2 + 3*I)*(2 + 5*I)*i + 0*j + (2 + 3*I)*(7 + 8*I)*k
|
792 |
+
|
793 |
+
"""
|
794 |
+
return self._generic_mul(self, _sympify(other))
|
795 |
+
|
796 |
+
@staticmethod
|
797 |
+
def _generic_mul(q1, q2):
|
798 |
+
"""Generic multiplication.
|
799 |
+
|
800 |
+
Parameters
|
801 |
+
==========
|
802 |
+
|
803 |
+
q1 : Quaternion or symbol
|
804 |
+
q2 : Quaternion or symbol
|
805 |
+
|
806 |
+
It is important to note that if neither q1 nor q2 is a Quaternion,
|
807 |
+
this function simply returns q1 * q2.
|
808 |
+
|
809 |
+
Returns
|
810 |
+
=======
|
811 |
+
|
812 |
+
Quaternion
|
813 |
+
The resultant quaternion after multiplying q1 and q2
|
814 |
+
|
815 |
+
Examples
|
816 |
+
========
|
817 |
+
|
818 |
+
>>> from sympy import Quaternion
|
819 |
+
>>> from sympy import Symbol, S
|
820 |
+
>>> q1 = Quaternion(1, 2, 3, 4)
|
821 |
+
>>> q2 = Quaternion(5, 6, 7, 8)
|
822 |
+
>>> Quaternion._generic_mul(q1, q2)
|
823 |
+
(-60) + 12*i + 30*j + 24*k
|
824 |
+
>>> Quaternion._generic_mul(q1, S(2))
|
825 |
+
2 + 4*i + 6*j + 8*k
|
826 |
+
>>> x = Symbol('x', real = True)
|
827 |
+
>>> Quaternion._generic_mul(q1, x)
|
828 |
+
x + 2*x*i + 3*x*j + 4*x*k
|
829 |
+
|
830 |
+
Quaternions over complex fields :
|
831 |
+
|
832 |
+
>>> from sympy import I
|
833 |
+
>>> q3 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False)
|
834 |
+
>>> Quaternion._generic_mul(q3, 2 + 3*I)
|
835 |
+
(2 + 3*I)*(3 + 4*I) + (2 + 3*I)*(2 + 5*I)*i + 0*j + (2 + 3*I)*(7 + 8*I)*k
|
836 |
+
|
837 |
+
"""
|
838 |
+
# None is a Quaternion:
|
839 |
+
if not isinstance(q1, Quaternion) and not isinstance(q2, Quaternion):
|
840 |
+
return q1 * q2
|
841 |
+
|
842 |
+
# If q1 is a number or a SymPy expression instead of a quaternion
|
843 |
+
if not isinstance(q1, Quaternion):
|
844 |
+
if q2.real_field and q1.is_complex:
|
845 |
+
return Quaternion(re(q1), im(q1), 0, 0) * q2
|
846 |
+
elif q1.is_commutative:
|
847 |
+
return Quaternion(q1 * q2.a, q1 * q2.b, q1 * q2.c, q1 * q2.d)
|
848 |
+
else:
|
849 |
+
raise ValueError("Only commutative expressions can be multiplied with a Quaternion.")
|
850 |
+
|
851 |
+
# If q2 is a number or a SymPy expression instead of a quaternion
|
852 |
+
if not isinstance(q2, Quaternion):
|
853 |
+
if q1.real_field and q2.is_complex:
|
854 |
+
return q1 * Quaternion(re(q2), im(q2), 0, 0)
|
855 |
+
elif q2.is_commutative:
|
856 |
+
return Quaternion(q2 * q1.a, q2 * q1.b, q2 * q1.c, q2 * q1.d)
|
857 |
+
else:
|
858 |
+
raise ValueError("Only commutative expressions can be multiplied with a Quaternion.")
|
859 |
+
|
860 |
+
# If any of the quaternions has a fixed norm, pre-compute norm
|
861 |
+
if q1._norm is None and q2._norm is None:
|
862 |
+
norm = None
|
863 |
+
else:
|
864 |
+
norm = q1.norm() * q2.norm()
|
865 |
+
|
866 |
+
return Quaternion(-q1.b*q2.b - q1.c*q2.c - q1.d*q2.d + q1.a*q2.a,
|
867 |
+
q1.b*q2.a + q1.c*q2.d - q1.d*q2.c + q1.a*q2.b,
|
868 |
+
-q1.b*q2.d + q1.c*q2.a + q1.d*q2.b + q1.a*q2.c,
|
869 |
+
q1.b*q2.c - q1.c*q2.b + q1.d*q2.a + q1.a * q2.d,
|
870 |
+
norm=norm)
|
871 |
+
|
872 |
+
def _eval_conjugate(self):
|
873 |
+
"""Returns the conjugate of the quaternion."""
|
874 |
+
q = self
|
875 |
+
return Quaternion(q.a, -q.b, -q.c, -q.d, norm=q._norm)
|
876 |
+
|
877 |
+
def norm(self):
|
878 |
+
"""Returns the norm of the quaternion."""
|
879 |
+
if self._norm is None: # check if norm is pre-defined
|
880 |
+
q = self
|
881 |
+
# trigsimp is used to simplify sin(x)^2 + cos(x)^2 (these terms
|
882 |
+
# arise when from_axis_angle is used).
|
883 |
+
return sqrt(trigsimp(q.a**2 + q.b**2 + q.c**2 + q.d**2))
|
884 |
+
|
885 |
+
return self._norm
|
886 |
+
|
887 |
+
def normalize(self):
|
888 |
+
"""Returns the normalized form of the quaternion."""
|
889 |
+
q = self
|
890 |
+
return q * (1/q.norm())
|
891 |
+
|
892 |
+
def inverse(self):
|
893 |
+
"""Returns the inverse of the quaternion."""
|
894 |
+
q = self
|
895 |
+
if not q.norm():
|
896 |
+
raise ValueError("Cannot compute inverse for a quaternion with zero norm")
|
897 |
+
return conjugate(q) * (1/q.norm()**2)
|
898 |
+
|
899 |
+
def pow(self, p):
|
900 |
+
"""Finds the pth power of the quaternion.
|
901 |
+
|
902 |
+
Parameters
|
903 |
+
==========
|
904 |
+
|
905 |
+
p : int
|
906 |
+
Power to be applied on quaternion.
|
907 |
+
|
908 |
+
Returns
|
909 |
+
=======
|
910 |
+
|
911 |
+
Quaternion
|
912 |
+
Returns the p-th power of the current quaternion.
|
913 |
+
Returns the inverse if p = -1.
|
914 |
+
|
915 |
+
Examples
|
916 |
+
========
|
917 |
+
|
918 |
+
>>> from sympy import Quaternion
|
919 |
+
>>> q = Quaternion(1, 2, 3, 4)
|
920 |
+
>>> q.pow(4)
|
921 |
+
668 + (-224)*i + (-336)*j + (-448)*k
|
922 |
+
|
923 |
+
"""
|
924 |
+
try:
|
925 |
+
q, p = self, as_int(p)
|
926 |
+
except ValueError:
|
927 |
+
return NotImplemented
|
928 |
+
|
929 |
+
if p < 0:
|
930 |
+
q, p = q.inverse(), -p
|
931 |
+
|
932 |
+
if p == 1:
|
933 |
+
return q
|
934 |
+
|
935 |
+
res = Quaternion(1, 0, 0, 0)
|
936 |
+
while p > 0:
|
937 |
+
if p & 1:
|
938 |
+
res *= q
|
939 |
+
q *= q
|
940 |
+
p >>= 1
|
941 |
+
|
942 |
+
return res
|
943 |
+
|
944 |
+
def exp(self):
|
945 |
+
"""Returns the exponential of $q$, given by $e^q$.
|
946 |
+
|
947 |
+
Returns
|
948 |
+
=======
|
949 |
+
|
950 |
+
Quaternion
|
951 |
+
The exponential of the quaternion.
|
952 |
+
|
953 |
+
Examples
|
954 |
+
========
|
955 |
+
|
956 |
+
>>> from sympy import Quaternion
|
957 |
+
>>> q = Quaternion(1, 2, 3, 4)
|
958 |
+
>>> q.exp()
|
959 |
+
E*cos(sqrt(29))
|
960 |
+
+ 2*sqrt(29)*E*sin(sqrt(29))/29*i
|
961 |
+
+ 3*sqrt(29)*E*sin(sqrt(29))/29*j
|
962 |
+
+ 4*sqrt(29)*E*sin(sqrt(29))/29*k
|
963 |
+
|
964 |
+
"""
|
965 |
+
# exp(q) = e^a(cos||v|| + v/||v||*sin||v||)
|
966 |
+
q = self
|
967 |
+
vector_norm = sqrt(q.b**2 + q.c**2 + q.d**2)
|
968 |
+
a = exp(q.a) * cos(vector_norm)
|
969 |
+
b = exp(q.a) * sin(vector_norm) * q.b / vector_norm
|
970 |
+
c = exp(q.a) * sin(vector_norm) * q.c / vector_norm
|
971 |
+
d = exp(q.a) * sin(vector_norm) * q.d / vector_norm
|
972 |
+
|
973 |
+
return Quaternion(a, b, c, d)
|
974 |
+
|
975 |
+
def log(self):
|
976 |
+
r"""Returns the logarithm of the quaternion, given by $\log q$.
|
977 |
+
|
978 |
+
Examples
|
979 |
+
========
|
980 |
+
|
981 |
+
>>> from sympy import Quaternion
|
982 |
+
>>> q = Quaternion(1, 2, 3, 4)
|
983 |
+
>>> q.log()
|
984 |
+
log(sqrt(30))
|
985 |
+
+ 2*sqrt(29)*acos(sqrt(30)/30)/29*i
|
986 |
+
+ 3*sqrt(29)*acos(sqrt(30)/30)/29*j
|
987 |
+
+ 4*sqrt(29)*acos(sqrt(30)/30)/29*k
|
988 |
+
|
989 |
+
"""
|
990 |
+
# log(q) = log||q|| + v/||v||*arccos(a/||q||)
|
991 |
+
q = self
|
992 |
+
vector_norm = sqrt(q.b**2 + q.c**2 + q.d**2)
|
993 |
+
q_norm = q.norm()
|
994 |
+
a = ln(q_norm)
|
995 |
+
b = q.b * acos(q.a / q_norm) / vector_norm
|
996 |
+
c = q.c * acos(q.a / q_norm) / vector_norm
|
997 |
+
d = q.d * acos(q.a / q_norm) / vector_norm
|
998 |
+
|
999 |
+
return Quaternion(a, b, c, d)
|
1000 |
+
|
1001 |
+
def _eval_subs(self, *args):
|
1002 |
+
elements = [i.subs(*args) for i in self.args]
|
1003 |
+
norm = self._norm
|
1004 |
+
if norm is not None:
|
1005 |
+
norm = norm.subs(*args)
|
1006 |
+
_check_norm(elements, norm)
|
1007 |
+
return Quaternion(*elements, norm=norm)
|
1008 |
+
|
1009 |
+
def _eval_evalf(self, prec):
|
1010 |
+
"""Returns the floating point approximations (decimal numbers) of the quaternion.
|
1011 |
+
|
1012 |
+
Returns
|
1013 |
+
=======
|
1014 |
+
|
1015 |
+
Quaternion
|
1016 |
+
Floating point approximations of quaternion(self)
|
1017 |
+
|
1018 |
+
Examples
|
1019 |
+
========
|
1020 |
+
|
1021 |
+
>>> from sympy import Quaternion
|
1022 |
+
>>> from sympy import sqrt
|
1023 |
+
>>> q = Quaternion(1/sqrt(1), 1/sqrt(2), 1/sqrt(3), 1/sqrt(4))
|
1024 |
+
>>> q.evalf()
|
1025 |
+
1.00000000000000
|
1026 |
+
+ 0.707106781186547*i
|
1027 |
+
+ 0.577350269189626*j
|
1028 |
+
+ 0.500000000000000*k
|
1029 |
+
|
1030 |
+
"""
|
1031 |
+
nprec = prec_to_dps(prec)
|
1032 |
+
return Quaternion(*[arg.evalf(n=nprec) for arg in self.args])
|
1033 |
+
|
1034 |
+
def pow_cos_sin(self, p):
|
1035 |
+
"""Computes the pth power in the cos-sin form.
|
1036 |
+
|
1037 |
+
Parameters
|
1038 |
+
==========
|
1039 |
+
|
1040 |
+
p : int
|
1041 |
+
Power to be applied on quaternion.
|
1042 |
+
|
1043 |
+
Returns
|
1044 |
+
=======
|
1045 |
+
|
1046 |
+
Quaternion
|
1047 |
+
The p-th power in the cos-sin form.
|
1048 |
+
|
1049 |
+
Examples
|
1050 |
+
========
|
1051 |
+
|
1052 |
+
>>> from sympy import Quaternion
|
1053 |
+
>>> q = Quaternion(1, 2, 3, 4)
|
1054 |
+
>>> q.pow_cos_sin(4)
|
1055 |
+
900*cos(4*acos(sqrt(30)/30))
|
1056 |
+
+ 1800*sqrt(29)*sin(4*acos(sqrt(30)/30))/29*i
|
1057 |
+
+ 2700*sqrt(29)*sin(4*acos(sqrt(30)/30))/29*j
|
1058 |
+
+ 3600*sqrt(29)*sin(4*acos(sqrt(30)/30))/29*k
|
1059 |
+
|
1060 |
+
"""
|
1061 |
+
# q = ||q||*(cos(a) + u*sin(a))
|
1062 |
+
# q^p = ||q||^p * (cos(p*a) + u*sin(p*a))
|
1063 |
+
|
1064 |
+
q = self
|
1065 |
+
(v, angle) = q.to_axis_angle()
|
1066 |
+
q2 = Quaternion.from_axis_angle(v, p * angle)
|
1067 |
+
return q2 * (q.norm()**p)
|
1068 |
+
|
1069 |
+
def integrate(self, *args):
|
1070 |
+
"""Computes integration of quaternion.
|
1071 |
+
|
1072 |
+
Returns
|
1073 |
+
=======
|
1074 |
+
|
1075 |
+
Quaternion
|
1076 |
+
Integration of the quaternion(self) with the given variable.
|
1077 |
+
|
1078 |
+
Examples
|
1079 |
+
========
|
1080 |
+
|
1081 |
+
Indefinite Integral of quaternion :
|
1082 |
+
|
1083 |
+
>>> from sympy import Quaternion
|
1084 |
+
>>> from sympy.abc import x
|
1085 |
+
>>> q = Quaternion(1, 2, 3, 4)
|
1086 |
+
>>> q.integrate(x)
|
1087 |
+
x + 2*x*i + 3*x*j + 4*x*k
|
1088 |
+
|
1089 |
+
Definite integral of quaternion :
|
1090 |
+
|
1091 |
+
>>> from sympy import Quaternion
|
1092 |
+
>>> from sympy.abc import x
|
1093 |
+
>>> q = Quaternion(1, 2, 3, 4)
|
1094 |
+
>>> q.integrate((x, 1, 5))
|
1095 |
+
4 + 8*i + 12*j + 16*k
|
1096 |
+
|
1097 |
+
"""
|
1098 |
+
# TODO: is this expression correct?
|
1099 |
+
return Quaternion(integrate(self.a, *args), integrate(self.b, *args),
|
1100 |
+
integrate(self.c, *args), integrate(self.d, *args))
|
1101 |
+
|
1102 |
+
@staticmethod
|
1103 |
+
def rotate_point(pin, r):
|
1104 |
+
"""Returns the coordinates of the point pin (a 3 tuple) after rotation.
|
1105 |
+
|
1106 |
+
Parameters
|
1107 |
+
==========
|
1108 |
+
|
1109 |
+
pin : tuple
|
1110 |
+
A 3-element tuple of coordinates of a point which needs to be
|
1111 |
+
rotated.
|
1112 |
+
r : Quaternion or tuple
|
1113 |
+
Axis and angle of rotation.
|
1114 |
+
|
1115 |
+
It's important to note that when r is a tuple, it must be of the form
|
1116 |
+
(axis, angle)
|
1117 |
+
|
1118 |
+
Returns
|
1119 |
+
=======
|
1120 |
+
|
1121 |
+
tuple
|
1122 |
+
The coordinates of the point after rotation.
|
1123 |
+
|
1124 |
+
Examples
|
1125 |
+
========
|
1126 |
+
|
1127 |
+
>>> from sympy import Quaternion
|
1128 |
+
>>> from sympy import symbols, trigsimp, cos, sin
|
1129 |
+
>>> x = symbols('x')
|
1130 |
+
>>> q = Quaternion(cos(x/2), 0, 0, sin(x/2))
|
1131 |
+
>>> trigsimp(Quaternion.rotate_point((1, 1, 1), q))
|
1132 |
+
(sqrt(2)*cos(x + pi/4), sqrt(2)*sin(x + pi/4), 1)
|
1133 |
+
>>> (axis, angle) = q.to_axis_angle()
|
1134 |
+
>>> trigsimp(Quaternion.rotate_point((1, 1, 1), (axis, angle)))
|
1135 |
+
(sqrt(2)*cos(x + pi/4), sqrt(2)*sin(x + pi/4), 1)
|
1136 |
+
|
1137 |
+
"""
|
1138 |
+
if isinstance(r, tuple):
|
1139 |
+
# if r is of the form (vector, angle)
|
1140 |
+
q = Quaternion.from_axis_angle(r[0], r[1])
|
1141 |
+
else:
|
1142 |
+
# if r is a quaternion
|
1143 |
+
q = r.normalize()
|
1144 |
+
pout = q * Quaternion(0, pin[0], pin[1], pin[2]) * conjugate(q)
|
1145 |
+
return (pout.b, pout.c, pout.d)
|
1146 |
+
|
1147 |
+
def to_axis_angle(self):
|
1148 |
+
"""Returns the axis and angle of rotation of a quaternion.
|
1149 |
+
|
1150 |
+
Returns
|
1151 |
+
=======
|
1152 |
+
|
1153 |
+
tuple
|
1154 |
+
Tuple of (axis, angle)
|
1155 |
+
|
1156 |
+
Examples
|
1157 |
+
========
|
1158 |
+
|
1159 |
+
>>> from sympy import Quaternion
|
1160 |
+
>>> q = Quaternion(1, 1, 1, 1)
|
1161 |
+
>>> (axis, angle) = q.to_axis_angle()
|
1162 |
+
>>> axis
|
1163 |
+
(sqrt(3)/3, sqrt(3)/3, sqrt(3)/3)
|
1164 |
+
>>> angle
|
1165 |
+
2*pi/3
|
1166 |
+
|
1167 |
+
"""
|
1168 |
+
q = self
|
1169 |
+
if q.a.is_negative:
|
1170 |
+
q = q * -1
|
1171 |
+
|
1172 |
+
q = q.normalize()
|
1173 |
+
angle = trigsimp(2 * acos(q.a))
|
1174 |
+
|
1175 |
+
# Since quaternion is normalised, q.a is less than 1.
|
1176 |
+
s = sqrt(1 - q.a*q.a)
|
1177 |
+
|
1178 |
+
x = trigsimp(q.b / s)
|
1179 |
+
y = trigsimp(q.c / s)
|
1180 |
+
z = trigsimp(q.d / s)
|
1181 |
+
|
1182 |
+
v = (x, y, z)
|
1183 |
+
t = (v, angle)
|
1184 |
+
|
1185 |
+
return t
|
1186 |
+
|
1187 |
+
def to_rotation_matrix(self, v=None, homogeneous=True):
|
1188 |
+
"""Returns the equivalent rotation transformation matrix of the quaternion
|
1189 |
+
which represents rotation about the origin if ``v`` is not passed.
|
1190 |
+
|
1191 |
+
Parameters
|
1192 |
+
==========
|
1193 |
+
|
1194 |
+
v : tuple or None
|
1195 |
+
Default value: None
|
1196 |
+
homogeneous : bool
|
1197 |
+
When True, gives an expression that may be more efficient for
|
1198 |
+
symbolic calculations but less so for direct evaluation. Both
|
1199 |
+
formulas are mathematically equivalent.
|
1200 |
+
Default value: True
|
1201 |
+
|
1202 |
+
Returns
|
1203 |
+
=======
|
1204 |
+
|
1205 |
+
tuple
|
1206 |
+
Returns the equivalent rotation transformation matrix of the quaternion
|
1207 |
+
which represents rotation about the origin if v is not passed.
|
1208 |
+
|
1209 |
+
Examples
|
1210 |
+
========
|
1211 |
+
|
1212 |
+
>>> from sympy import Quaternion
|
1213 |
+
>>> from sympy import symbols, trigsimp, cos, sin
|
1214 |
+
>>> x = symbols('x')
|
1215 |
+
>>> q = Quaternion(cos(x/2), 0, 0, sin(x/2))
|
1216 |
+
>>> trigsimp(q.to_rotation_matrix())
|
1217 |
+
Matrix([
|
1218 |
+
[cos(x), -sin(x), 0],
|
1219 |
+
[sin(x), cos(x), 0],
|
1220 |
+
[ 0, 0, 1]])
|
1221 |
+
|
1222 |
+
Generates a 4x4 transformation matrix (used for rotation about a point
|
1223 |
+
other than the origin) if the point(v) is passed as an argument.
|
1224 |
+
"""
|
1225 |
+
|
1226 |
+
q = self
|
1227 |
+
s = q.norm()**-2
|
1228 |
+
|
1229 |
+
# diagonal elements are different according to parameter normal
|
1230 |
+
if homogeneous:
|
1231 |
+
m00 = s*(q.a**2 + q.b**2 - q.c**2 - q.d**2)
|
1232 |
+
m11 = s*(q.a**2 - q.b**2 + q.c**2 - q.d**2)
|
1233 |
+
m22 = s*(q.a**2 - q.b**2 - q.c**2 + q.d**2)
|
1234 |
+
else:
|
1235 |
+
m00 = 1 - 2*s*(q.c**2 + q.d**2)
|
1236 |
+
m11 = 1 - 2*s*(q.b**2 + q.d**2)
|
1237 |
+
m22 = 1 - 2*s*(q.b**2 + q.c**2)
|
1238 |
+
|
1239 |
+
m01 = 2*s*(q.b*q.c - q.d*q.a)
|
1240 |
+
m02 = 2*s*(q.b*q.d + q.c*q.a)
|
1241 |
+
|
1242 |
+
m10 = 2*s*(q.b*q.c + q.d*q.a)
|
1243 |
+
m12 = 2*s*(q.c*q.d - q.b*q.a)
|
1244 |
+
|
1245 |
+
m20 = 2*s*(q.b*q.d - q.c*q.a)
|
1246 |
+
m21 = 2*s*(q.c*q.d + q.b*q.a)
|
1247 |
+
|
1248 |
+
if not v:
|
1249 |
+
return Matrix([[m00, m01, m02], [m10, m11, m12], [m20, m21, m22]])
|
1250 |
+
|
1251 |
+
else:
|
1252 |
+
(x, y, z) = v
|
1253 |
+
|
1254 |
+
m03 = x - x*m00 - y*m01 - z*m02
|
1255 |
+
m13 = y - x*m10 - y*m11 - z*m12
|
1256 |
+
m23 = z - x*m20 - y*m21 - z*m22
|
1257 |
+
m30 = m31 = m32 = 0
|
1258 |
+
m33 = 1
|
1259 |
+
|
1260 |
+
return Matrix([[m00, m01, m02, m03], [m10, m11, m12, m13],
|
1261 |
+
[m20, m21, m22, m23], [m30, m31, m32, m33]])
|
1262 |
+
|
1263 |
+
def scalar_part(self):
|
1264 |
+
r"""Returns scalar part($\mathbf{S}(q)$) of the quaternion q.
|
1265 |
+
|
1266 |
+
Explanation
|
1267 |
+
===========
|
1268 |
+
|
1269 |
+
Given a quaternion $q = a + bi + cj + dk$, returns $\mathbf{S}(q) = a$.
|
1270 |
+
|
1271 |
+
Examples
|
1272 |
+
========
|
1273 |
+
|
1274 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1275 |
+
>>> q = Quaternion(4, 8, 13, 12)
|
1276 |
+
>>> q.scalar_part()
|
1277 |
+
4
|
1278 |
+
|
1279 |
+
"""
|
1280 |
+
|
1281 |
+
return self.a
|
1282 |
+
|
1283 |
+
def vector_part(self):
|
1284 |
+
r"""
|
1285 |
+
Returns $\mathbf{V}(q)$, the vector part of the quaternion $q$.
|
1286 |
+
|
1287 |
+
Explanation
|
1288 |
+
===========
|
1289 |
+
|
1290 |
+
Given a quaternion $q = a + bi + cj + dk$, returns $\mathbf{V}(q) = bi + cj + dk$.
|
1291 |
+
|
1292 |
+
Examples
|
1293 |
+
========
|
1294 |
+
|
1295 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1296 |
+
>>> q = Quaternion(1, 1, 1, 1)
|
1297 |
+
>>> q.vector_part()
|
1298 |
+
0 + 1*i + 1*j + 1*k
|
1299 |
+
|
1300 |
+
>>> q = Quaternion(4, 8, 13, 12)
|
1301 |
+
>>> q.vector_part()
|
1302 |
+
0 + 8*i + 13*j + 12*k
|
1303 |
+
|
1304 |
+
"""
|
1305 |
+
|
1306 |
+
return Quaternion(0, self.b, self.c, self.d)
|
1307 |
+
|
1308 |
+
def axis(self):
|
1309 |
+
r"""
|
1310 |
+
Returns $\mathbf{Ax}(q)$, the axis of the quaternion $q$.
|
1311 |
+
|
1312 |
+
Explanation
|
1313 |
+
===========
|
1314 |
+
|
1315 |
+
Given a quaternion $q = a + bi + cj + dk$, returns $\mathbf{Ax}(q)$ i.e., the versor of the vector part of that quaternion
|
1316 |
+
equal to $\mathbf{U}[\mathbf{V}(q)]$.
|
1317 |
+
The axis is always an imaginary unit with square equal to $-1 + 0i + 0j + 0k$.
|
1318 |
+
|
1319 |
+
Examples
|
1320 |
+
========
|
1321 |
+
|
1322 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1323 |
+
>>> q = Quaternion(1, 1, 1, 1)
|
1324 |
+
>>> q.axis()
|
1325 |
+
0 + sqrt(3)/3*i + sqrt(3)/3*j + sqrt(3)/3*k
|
1326 |
+
|
1327 |
+
See Also
|
1328 |
+
========
|
1329 |
+
|
1330 |
+
vector_part
|
1331 |
+
|
1332 |
+
"""
|
1333 |
+
axis = self.vector_part().normalize()
|
1334 |
+
|
1335 |
+
return Quaternion(0, axis.b, axis.c, axis.d)
|
1336 |
+
|
1337 |
+
def is_pure(self):
|
1338 |
+
"""
|
1339 |
+
Returns true if the quaternion is pure, false if the quaternion is not pure
|
1340 |
+
or returns none if it is unknown.
|
1341 |
+
|
1342 |
+
Explanation
|
1343 |
+
===========
|
1344 |
+
|
1345 |
+
A pure quaternion (also a vector quaternion) is a quaternion with scalar
|
1346 |
+
part equal to 0.
|
1347 |
+
|
1348 |
+
Examples
|
1349 |
+
========
|
1350 |
+
|
1351 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1352 |
+
>>> q = Quaternion(0, 8, 13, 12)
|
1353 |
+
>>> q.is_pure()
|
1354 |
+
True
|
1355 |
+
|
1356 |
+
See Also
|
1357 |
+
========
|
1358 |
+
scalar_part
|
1359 |
+
|
1360 |
+
"""
|
1361 |
+
|
1362 |
+
return self.a.is_zero
|
1363 |
+
|
1364 |
+
def is_zero_quaternion(self):
|
1365 |
+
"""
|
1366 |
+
Returns true if the quaternion is a zero quaternion or false if it is not a zero quaternion
|
1367 |
+
and None if the value is unknown.
|
1368 |
+
|
1369 |
+
Explanation
|
1370 |
+
===========
|
1371 |
+
|
1372 |
+
A zero quaternion is a quaternion with both scalar part and
|
1373 |
+
vector part equal to 0.
|
1374 |
+
|
1375 |
+
Examples
|
1376 |
+
========
|
1377 |
+
|
1378 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1379 |
+
>>> q = Quaternion(1, 0, 0, 0)
|
1380 |
+
>>> q.is_zero_quaternion()
|
1381 |
+
False
|
1382 |
+
|
1383 |
+
>>> q = Quaternion(0, 0, 0, 0)
|
1384 |
+
>>> q.is_zero_quaternion()
|
1385 |
+
True
|
1386 |
+
|
1387 |
+
See Also
|
1388 |
+
========
|
1389 |
+
scalar_part
|
1390 |
+
vector_part
|
1391 |
+
|
1392 |
+
"""
|
1393 |
+
|
1394 |
+
return self.norm().is_zero
|
1395 |
+
|
1396 |
+
def angle(self):
|
1397 |
+
r"""
|
1398 |
+
Returns the angle of the quaternion measured in the real-axis plane.
|
1399 |
+
|
1400 |
+
Explanation
|
1401 |
+
===========
|
1402 |
+
|
1403 |
+
Given a quaternion $q = a + bi + cj + dk$ where $a$, $b$, $c$ and $d$
|
1404 |
+
are real numbers, returns the angle of the quaternion given by
|
1405 |
+
|
1406 |
+
.. math::
|
1407 |
+
\theta := 2 \operatorname{atan_2}\left(\sqrt{b^2 + c^2 + d^2}, {a}\right)
|
1408 |
+
|
1409 |
+
Examples
|
1410 |
+
========
|
1411 |
+
|
1412 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1413 |
+
>>> q = Quaternion(1, 4, 4, 4)
|
1414 |
+
>>> q.angle()
|
1415 |
+
2*atan(4*sqrt(3))
|
1416 |
+
|
1417 |
+
"""
|
1418 |
+
|
1419 |
+
return 2 * atan2(self.vector_part().norm(), self.scalar_part())
|
1420 |
+
|
1421 |
+
|
1422 |
+
def arc_coplanar(self, other):
|
1423 |
+
"""
|
1424 |
+
Returns True if the transformation arcs represented by the input quaternions happen in the same plane.
|
1425 |
+
|
1426 |
+
Explanation
|
1427 |
+
===========
|
1428 |
+
|
1429 |
+
Two quaternions are said to be coplanar (in this arc sense) when their axes are parallel.
|
1430 |
+
The plane of a quaternion is the one normal to its axis.
|
1431 |
+
|
1432 |
+
Parameters
|
1433 |
+
==========
|
1434 |
+
|
1435 |
+
other : a Quaternion
|
1436 |
+
|
1437 |
+
Returns
|
1438 |
+
=======
|
1439 |
+
|
1440 |
+
True : if the planes of the two quaternions are the same, apart from its orientation/sign.
|
1441 |
+
False : if the planes of the two quaternions are not the same, apart from its orientation/sign.
|
1442 |
+
None : if plane of either of the quaternion is unknown.
|
1443 |
+
|
1444 |
+
Examples
|
1445 |
+
========
|
1446 |
+
|
1447 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1448 |
+
>>> q1 = Quaternion(1, 4, 4, 4)
|
1449 |
+
>>> q2 = Quaternion(3, 8, 8, 8)
|
1450 |
+
>>> Quaternion.arc_coplanar(q1, q2)
|
1451 |
+
True
|
1452 |
+
|
1453 |
+
>>> q1 = Quaternion(2, 8, 13, 12)
|
1454 |
+
>>> Quaternion.arc_coplanar(q1, q2)
|
1455 |
+
False
|
1456 |
+
|
1457 |
+
See Also
|
1458 |
+
========
|
1459 |
+
|
1460 |
+
vector_coplanar
|
1461 |
+
is_pure
|
1462 |
+
|
1463 |
+
"""
|
1464 |
+
if (self.is_zero_quaternion()) or (other.is_zero_quaternion()):
|
1465 |
+
raise ValueError('Neither of the given quaternions can be 0')
|
1466 |
+
|
1467 |
+
return fuzzy_or([(self.axis() - other.axis()).is_zero_quaternion(), (self.axis() + other.axis()).is_zero_quaternion()])
|
1468 |
+
|
1469 |
+
@classmethod
|
1470 |
+
def vector_coplanar(cls, q1, q2, q3):
|
1471 |
+
r"""
|
1472 |
+
Returns True if the axis of the pure quaternions seen as 3D vectors
|
1473 |
+
``q1``, ``q2``, and ``q3`` are coplanar.
|
1474 |
+
|
1475 |
+
Explanation
|
1476 |
+
===========
|
1477 |
+
|
1478 |
+
Three pure quaternions are vector coplanar if the quaternions seen as 3D vectors are coplanar.
|
1479 |
+
|
1480 |
+
Parameters
|
1481 |
+
==========
|
1482 |
+
|
1483 |
+
q1
|
1484 |
+
A pure Quaternion.
|
1485 |
+
q2
|
1486 |
+
A pure Quaternion.
|
1487 |
+
q3
|
1488 |
+
A pure Quaternion.
|
1489 |
+
|
1490 |
+
Returns
|
1491 |
+
=======
|
1492 |
+
|
1493 |
+
True : if the axis of the pure quaternions seen as 3D vectors
|
1494 |
+
q1, q2, and q3 are coplanar.
|
1495 |
+
False : if the axis of the pure quaternions seen as 3D vectors
|
1496 |
+
q1, q2, and q3 are not coplanar.
|
1497 |
+
None : if the axis of the pure quaternions seen as 3D vectors
|
1498 |
+
q1, q2, and q3 are coplanar is unknown.
|
1499 |
+
|
1500 |
+
Examples
|
1501 |
+
========
|
1502 |
+
|
1503 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1504 |
+
>>> q1 = Quaternion(0, 4, 4, 4)
|
1505 |
+
>>> q2 = Quaternion(0, 8, 8, 8)
|
1506 |
+
>>> q3 = Quaternion(0, 24, 24, 24)
|
1507 |
+
>>> Quaternion.vector_coplanar(q1, q2, q3)
|
1508 |
+
True
|
1509 |
+
|
1510 |
+
>>> q1 = Quaternion(0, 8, 16, 8)
|
1511 |
+
>>> q2 = Quaternion(0, 8, 3, 12)
|
1512 |
+
>>> Quaternion.vector_coplanar(q1, q2, q3)
|
1513 |
+
False
|
1514 |
+
|
1515 |
+
See Also
|
1516 |
+
========
|
1517 |
+
|
1518 |
+
axis
|
1519 |
+
is_pure
|
1520 |
+
|
1521 |
+
"""
|
1522 |
+
|
1523 |
+
if fuzzy_not(q1.is_pure()) or fuzzy_not(q2.is_pure()) or fuzzy_not(q3.is_pure()):
|
1524 |
+
raise ValueError('The given quaternions must be pure')
|
1525 |
+
|
1526 |
+
M = Matrix([[q1.b, q1.c, q1.d], [q2.b, q2.c, q2.d], [q3.b, q3.c, q3.d]]).det()
|
1527 |
+
return M.is_zero
|
1528 |
+
|
1529 |
+
def parallel(self, other):
|
1530 |
+
"""
|
1531 |
+
Returns True if the two pure quaternions seen as 3D vectors are parallel.
|
1532 |
+
|
1533 |
+
Explanation
|
1534 |
+
===========
|
1535 |
+
|
1536 |
+
Two pure quaternions are called parallel when their vector product is commutative which
|
1537 |
+
implies that the quaternions seen as 3D vectors have same direction.
|
1538 |
+
|
1539 |
+
Parameters
|
1540 |
+
==========
|
1541 |
+
|
1542 |
+
other : a Quaternion
|
1543 |
+
|
1544 |
+
Returns
|
1545 |
+
=======
|
1546 |
+
|
1547 |
+
True : if the two pure quaternions seen as 3D vectors are parallel.
|
1548 |
+
False : if the two pure quaternions seen as 3D vectors are not parallel.
|
1549 |
+
None : if the two pure quaternions seen as 3D vectors are parallel is unknown.
|
1550 |
+
|
1551 |
+
Examples
|
1552 |
+
========
|
1553 |
+
|
1554 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1555 |
+
>>> q = Quaternion(0, 4, 4, 4)
|
1556 |
+
>>> q1 = Quaternion(0, 8, 8, 8)
|
1557 |
+
>>> q.parallel(q1)
|
1558 |
+
True
|
1559 |
+
|
1560 |
+
>>> q1 = Quaternion(0, 8, 13, 12)
|
1561 |
+
>>> q.parallel(q1)
|
1562 |
+
False
|
1563 |
+
|
1564 |
+
"""
|
1565 |
+
|
1566 |
+
if fuzzy_not(self.is_pure()) or fuzzy_not(other.is_pure()):
|
1567 |
+
raise ValueError('The provided quaternions must be pure')
|
1568 |
+
|
1569 |
+
return (self*other - other*self).is_zero_quaternion()
|
1570 |
+
|
1571 |
+
def orthogonal(self, other):
|
1572 |
+
"""
|
1573 |
+
Returns the orthogonality of two quaternions.
|
1574 |
+
|
1575 |
+
Explanation
|
1576 |
+
===========
|
1577 |
+
|
1578 |
+
Two pure quaternions are called orthogonal when their product is anti-commutative.
|
1579 |
+
|
1580 |
+
Parameters
|
1581 |
+
==========
|
1582 |
+
|
1583 |
+
other : a Quaternion
|
1584 |
+
|
1585 |
+
Returns
|
1586 |
+
=======
|
1587 |
+
|
1588 |
+
True : if the two pure quaternions seen as 3D vectors are orthogonal.
|
1589 |
+
False : if the two pure quaternions seen as 3D vectors are not orthogonal.
|
1590 |
+
None : if the two pure quaternions seen as 3D vectors are orthogonal is unknown.
|
1591 |
+
|
1592 |
+
Examples
|
1593 |
+
========
|
1594 |
+
|
1595 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1596 |
+
>>> q = Quaternion(0, 4, 4, 4)
|
1597 |
+
>>> q1 = Quaternion(0, 8, 8, 8)
|
1598 |
+
>>> q.orthogonal(q1)
|
1599 |
+
False
|
1600 |
+
|
1601 |
+
>>> q1 = Quaternion(0, 2, 2, 0)
|
1602 |
+
>>> q = Quaternion(0, 2, -2, 0)
|
1603 |
+
>>> q.orthogonal(q1)
|
1604 |
+
True
|
1605 |
+
|
1606 |
+
"""
|
1607 |
+
|
1608 |
+
if fuzzy_not(self.is_pure()) or fuzzy_not(other.is_pure()):
|
1609 |
+
raise ValueError('The given quaternions must be pure')
|
1610 |
+
|
1611 |
+
return (self*other + other*self).is_zero_quaternion()
|
1612 |
+
|
1613 |
+
def index_vector(self):
|
1614 |
+
r"""
|
1615 |
+
Returns the index vector of the quaternion.
|
1616 |
+
|
1617 |
+
Explanation
|
1618 |
+
===========
|
1619 |
+
|
1620 |
+
The index vector is given by $\mathbf{T}(q)$, the norm (or magnitude) of
|
1621 |
+
the quaternion $q$, multiplied by $\mathbf{Ax}(q)$, the axis of $q$.
|
1622 |
+
|
1623 |
+
Returns
|
1624 |
+
=======
|
1625 |
+
|
1626 |
+
Quaternion: representing index vector of the provided quaternion.
|
1627 |
+
|
1628 |
+
Examples
|
1629 |
+
========
|
1630 |
+
|
1631 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1632 |
+
>>> q = Quaternion(2, 4, 2, 4)
|
1633 |
+
>>> q.index_vector()
|
1634 |
+
0 + 4*sqrt(10)/3*i + 2*sqrt(10)/3*j + 4*sqrt(10)/3*k
|
1635 |
+
|
1636 |
+
See Also
|
1637 |
+
========
|
1638 |
+
|
1639 |
+
axis
|
1640 |
+
norm
|
1641 |
+
|
1642 |
+
"""
|
1643 |
+
|
1644 |
+
return self.norm() * self.axis()
|
1645 |
+
|
1646 |
+
def mensor(self):
|
1647 |
+
"""
|
1648 |
+
Returns the natural logarithm of the norm(magnitude) of the quaternion.
|
1649 |
+
|
1650 |
+
Examples
|
1651 |
+
========
|
1652 |
+
|
1653 |
+
>>> from sympy.algebras.quaternion import Quaternion
|
1654 |
+
>>> q = Quaternion(2, 4, 2, 4)
|
1655 |
+
>>> q.mensor()
|
1656 |
+
log(2*sqrt(10))
|
1657 |
+
>>> q.norm()
|
1658 |
+
2*sqrt(10)
|
1659 |
+
|
1660 |
+
See Also
|
1661 |
+
========
|
1662 |
+
|
1663 |
+
norm
|
1664 |
+
|
1665 |
+
"""
|
1666 |
+
|
1667 |
+
return ln(self.norm())
|
MLPY/Lib/site-packages/sympy/algebras/tests/__init__.py
ADDED
File without changes
|
MLPY/Lib/site-packages/sympy/algebras/tests/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (157 Bytes). View file
|
|
MLPY/Lib/site-packages/sympy/algebras/tests/__pycache__/test_quaternion.cpython-39.pyc
ADDED
Binary file (16 kB). View file
|
|
MLPY/Lib/site-packages/sympy/algebras/tests/test_quaternion.py
ADDED
@@ -0,0 +1,428 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sympy.testing.pytest import slow
|
2 |
+
from sympy.core.function import diff
|
3 |
+
from sympy.core.function import expand
|
4 |
+
from sympy.core.numbers import (E, I, Rational, pi)
|
5 |
+
from sympy.core.singleton import S
|
6 |
+
from sympy.core.symbol import (Symbol, symbols)
|
7 |
+
from sympy.functions.elementary.complexes import (Abs, conjugate, im, re, sign)
|
8 |
+
from sympy.functions.elementary.exponential import log
|
9 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
10 |
+
from sympy.functions.elementary.trigonometric import (acos, asin, cos, sin, atan2, atan)
|
11 |
+
from sympy.integrals.integrals import integrate
|
12 |
+
from sympy.matrices.dense import Matrix
|
13 |
+
from sympy.simplify import simplify
|
14 |
+
from sympy.simplify.trigsimp import trigsimp
|
15 |
+
from sympy.algebras.quaternion import Quaternion
|
16 |
+
from sympy.testing.pytest import raises
|
17 |
+
import math
|
18 |
+
from itertools import permutations, product
|
19 |
+
|
20 |
+
w, x, y, z = symbols('w:z')
|
21 |
+
phi = symbols('phi')
|
22 |
+
|
23 |
+
def test_quaternion_construction():
|
24 |
+
q = Quaternion(w, x, y, z)
|
25 |
+
assert q + q == Quaternion(2*w, 2*x, 2*y, 2*z)
|
26 |
+
|
27 |
+
q2 = Quaternion.from_axis_angle((sqrt(3)/3, sqrt(3)/3, sqrt(3)/3),
|
28 |
+
pi*Rational(2, 3))
|
29 |
+
assert q2 == Quaternion(S.Half, S.Half,
|
30 |
+
S.Half, S.Half)
|
31 |
+
|
32 |
+
M = Matrix([[cos(phi), -sin(phi), 0], [sin(phi), cos(phi), 0], [0, 0, 1]])
|
33 |
+
q3 = trigsimp(Quaternion.from_rotation_matrix(M))
|
34 |
+
assert q3 == Quaternion(
|
35 |
+
sqrt(2)*sqrt(cos(phi) + 1)/2, 0, 0, sqrt(2 - 2*cos(phi))*sign(sin(phi))/2)
|
36 |
+
|
37 |
+
nc = Symbol('nc', commutative=False)
|
38 |
+
raises(ValueError, lambda: Quaternion(w, x, nc, z))
|
39 |
+
|
40 |
+
|
41 |
+
def test_quaternion_construction_norm():
|
42 |
+
q1 = Quaternion(*symbols('a:d'))
|
43 |
+
|
44 |
+
q2 = Quaternion(w, x, y, z)
|
45 |
+
assert expand((q1*q2).norm()**2 - (q1.norm()**2 * q2.norm()**2)) == 0
|
46 |
+
|
47 |
+
q3 = Quaternion(w, x, y, z, norm=1)
|
48 |
+
assert (q1 * q3).norm() == q1.norm()
|
49 |
+
|
50 |
+
|
51 |
+
def test_issue_25254():
|
52 |
+
# calculating the inverse cached the norm which caused problems
|
53 |
+
# when multiplying
|
54 |
+
p = Quaternion(1, 0, 0, 0)
|
55 |
+
q = Quaternion.from_axis_angle((1, 1, 1), 3 * math.pi/4)
|
56 |
+
qi = q.inverse() # this operation cached the norm
|
57 |
+
test = q * p * qi
|
58 |
+
assert ((test - p).norm() < 1E-10)
|
59 |
+
|
60 |
+
|
61 |
+
def test_to_and_from_Matrix():
|
62 |
+
q = Quaternion(w, x, y, z)
|
63 |
+
q_full = Quaternion.from_Matrix(q.to_Matrix())
|
64 |
+
q_vect = Quaternion.from_Matrix(q.to_Matrix(True))
|
65 |
+
assert (q - q_full).is_zero_quaternion()
|
66 |
+
assert (q.vector_part() - q_vect).is_zero_quaternion()
|
67 |
+
|
68 |
+
|
69 |
+
def test_product_matrices():
|
70 |
+
q1 = Quaternion(w, x, y, z)
|
71 |
+
q2 = Quaternion(*(symbols("a:d")))
|
72 |
+
assert (q1 * q2).to_Matrix() == q1.product_matrix_left * q2.to_Matrix()
|
73 |
+
assert (q1 * q2).to_Matrix() == q2.product_matrix_right * q1.to_Matrix()
|
74 |
+
|
75 |
+
R1 = (q1.product_matrix_left * q1.product_matrix_right.T)[1:, 1:]
|
76 |
+
R2 = simplify(q1.to_rotation_matrix()*q1.norm()**2)
|
77 |
+
assert R1 == R2
|
78 |
+
|
79 |
+
|
80 |
+
def test_quaternion_axis_angle():
|
81 |
+
|
82 |
+
test_data = [ # axis, angle, expected_quaternion
|
83 |
+
((1, 0, 0), 0, (1, 0, 0, 0)),
|
84 |
+
((1, 0, 0), pi/2, (sqrt(2)/2, sqrt(2)/2, 0, 0)),
|
85 |
+
((0, 1, 0), pi/2, (sqrt(2)/2, 0, sqrt(2)/2, 0)),
|
86 |
+
((0, 0, 1), pi/2, (sqrt(2)/2, 0, 0, sqrt(2)/2)),
|
87 |
+
((1, 0, 0), pi, (0, 1, 0, 0)),
|
88 |
+
((0, 1, 0), pi, (0, 0, 1, 0)),
|
89 |
+
((0, 0, 1), pi, (0, 0, 0, 1)),
|
90 |
+
((1, 1, 1), pi, (0, 1/sqrt(3),1/sqrt(3),1/sqrt(3))),
|
91 |
+
((sqrt(3)/3, sqrt(3)/3, sqrt(3)/3), pi*2/3, (S.Half, S.Half, S.Half, S.Half))
|
92 |
+
]
|
93 |
+
|
94 |
+
for axis, angle, expected in test_data:
|
95 |
+
assert Quaternion.from_axis_angle(axis, angle) == Quaternion(*expected)
|
96 |
+
|
97 |
+
|
98 |
+
def test_quaternion_axis_angle_simplification():
|
99 |
+
result = Quaternion.from_axis_angle((1, 2, 3), asin(4))
|
100 |
+
assert result.a == cos(asin(4)/2)
|
101 |
+
assert result.b == sqrt(14)*sin(asin(4)/2)/14
|
102 |
+
assert result.c == sqrt(14)*sin(asin(4)/2)/7
|
103 |
+
assert result.d == 3*sqrt(14)*sin(asin(4)/2)/14
|
104 |
+
|
105 |
+
def test_quaternion_complex_real_addition():
|
106 |
+
a = symbols("a", complex=True)
|
107 |
+
b = symbols("b", real=True)
|
108 |
+
# This symbol is not complex:
|
109 |
+
c = symbols("c", commutative=False)
|
110 |
+
|
111 |
+
q = Quaternion(w, x, y, z)
|
112 |
+
assert a + q == Quaternion(w + re(a), x + im(a), y, z)
|
113 |
+
assert 1 + q == Quaternion(1 + w, x, y, z)
|
114 |
+
assert I + q == Quaternion(w, 1 + x, y, z)
|
115 |
+
assert b + q == Quaternion(w + b, x, y, z)
|
116 |
+
raises(ValueError, lambda: c + q)
|
117 |
+
raises(ValueError, lambda: q * c)
|
118 |
+
raises(ValueError, lambda: c * q)
|
119 |
+
|
120 |
+
assert -q == Quaternion(-w, -x, -y, -z)
|
121 |
+
|
122 |
+
q1 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False)
|
123 |
+
q2 = Quaternion(1, 4, 7, 8)
|
124 |
+
|
125 |
+
assert q1 + (2 + 3*I) == Quaternion(5 + 7*I, 2 + 5*I, 0, 7 + 8*I)
|
126 |
+
assert q2 + (2 + 3*I) == Quaternion(3, 7, 7, 8)
|
127 |
+
assert q1 * (2 + 3*I) == \
|
128 |
+
Quaternion((2 + 3*I)*(3 + 4*I), (2 + 3*I)*(2 + 5*I), 0, (2 + 3*I)*(7 + 8*I))
|
129 |
+
assert q2 * (2 + 3*I) == Quaternion(-10, 11, 38, -5)
|
130 |
+
|
131 |
+
q1 = Quaternion(1, 2, 3, 4)
|
132 |
+
q0 = Quaternion(0, 0, 0, 0)
|
133 |
+
assert q1 + q0 == q1
|
134 |
+
assert q1 - q0 == q1
|
135 |
+
assert q1 - q1 == q0
|
136 |
+
|
137 |
+
|
138 |
+
def test_quaternion_subs():
|
139 |
+
q = Quaternion.from_axis_angle((0, 0, 1), phi)
|
140 |
+
assert q.subs(phi, 0) == Quaternion(1, 0, 0, 0)
|
141 |
+
|
142 |
+
|
143 |
+
def test_quaternion_evalf():
|
144 |
+
assert (Quaternion(sqrt(2), 0, 0, sqrt(3)).evalf() ==
|
145 |
+
Quaternion(sqrt(2).evalf(), 0, 0, sqrt(3).evalf()))
|
146 |
+
assert (Quaternion(1/sqrt(2), 0, 0, 1/sqrt(2)).evalf() ==
|
147 |
+
Quaternion((1/sqrt(2)).evalf(), 0, 0, (1/sqrt(2)).evalf()))
|
148 |
+
|
149 |
+
|
150 |
+
def test_quaternion_functions():
|
151 |
+
q = Quaternion(w, x, y, z)
|
152 |
+
q1 = Quaternion(1, 2, 3, 4)
|
153 |
+
q0 = Quaternion(0, 0, 0, 0)
|
154 |
+
|
155 |
+
assert conjugate(q) == Quaternion(w, -x, -y, -z)
|
156 |
+
assert q.norm() == sqrt(w**2 + x**2 + y**2 + z**2)
|
157 |
+
assert q.normalize() == Quaternion(w, x, y, z) / sqrt(w**2 + x**2 + y**2 + z**2)
|
158 |
+
assert q.inverse() == Quaternion(w, -x, -y, -z) / (w**2 + x**2 + y**2 + z**2)
|
159 |
+
assert q.inverse() == q.pow(-1)
|
160 |
+
raises(ValueError, lambda: q0.inverse())
|
161 |
+
assert q.pow(2) == Quaternion(w**2 - x**2 - y**2 - z**2, 2*w*x, 2*w*y, 2*w*z)
|
162 |
+
assert q**(2) == Quaternion(w**2 - x**2 - y**2 - z**2, 2*w*x, 2*w*y, 2*w*z)
|
163 |
+
assert q1.pow(-2) == Quaternion(
|
164 |
+
Rational(-7, 225), Rational(-1, 225), Rational(-1, 150), Rational(-2, 225))
|
165 |
+
assert q1**(-2) == Quaternion(
|
166 |
+
Rational(-7, 225), Rational(-1, 225), Rational(-1, 150), Rational(-2, 225))
|
167 |
+
assert q1.pow(-0.5) == NotImplemented
|
168 |
+
raises(TypeError, lambda: q1**(-0.5))
|
169 |
+
|
170 |
+
assert q1.exp() == \
|
171 |
+
Quaternion(E * cos(sqrt(29)),
|
172 |
+
2 * sqrt(29) * E * sin(sqrt(29)) / 29,
|
173 |
+
3 * sqrt(29) * E * sin(sqrt(29)) / 29,
|
174 |
+
4 * sqrt(29) * E * sin(sqrt(29)) / 29)
|
175 |
+
assert q1.log() == \
|
176 |
+
Quaternion(log(sqrt(30)),
|
177 |
+
2 * sqrt(29) * acos(sqrt(30)/30) / 29,
|
178 |
+
3 * sqrt(29) * acos(sqrt(30)/30) / 29,
|
179 |
+
4 * sqrt(29) * acos(sqrt(30)/30) / 29)
|
180 |
+
|
181 |
+
assert q1.pow_cos_sin(2) == \
|
182 |
+
Quaternion(30 * cos(2 * acos(sqrt(30)/30)),
|
183 |
+
60 * sqrt(29) * sin(2 * acos(sqrt(30)/30)) / 29,
|
184 |
+
90 * sqrt(29) * sin(2 * acos(sqrt(30)/30)) / 29,
|
185 |
+
120 * sqrt(29) * sin(2 * acos(sqrt(30)/30)) / 29)
|
186 |
+
|
187 |
+
assert diff(Quaternion(x, x, x, x), x) == Quaternion(1, 1, 1, 1)
|
188 |
+
|
189 |
+
assert integrate(Quaternion(x, x, x, x), x) == \
|
190 |
+
Quaternion(x**2 / 2, x**2 / 2, x**2 / 2, x**2 / 2)
|
191 |
+
|
192 |
+
assert Quaternion.rotate_point((1, 1, 1), q1) == (S.One / 5, 1, S(7) / 5)
|
193 |
+
n = Symbol('n')
|
194 |
+
raises(TypeError, lambda: q1**n)
|
195 |
+
n = Symbol('n', integer=True)
|
196 |
+
raises(TypeError, lambda: q1**n)
|
197 |
+
|
198 |
+
assert Quaternion(22, 23, 55, 8).scalar_part() == 22
|
199 |
+
assert Quaternion(w, x, y, z).scalar_part() == w
|
200 |
+
|
201 |
+
assert Quaternion(22, 23, 55, 8).vector_part() == Quaternion(0, 23, 55, 8)
|
202 |
+
assert Quaternion(w, x, y, z).vector_part() == Quaternion(0, x, y, z)
|
203 |
+
|
204 |
+
assert q1.axis() == Quaternion(0, 2*sqrt(29)/29, 3*sqrt(29)/29, 4*sqrt(29)/29)
|
205 |
+
assert q1.axis().pow(2) == Quaternion(-1, 0, 0, 0)
|
206 |
+
assert q0.axis().scalar_part() == 0
|
207 |
+
assert (q.axis() == Quaternion(0,
|
208 |
+
x/sqrt(x**2 + y**2 + z**2),
|
209 |
+
y/sqrt(x**2 + y**2 + z**2),
|
210 |
+
z/sqrt(x**2 + y**2 + z**2)))
|
211 |
+
|
212 |
+
assert q0.is_pure() is True
|
213 |
+
assert q1.is_pure() is False
|
214 |
+
assert Quaternion(0, 0, 0, 3).is_pure() is True
|
215 |
+
assert Quaternion(0, 2, 10, 3).is_pure() is True
|
216 |
+
assert Quaternion(w, 2, 10, 3).is_pure() is None
|
217 |
+
|
218 |
+
assert q1.angle() == 2*atan(sqrt(29))
|
219 |
+
assert q.angle() == 2*atan2(sqrt(x**2 + y**2 + z**2), w)
|
220 |
+
|
221 |
+
assert Quaternion.arc_coplanar(q1, Quaternion(2, 4, 6, 8)) is True
|
222 |
+
assert Quaternion.arc_coplanar(q1, Quaternion(1, -2, -3, -4)) is True
|
223 |
+
assert Quaternion.arc_coplanar(q1, Quaternion(1, 8, 12, 16)) is True
|
224 |
+
assert Quaternion.arc_coplanar(q1, Quaternion(1, 2, 3, 4)) is True
|
225 |
+
assert Quaternion.arc_coplanar(q1, Quaternion(w, 4, 6, 8)) is True
|
226 |
+
assert Quaternion.arc_coplanar(q1, Quaternion(2, 7, 4, 1)) is False
|
227 |
+
assert Quaternion.arc_coplanar(q1, Quaternion(w, x, y, z)) is None
|
228 |
+
raises(ValueError, lambda: Quaternion.arc_coplanar(q1, q0))
|
229 |
+
|
230 |
+
assert Quaternion.vector_coplanar(
|
231 |
+
Quaternion(0, 8, 12, 16),
|
232 |
+
Quaternion(0, 4, 6, 8),
|
233 |
+
Quaternion(0, 2, 3, 4)) is True
|
234 |
+
assert Quaternion.vector_coplanar(
|
235 |
+
Quaternion(0, 0, 0, 0), Quaternion(0, 4, 6, 8), Quaternion(0, 2, 3, 4)) is True
|
236 |
+
assert Quaternion.vector_coplanar(
|
237 |
+
Quaternion(0, 8, 2, 6), Quaternion(0, 1, 6, 6), Quaternion(0, 0, 3, 4)) is False
|
238 |
+
assert Quaternion.vector_coplanar(
|
239 |
+
Quaternion(0, 1, 3, 4),
|
240 |
+
Quaternion(0, 4, w, 6),
|
241 |
+
Quaternion(0, 6, 8, 1)) is None
|
242 |
+
raises(ValueError, lambda:
|
243 |
+
Quaternion.vector_coplanar(q0, Quaternion(0, 4, 6, 8), q1))
|
244 |
+
|
245 |
+
assert Quaternion(0, 1, 2, 3).parallel(Quaternion(0, 2, 4, 6)) is True
|
246 |
+
assert Quaternion(0, 1, 2, 3).parallel(Quaternion(0, 2, 2, 6)) is False
|
247 |
+
assert Quaternion(0, 1, 2, 3).parallel(Quaternion(w, x, y, 6)) is None
|
248 |
+
raises(ValueError, lambda: q0.parallel(q1))
|
249 |
+
|
250 |
+
assert Quaternion(0, 1, 2, 3).orthogonal(Quaternion(0, -2, 1, 0)) is True
|
251 |
+
assert Quaternion(0, 2, 4, 7).orthogonal(Quaternion(0, 2, 2, 6)) is False
|
252 |
+
assert Quaternion(0, 2, 4, 7).orthogonal(Quaternion(w, x, y, 6)) is None
|
253 |
+
raises(ValueError, lambda: q0.orthogonal(q1))
|
254 |
+
|
255 |
+
assert q1.index_vector() == Quaternion(
|
256 |
+
0, 2*sqrt(870)/29,
|
257 |
+
3*sqrt(870)/29,
|
258 |
+
4*sqrt(870)/29)
|
259 |
+
assert Quaternion(0, 3, 9, 4).index_vector() == Quaternion(0, 3, 9, 4)
|
260 |
+
|
261 |
+
assert Quaternion(4, 3, 9, 4).mensor() == log(sqrt(122))
|
262 |
+
assert Quaternion(3, 3, 0, 2).mensor() == log(sqrt(22))
|
263 |
+
|
264 |
+
assert q0.is_zero_quaternion() is True
|
265 |
+
assert q1.is_zero_quaternion() is False
|
266 |
+
assert Quaternion(w, 0, 0, 0).is_zero_quaternion() is None
|
267 |
+
|
268 |
+
def test_quaternion_conversions():
|
269 |
+
q1 = Quaternion(1, 2, 3, 4)
|
270 |
+
|
271 |
+
assert q1.to_axis_angle() == ((2 * sqrt(29)/29,
|
272 |
+
3 * sqrt(29)/29,
|
273 |
+
4 * sqrt(29)/29),
|
274 |
+
2 * acos(sqrt(30)/30))
|
275 |
+
|
276 |
+
assert (q1.to_rotation_matrix() ==
|
277 |
+
Matrix([[Rational(-2, 3), Rational(2, 15), Rational(11, 15)],
|
278 |
+
[Rational(2, 3), Rational(-1, 3), Rational(2, 3)],
|
279 |
+
[Rational(1, 3), Rational(14, 15), Rational(2, 15)]]))
|
280 |
+
|
281 |
+
assert (q1.to_rotation_matrix((1, 1, 1)) ==
|
282 |
+
Matrix([
|
283 |
+
[Rational(-2, 3), Rational(2, 15), Rational(11, 15), Rational(4, 5)],
|
284 |
+
[Rational(2, 3), Rational(-1, 3), Rational(2, 3), S.Zero],
|
285 |
+
[Rational(1, 3), Rational(14, 15), Rational(2, 15), Rational(-2, 5)],
|
286 |
+
[S.Zero, S.Zero, S.Zero, S.One]]))
|
287 |
+
|
288 |
+
theta = symbols("theta", real=True)
|
289 |
+
q2 = Quaternion(cos(theta/2), 0, 0, sin(theta/2))
|
290 |
+
|
291 |
+
assert trigsimp(q2.to_rotation_matrix()) == Matrix([
|
292 |
+
[cos(theta), -sin(theta), 0],
|
293 |
+
[sin(theta), cos(theta), 0],
|
294 |
+
[0, 0, 1]])
|
295 |
+
|
296 |
+
assert q2.to_axis_angle() == ((0, 0, sin(theta/2)/Abs(sin(theta/2))),
|
297 |
+
2*acos(cos(theta/2)))
|
298 |
+
|
299 |
+
assert trigsimp(q2.to_rotation_matrix((1, 1, 1))) == Matrix([
|
300 |
+
[cos(theta), -sin(theta), 0, sin(theta) - cos(theta) + 1],
|
301 |
+
[sin(theta), cos(theta), 0, -sin(theta) - cos(theta) + 1],
|
302 |
+
[0, 0, 1, 0],
|
303 |
+
[0, 0, 0, 1]])
|
304 |
+
|
305 |
+
|
306 |
+
def test_rotation_matrix_homogeneous():
|
307 |
+
q = Quaternion(w, x, y, z)
|
308 |
+
R1 = q.to_rotation_matrix(homogeneous=True) * q.norm()**2
|
309 |
+
R2 = simplify(q.to_rotation_matrix(homogeneous=False) * q.norm()**2)
|
310 |
+
assert R1 == R2
|
311 |
+
|
312 |
+
|
313 |
+
def test_quaternion_rotation_iss1593():
|
314 |
+
"""
|
315 |
+
There was a sign mistake in the definition,
|
316 |
+
of the rotation matrix. This tests that particular sign mistake.
|
317 |
+
See issue 1593 for reference.
|
318 |
+
See wikipedia
|
319 |
+
https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Quaternion-derived_rotation_matrix
|
320 |
+
for the correct definition
|
321 |
+
"""
|
322 |
+
q = Quaternion(cos(phi/2), sin(phi/2), 0, 0)
|
323 |
+
assert(trigsimp(q.to_rotation_matrix()) == Matrix([
|
324 |
+
[1, 0, 0],
|
325 |
+
[0, cos(phi), -sin(phi)],
|
326 |
+
[0, sin(phi), cos(phi)]]))
|
327 |
+
|
328 |
+
|
329 |
+
def test_quaternion_multiplication():
|
330 |
+
q1 = Quaternion(3 + 4*I, 2 + 5*I, 0, 7 + 8*I, real_field = False)
|
331 |
+
q2 = Quaternion(1, 2, 3, 5)
|
332 |
+
q3 = Quaternion(1, 1, 1, y)
|
333 |
+
|
334 |
+
assert Quaternion._generic_mul(S(4), S.One) == 4
|
335 |
+
assert (Quaternion._generic_mul(S(4), q1) ==
|
336 |
+
Quaternion(12 + 16*I, 8 + 20*I, 0, 28 + 32*I))
|
337 |
+
assert q2.mul(2) == Quaternion(2, 4, 6, 10)
|
338 |
+
assert q2.mul(q3) == Quaternion(-5*y - 4, 3*y - 2, 9 - 2*y, y + 4)
|
339 |
+
assert q2.mul(q3) == q2*q3
|
340 |
+
|
341 |
+
z = symbols('z', complex=True)
|
342 |
+
z_quat = Quaternion(re(z), im(z), 0, 0)
|
343 |
+
q = Quaternion(*symbols('q:4', real=True))
|
344 |
+
|
345 |
+
assert z * q == z_quat * q
|
346 |
+
assert q * z == q * z_quat
|
347 |
+
|
348 |
+
|
349 |
+
def test_issue_16318():
|
350 |
+
#for rtruediv
|
351 |
+
q0 = Quaternion(0, 0, 0, 0)
|
352 |
+
raises(ValueError, lambda: 1/q0)
|
353 |
+
#for rotate_point
|
354 |
+
q = Quaternion(1, 2, 3, 4)
|
355 |
+
(axis, angle) = q.to_axis_angle()
|
356 |
+
assert Quaternion.rotate_point((1, 1, 1), (axis, angle)) == (S.One / 5, 1, S(7) / 5)
|
357 |
+
#test for to_axis_angle
|
358 |
+
q = Quaternion(-1, 1, 1, 1)
|
359 |
+
axis = (-sqrt(3)/3, -sqrt(3)/3, -sqrt(3)/3)
|
360 |
+
angle = 2*pi/3
|
361 |
+
assert (axis, angle) == q.to_axis_angle()
|
362 |
+
|
363 |
+
|
364 |
+
@slow
|
365 |
+
def test_to_euler():
|
366 |
+
q = Quaternion(w, x, y, z)
|
367 |
+
q_normalized = q.normalize()
|
368 |
+
|
369 |
+
seqs = ['zxy', 'zyx', 'zyz', 'zxz']
|
370 |
+
seqs += [seq.upper() for seq in seqs]
|
371 |
+
|
372 |
+
for seq in seqs:
|
373 |
+
euler_from_q = q.to_euler(seq)
|
374 |
+
q_back = simplify(Quaternion.from_euler(euler_from_q, seq))
|
375 |
+
assert q_back == q_normalized
|
376 |
+
|
377 |
+
|
378 |
+
def test_to_euler_iss24504():
|
379 |
+
"""
|
380 |
+
There was a mistake in the degenerate case testing
|
381 |
+
See issue 24504 for reference.
|
382 |
+
"""
|
383 |
+
q = Quaternion.from_euler((phi, 0, 0), 'zyz')
|
384 |
+
assert trigsimp(q.to_euler('zyz'), inverse=True) == (phi, 0, 0)
|
385 |
+
|
386 |
+
|
387 |
+
def test_to_euler_numerical_singilarities():
|
388 |
+
|
389 |
+
def test_one_case(angles, seq):
|
390 |
+
q = Quaternion.from_euler(angles, seq)
|
391 |
+
assert q.to_euler(seq) == angles
|
392 |
+
|
393 |
+
# symmetric
|
394 |
+
test_one_case((pi/2, 0, 0), 'zyz')
|
395 |
+
test_one_case((pi/2, 0, 0), 'ZYZ')
|
396 |
+
test_one_case((pi/2, pi, 0), 'zyz')
|
397 |
+
test_one_case((pi/2, pi, 0), 'ZYZ')
|
398 |
+
|
399 |
+
# asymmetric
|
400 |
+
test_one_case((pi/2, pi/2, 0), 'zyx')
|
401 |
+
test_one_case((pi/2, -pi/2, 0), 'zyx')
|
402 |
+
test_one_case((pi/2, pi/2, 0), 'ZYX')
|
403 |
+
test_one_case((pi/2, -pi/2, 0), 'ZYX')
|
404 |
+
|
405 |
+
|
406 |
+
@slow
|
407 |
+
def test_to_euler_options():
|
408 |
+
def test_one_case(q):
|
409 |
+
angles1 = Matrix(q.to_euler(seq, True, True))
|
410 |
+
angles2 = Matrix(q.to_euler(seq, False, False))
|
411 |
+
angle_errors = simplify(angles1-angles2).evalf()
|
412 |
+
for angle_error in angle_errors:
|
413 |
+
# forcing angles to set {-pi, pi}
|
414 |
+
angle_error = (angle_error + pi) % (2 * pi) - pi
|
415 |
+
assert angle_error < 10e-7
|
416 |
+
|
417 |
+
for xyz in ('xyz', 'XYZ'):
|
418 |
+
for seq_tuple in permutations(xyz):
|
419 |
+
for symmetric in (True, False):
|
420 |
+
if symmetric:
|
421 |
+
seq = ''.join([seq_tuple[0], seq_tuple[1], seq_tuple[0]])
|
422 |
+
else:
|
423 |
+
seq = ''.join(seq_tuple)
|
424 |
+
|
425 |
+
for elements in product([-1, 0, 1], repeat=4):
|
426 |
+
q = Quaternion(*elements)
|
427 |
+
if not q.is_zero_quaternion():
|
428 |
+
test_one_case(q)
|
MLPY/Lib/site-packages/sympy/assumptions/__init__.py
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
A module to implement logical predicates and assumption system.
|
3 |
+
"""
|
4 |
+
|
5 |
+
from .assume import (
|
6 |
+
AppliedPredicate, Predicate, AssumptionsContext, assuming,
|
7 |
+
global_assumptions
|
8 |
+
)
|
9 |
+
from .ask import Q, ask, register_handler, remove_handler
|
10 |
+
from .refine import refine
|
11 |
+
from .relation import BinaryRelation, AppliedBinaryRelation
|
12 |
+
|
13 |
+
__all__ = [
|
14 |
+
'AppliedPredicate', 'Predicate', 'AssumptionsContext', 'assuming',
|
15 |
+
'global_assumptions', 'Q', 'ask', 'register_handler', 'remove_handler',
|
16 |
+
'refine',
|
17 |
+
'BinaryRelation', 'AppliedBinaryRelation'
|
18 |
+
]
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (659 Bytes). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/ask.cpython-39.pyc
ADDED
Binary file (20 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/ask_generated.cpython-39.pyc
ADDED
Binary file (10.3 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/assume.cpython-39.pyc
ADDED
Binary file (14.5 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/cnf.cpython-39.pyc
ADDED
Binary file (17.2 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/facts.cpython-39.pyc
ADDED
Binary file (6.73 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/lra_satask.cpython-39.pyc
ADDED
Binary file (6.49 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/refine.cpython-39.pyc
ADDED
Binary file (9.89 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/satask.cpython-39.pyc
ADDED
Binary file (11 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/sathandlers.cpython-39.pyc
ADDED
Binary file (10.6 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/__pycache__/wrapper.cpython-39.pyc
ADDED
Binary file (5.41 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/ask.py
ADDED
@@ -0,0 +1,651 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""Module for querying SymPy objects about assumptions."""
|
2 |
+
|
3 |
+
from sympy.assumptions.assume import (global_assumptions, Predicate,
|
4 |
+
AppliedPredicate)
|
5 |
+
from sympy.assumptions.cnf import CNF, EncodedCNF, Literal
|
6 |
+
from sympy.core import sympify
|
7 |
+
from sympy.core.kind import BooleanKind
|
8 |
+
from sympy.core.relational import Eq, Ne, Gt, Lt, Ge, Le
|
9 |
+
from sympy.logic.inference import satisfiable
|
10 |
+
from sympy.utilities.decorator import memoize_property
|
11 |
+
from sympy.utilities.exceptions import (sympy_deprecation_warning,
|
12 |
+
SymPyDeprecationWarning,
|
13 |
+
ignore_warnings)
|
14 |
+
|
15 |
+
|
16 |
+
# Memoization is necessary for the properties of AssumptionKeys to
|
17 |
+
# ensure that only one object of Predicate objects are created.
|
18 |
+
# This is because assumption handlers are registered on those objects.
|
19 |
+
|
20 |
+
|
21 |
+
class AssumptionKeys:
|
22 |
+
"""
|
23 |
+
This class contains all the supported keys by ``ask``.
|
24 |
+
It should be accessed via the instance ``sympy.Q``.
|
25 |
+
|
26 |
+
"""
|
27 |
+
|
28 |
+
# DO NOT add methods or properties other than predicate keys.
|
29 |
+
# SAT solver checks the properties of Q and use them to compute the
|
30 |
+
# fact system. Non-predicate attributes will break this.
|
31 |
+
|
32 |
+
@memoize_property
|
33 |
+
def hermitian(self):
|
34 |
+
from .handlers.sets import HermitianPredicate
|
35 |
+
return HermitianPredicate()
|
36 |
+
|
37 |
+
@memoize_property
|
38 |
+
def antihermitian(self):
|
39 |
+
from .handlers.sets import AntihermitianPredicate
|
40 |
+
return AntihermitianPredicate()
|
41 |
+
|
42 |
+
@memoize_property
|
43 |
+
def real(self):
|
44 |
+
from .handlers.sets import RealPredicate
|
45 |
+
return RealPredicate()
|
46 |
+
|
47 |
+
@memoize_property
|
48 |
+
def extended_real(self):
|
49 |
+
from .handlers.sets import ExtendedRealPredicate
|
50 |
+
return ExtendedRealPredicate()
|
51 |
+
|
52 |
+
@memoize_property
|
53 |
+
def imaginary(self):
|
54 |
+
from .handlers.sets import ImaginaryPredicate
|
55 |
+
return ImaginaryPredicate()
|
56 |
+
|
57 |
+
@memoize_property
|
58 |
+
def complex(self):
|
59 |
+
from .handlers.sets import ComplexPredicate
|
60 |
+
return ComplexPredicate()
|
61 |
+
|
62 |
+
@memoize_property
|
63 |
+
def algebraic(self):
|
64 |
+
from .handlers.sets import AlgebraicPredicate
|
65 |
+
return AlgebraicPredicate()
|
66 |
+
|
67 |
+
@memoize_property
|
68 |
+
def transcendental(self):
|
69 |
+
from .predicates.sets import TranscendentalPredicate
|
70 |
+
return TranscendentalPredicate()
|
71 |
+
|
72 |
+
@memoize_property
|
73 |
+
def integer(self):
|
74 |
+
from .handlers.sets import IntegerPredicate
|
75 |
+
return IntegerPredicate()
|
76 |
+
|
77 |
+
@memoize_property
|
78 |
+
def noninteger(self):
|
79 |
+
from .predicates.sets import NonIntegerPredicate
|
80 |
+
return NonIntegerPredicate()
|
81 |
+
|
82 |
+
@memoize_property
|
83 |
+
def rational(self):
|
84 |
+
from .handlers.sets import RationalPredicate
|
85 |
+
return RationalPredicate()
|
86 |
+
|
87 |
+
@memoize_property
|
88 |
+
def irrational(self):
|
89 |
+
from .handlers.sets import IrrationalPredicate
|
90 |
+
return IrrationalPredicate()
|
91 |
+
|
92 |
+
@memoize_property
|
93 |
+
def finite(self):
|
94 |
+
from .handlers.calculus import FinitePredicate
|
95 |
+
return FinitePredicate()
|
96 |
+
|
97 |
+
@memoize_property
|
98 |
+
def infinite(self):
|
99 |
+
from .handlers.calculus import InfinitePredicate
|
100 |
+
return InfinitePredicate()
|
101 |
+
|
102 |
+
@memoize_property
|
103 |
+
def positive_infinite(self):
|
104 |
+
from .handlers.calculus import PositiveInfinitePredicate
|
105 |
+
return PositiveInfinitePredicate()
|
106 |
+
|
107 |
+
@memoize_property
|
108 |
+
def negative_infinite(self):
|
109 |
+
from .handlers.calculus import NegativeInfinitePredicate
|
110 |
+
return NegativeInfinitePredicate()
|
111 |
+
|
112 |
+
@memoize_property
|
113 |
+
def positive(self):
|
114 |
+
from .handlers.order import PositivePredicate
|
115 |
+
return PositivePredicate()
|
116 |
+
|
117 |
+
@memoize_property
|
118 |
+
def negative(self):
|
119 |
+
from .handlers.order import NegativePredicate
|
120 |
+
return NegativePredicate()
|
121 |
+
|
122 |
+
@memoize_property
|
123 |
+
def zero(self):
|
124 |
+
from .handlers.order import ZeroPredicate
|
125 |
+
return ZeroPredicate()
|
126 |
+
|
127 |
+
@memoize_property
|
128 |
+
def extended_positive(self):
|
129 |
+
from .handlers.order import ExtendedPositivePredicate
|
130 |
+
return ExtendedPositivePredicate()
|
131 |
+
|
132 |
+
@memoize_property
|
133 |
+
def extended_negative(self):
|
134 |
+
from .handlers.order import ExtendedNegativePredicate
|
135 |
+
return ExtendedNegativePredicate()
|
136 |
+
|
137 |
+
@memoize_property
|
138 |
+
def nonzero(self):
|
139 |
+
from .handlers.order import NonZeroPredicate
|
140 |
+
return NonZeroPredicate()
|
141 |
+
|
142 |
+
@memoize_property
|
143 |
+
def nonpositive(self):
|
144 |
+
from .handlers.order import NonPositivePredicate
|
145 |
+
return NonPositivePredicate()
|
146 |
+
|
147 |
+
@memoize_property
|
148 |
+
def nonnegative(self):
|
149 |
+
from .handlers.order import NonNegativePredicate
|
150 |
+
return NonNegativePredicate()
|
151 |
+
|
152 |
+
@memoize_property
|
153 |
+
def extended_nonzero(self):
|
154 |
+
from .handlers.order import ExtendedNonZeroPredicate
|
155 |
+
return ExtendedNonZeroPredicate()
|
156 |
+
|
157 |
+
@memoize_property
|
158 |
+
def extended_nonpositive(self):
|
159 |
+
from .handlers.order import ExtendedNonPositivePredicate
|
160 |
+
return ExtendedNonPositivePredicate()
|
161 |
+
|
162 |
+
@memoize_property
|
163 |
+
def extended_nonnegative(self):
|
164 |
+
from .handlers.order import ExtendedNonNegativePredicate
|
165 |
+
return ExtendedNonNegativePredicate()
|
166 |
+
|
167 |
+
@memoize_property
|
168 |
+
def even(self):
|
169 |
+
from .handlers.ntheory import EvenPredicate
|
170 |
+
return EvenPredicate()
|
171 |
+
|
172 |
+
@memoize_property
|
173 |
+
def odd(self):
|
174 |
+
from .handlers.ntheory import OddPredicate
|
175 |
+
return OddPredicate()
|
176 |
+
|
177 |
+
@memoize_property
|
178 |
+
def prime(self):
|
179 |
+
from .handlers.ntheory import PrimePredicate
|
180 |
+
return PrimePredicate()
|
181 |
+
|
182 |
+
@memoize_property
|
183 |
+
def composite(self):
|
184 |
+
from .handlers.ntheory import CompositePredicate
|
185 |
+
return CompositePredicate()
|
186 |
+
|
187 |
+
@memoize_property
|
188 |
+
def commutative(self):
|
189 |
+
from .handlers.common import CommutativePredicate
|
190 |
+
return CommutativePredicate()
|
191 |
+
|
192 |
+
@memoize_property
|
193 |
+
def is_true(self):
|
194 |
+
from .handlers.common import IsTruePredicate
|
195 |
+
return IsTruePredicate()
|
196 |
+
|
197 |
+
@memoize_property
|
198 |
+
def symmetric(self):
|
199 |
+
from .handlers.matrices import SymmetricPredicate
|
200 |
+
return SymmetricPredicate()
|
201 |
+
|
202 |
+
@memoize_property
|
203 |
+
def invertible(self):
|
204 |
+
from .handlers.matrices import InvertiblePredicate
|
205 |
+
return InvertiblePredicate()
|
206 |
+
|
207 |
+
@memoize_property
|
208 |
+
def orthogonal(self):
|
209 |
+
from .handlers.matrices import OrthogonalPredicate
|
210 |
+
return OrthogonalPredicate()
|
211 |
+
|
212 |
+
@memoize_property
|
213 |
+
def unitary(self):
|
214 |
+
from .handlers.matrices import UnitaryPredicate
|
215 |
+
return UnitaryPredicate()
|
216 |
+
|
217 |
+
@memoize_property
|
218 |
+
def positive_definite(self):
|
219 |
+
from .handlers.matrices import PositiveDefinitePredicate
|
220 |
+
return PositiveDefinitePredicate()
|
221 |
+
|
222 |
+
@memoize_property
|
223 |
+
def upper_triangular(self):
|
224 |
+
from .handlers.matrices import UpperTriangularPredicate
|
225 |
+
return UpperTriangularPredicate()
|
226 |
+
|
227 |
+
@memoize_property
|
228 |
+
def lower_triangular(self):
|
229 |
+
from .handlers.matrices import LowerTriangularPredicate
|
230 |
+
return LowerTriangularPredicate()
|
231 |
+
|
232 |
+
@memoize_property
|
233 |
+
def diagonal(self):
|
234 |
+
from .handlers.matrices import DiagonalPredicate
|
235 |
+
return DiagonalPredicate()
|
236 |
+
|
237 |
+
@memoize_property
|
238 |
+
def fullrank(self):
|
239 |
+
from .handlers.matrices import FullRankPredicate
|
240 |
+
return FullRankPredicate()
|
241 |
+
|
242 |
+
@memoize_property
|
243 |
+
def square(self):
|
244 |
+
from .handlers.matrices import SquarePredicate
|
245 |
+
return SquarePredicate()
|
246 |
+
|
247 |
+
@memoize_property
|
248 |
+
def integer_elements(self):
|
249 |
+
from .handlers.matrices import IntegerElementsPredicate
|
250 |
+
return IntegerElementsPredicate()
|
251 |
+
|
252 |
+
@memoize_property
|
253 |
+
def real_elements(self):
|
254 |
+
from .handlers.matrices import RealElementsPredicate
|
255 |
+
return RealElementsPredicate()
|
256 |
+
|
257 |
+
@memoize_property
|
258 |
+
def complex_elements(self):
|
259 |
+
from .handlers.matrices import ComplexElementsPredicate
|
260 |
+
return ComplexElementsPredicate()
|
261 |
+
|
262 |
+
@memoize_property
|
263 |
+
def singular(self):
|
264 |
+
from .predicates.matrices import SingularPredicate
|
265 |
+
return SingularPredicate()
|
266 |
+
|
267 |
+
@memoize_property
|
268 |
+
def normal(self):
|
269 |
+
from .predicates.matrices import NormalPredicate
|
270 |
+
return NormalPredicate()
|
271 |
+
|
272 |
+
@memoize_property
|
273 |
+
def triangular(self):
|
274 |
+
from .predicates.matrices import TriangularPredicate
|
275 |
+
return TriangularPredicate()
|
276 |
+
|
277 |
+
@memoize_property
|
278 |
+
def unit_triangular(self):
|
279 |
+
from .predicates.matrices import UnitTriangularPredicate
|
280 |
+
return UnitTriangularPredicate()
|
281 |
+
|
282 |
+
@memoize_property
|
283 |
+
def eq(self):
|
284 |
+
from .relation.equality import EqualityPredicate
|
285 |
+
return EqualityPredicate()
|
286 |
+
|
287 |
+
@memoize_property
|
288 |
+
def ne(self):
|
289 |
+
from .relation.equality import UnequalityPredicate
|
290 |
+
return UnequalityPredicate()
|
291 |
+
|
292 |
+
@memoize_property
|
293 |
+
def gt(self):
|
294 |
+
from .relation.equality import StrictGreaterThanPredicate
|
295 |
+
return StrictGreaterThanPredicate()
|
296 |
+
|
297 |
+
@memoize_property
|
298 |
+
def ge(self):
|
299 |
+
from .relation.equality import GreaterThanPredicate
|
300 |
+
return GreaterThanPredicate()
|
301 |
+
|
302 |
+
@memoize_property
|
303 |
+
def lt(self):
|
304 |
+
from .relation.equality import StrictLessThanPredicate
|
305 |
+
return StrictLessThanPredicate()
|
306 |
+
|
307 |
+
@memoize_property
|
308 |
+
def le(self):
|
309 |
+
from .relation.equality import LessThanPredicate
|
310 |
+
return LessThanPredicate()
|
311 |
+
|
312 |
+
|
313 |
+
Q = AssumptionKeys()
|
314 |
+
|
315 |
+
def _extract_all_facts(assump, exprs):
|
316 |
+
"""
|
317 |
+
Extract all relevant assumptions from *assump* with respect to given *exprs*.
|
318 |
+
|
319 |
+
Parameters
|
320 |
+
==========
|
321 |
+
|
322 |
+
assump : sympy.assumptions.cnf.CNF
|
323 |
+
|
324 |
+
exprs : tuple of expressions
|
325 |
+
|
326 |
+
Returns
|
327 |
+
=======
|
328 |
+
|
329 |
+
sympy.assumptions.cnf.CNF
|
330 |
+
|
331 |
+
Examples
|
332 |
+
========
|
333 |
+
|
334 |
+
>>> from sympy import Q
|
335 |
+
>>> from sympy.assumptions.cnf import CNF
|
336 |
+
>>> from sympy.assumptions.ask import _extract_all_facts
|
337 |
+
>>> from sympy.abc import x, y
|
338 |
+
>>> assump = CNF.from_prop(Q.positive(x) & Q.integer(y))
|
339 |
+
>>> exprs = (x,)
|
340 |
+
>>> cnf = _extract_all_facts(assump, exprs)
|
341 |
+
>>> cnf.clauses
|
342 |
+
{frozenset({Literal(Q.positive, False)})}
|
343 |
+
|
344 |
+
"""
|
345 |
+
facts = set()
|
346 |
+
|
347 |
+
for clause in assump.clauses:
|
348 |
+
args = []
|
349 |
+
for literal in clause:
|
350 |
+
if isinstance(literal.lit, AppliedPredicate) and len(literal.lit.arguments) == 1:
|
351 |
+
if literal.lit.arg in exprs:
|
352 |
+
# Add literal if it has matching in it
|
353 |
+
args.append(Literal(literal.lit.function, literal.is_Not))
|
354 |
+
else:
|
355 |
+
# If any of the literals doesn't have matching expr don't add the whole clause.
|
356 |
+
break
|
357 |
+
else:
|
358 |
+
# If any of the literals aren't unary predicate don't add the whole clause.
|
359 |
+
break
|
360 |
+
|
361 |
+
else:
|
362 |
+
if args:
|
363 |
+
facts.add(frozenset(args))
|
364 |
+
return CNF(facts)
|
365 |
+
|
366 |
+
|
367 |
+
def ask(proposition, assumptions=True, context=global_assumptions):
|
368 |
+
"""
|
369 |
+
Function to evaluate the proposition with assumptions.
|
370 |
+
|
371 |
+
Explanation
|
372 |
+
===========
|
373 |
+
|
374 |
+
This function evaluates the proposition to ``True`` or ``False`` if
|
375 |
+
the truth value can be determined. If not, it returns ``None``.
|
376 |
+
|
377 |
+
It should be discerned from :func:`~.refine()` which, when applied to a
|
378 |
+
proposition, simplifies the argument to symbolic ``Boolean`` instead of
|
379 |
+
Python built-in ``True``, ``False`` or ``None``.
|
380 |
+
|
381 |
+
**Syntax**
|
382 |
+
|
383 |
+
* ask(proposition)
|
384 |
+
Evaluate the *proposition* in global assumption context.
|
385 |
+
|
386 |
+
* ask(proposition, assumptions)
|
387 |
+
Evaluate the *proposition* with respect to *assumptions* in
|
388 |
+
global assumption context.
|
389 |
+
|
390 |
+
Parameters
|
391 |
+
==========
|
392 |
+
|
393 |
+
proposition : Boolean
|
394 |
+
Proposition which will be evaluated to boolean value. If this is
|
395 |
+
not ``AppliedPredicate``, it will be wrapped by ``Q.is_true``.
|
396 |
+
|
397 |
+
assumptions : Boolean, optional
|
398 |
+
Local assumptions to evaluate the *proposition*.
|
399 |
+
|
400 |
+
context : AssumptionsContext, optional
|
401 |
+
Default assumptions to evaluate the *proposition*. By default,
|
402 |
+
this is ``sympy.assumptions.global_assumptions`` variable.
|
403 |
+
|
404 |
+
Returns
|
405 |
+
=======
|
406 |
+
|
407 |
+
``True``, ``False``, or ``None``
|
408 |
+
|
409 |
+
Raises
|
410 |
+
======
|
411 |
+
|
412 |
+
TypeError : *proposition* or *assumptions* is not valid logical expression.
|
413 |
+
|
414 |
+
ValueError : assumptions are inconsistent.
|
415 |
+
|
416 |
+
Examples
|
417 |
+
========
|
418 |
+
|
419 |
+
>>> from sympy import ask, Q, pi
|
420 |
+
>>> from sympy.abc import x, y
|
421 |
+
>>> ask(Q.rational(pi))
|
422 |
+
False
|
423 |
+
>>> ask(Q.even(x*y), Q.even(x) & Q.integer(y))
|
424 |
+
True
|
425 |
+
>>> ask(Q.prime(4*x), Q.integer(x))
|
426 |
+
False
|
427 |
+
|
428 |
+
If the truth value cannot be determined, ``None`` will be returned.
|
429 |
+
|
430 |
+
>>> print(ask(Q.odd(3*x))) # cannot determine unless we know x
|
431 |
+
None
|
432 |
+
|
433 |
+
``ValueError`` is raised if assumptions are inconsistent.
|
434 |
+
|
435 |
+
>>> ask(Q.integer(x), Q.even(x) & Q.odd(x))
|
436 |
+
Traceback (most recent call last):
|
437 |
+
...
|
438 |
+
ValueError: inconsistent assumptions Q.even(x) & Q.odd(x)
|
439 |
+
|
440 |
+
Notes
|
441 |
+
=====
|
442 |
+
|
443 |
+
Relations in assumptions are not implemented (yet), so the following
|
444 |
+
will not give a meaningful result.
|
445 |
+
|
446 |
+
>>> ask(Q.positive(x), x > 0)
|
447 |
+
|
448 |
+
It is however a work in progress.
|
449 |
+
|
450 |
+
See Also
|
451 |
+
========
|
452 |
+
|
453 |
+
sympy.assumptions.refine.refine : Simplification using assumptions.
|
454 |
+
Proposition is not reduced to ``None`` if the truth value cannot
|
455 |
+
be determined.
|
456 |
+
"""
|
457 |
+
from sympy.assumptions.satask import satask
|
458 |
+
from sympy.assumptions.lra_satask import lra_satask
|
459 |
+
from sympy.logic.algorithms.lra_theory import UnhandledInput
|
460 |
+
|
461 |
+
proposition = sympify(proposition)
|
462 |
+
assumptions = sympify(assumptions)
|
463 |
+
|
464 |
+
if isinstance(proposition, Predicate) or proposition.kind is not BooleanKind:
|
465 |
+
raise TypeError("proposition must be a valid logical expression")
|
466 |
+
|
467 |
+
if isinstance(assumptions, Predicate) or assumptions.kind is not BooleanKind:
|
468 |
+
raise TypeError("assumptions must be a valid logical expression")
|
469 |
+
|
470 |
+
binrelpreds = {Eq: Q.eq, Ne: Q.ne, Gt: Q.gt, Lt: Q.lt, Ge: Q.ge, Le: Q.le}
|
471 |
+
if isinstance(proposition, AppliedPredicate):
|
472 |
+
key, args = proposition.function, proposition.arguments
|
473 |
+
elif proposition.func in binrelpreds:
|
474 |
+
key, args = binrelpreds[type(proposition)], proposition.args
|
475 |
+
else:
|
476 |
+
key, args = Q.is_true, (proposition,)
|
477 |
+
|
478 |
+
# convert local and global assumptions to CNF
|
479 |
+
assump_cnf = CNF.from_prop(assumptions)
|
480 |
+
assump_cnf.extend(context)
|
481 |
+
|
482 |
+
# extract the relevant facts from assumptions with respect to args
|
483 |
+
local_facts = _extract_all_facts(assump_cnf, args)
|
484 |
+
|
485 |
+
# convert default facts and assumed facts to encoded CNF
|
486 |
+
known_facts_cnf = get_all_known_facts()
|
487 |
+
enc_cnf = EncodedCNF()
|
488 |
+
enc_cnf.from_cnf(CNF(known_facts_cnf))
|
489 |
+
enc_cnf.add_from_cnf(local_facts)
|
490 |
+
|
491 |
+
# check the satisfiability of given assumptions
|
492 |
+
if local_facts.clauses and satisfiable(enc_cnf) is False:
|
493 |
+
raise ValueError("inconsistent assumptions %s" % assumptions)
|
494 |
+
|
495 |
+
# quick computation for single fact
|
496 |
+
res = _ask_single_fact(key, local_facts)
|
497 |
+
if res is not None:
|
498 |
+
return res
|
499 |
+
|
500 |
+
# direct resolution method, no logic
|
501 |
+
res = key(*args)._eval_ask(assumptions)
|
502 |
+
if res is not None:
|
503 |
+
return bool(res)
|
504 |
+
|
505 |
+
# using satask (still costly)
|
506 |
+
res = satask(proposition, assumptions=assumptions, context=context)
|
507 |
+
if res is not None:
|
508 |
+
return res
|
509 |
+
|
510 |
+
try:
|
511 |
+
res = lra_satask(proposition, assumptions=assumptions, context=context)
|
512 |
+
except UnhandledInput:
|
513 |
+
return None
|
514 |
+
|
515 |
+
return res
|
516 |
+
|
517 |
+
|
518 |
+
def _ask_single_fact(key, local_facts):
|
519 |
+
"""
|
520 |
+
Compute the truth value of single predicate using assumptions.
|
521 |
+
|
522 |
+
Parameters
|
523 |
+
==========
|
524 |
+
|
525 |
+
key : sympy.assumptions.assume.Predicate
|
526 |
+
Proposition predicate.
|
527 |
+
|
528 |
+
local_facts : sympy.assumptions.cnf.CNF
|
529 |
+
Local assumption in CNF form.
|
530 |
+
|
531 |
+
Returns
|
532 |
+
=======
|
533 |
+
|
534 |
+
``True``, ``False`` or ``None``
|
535 |
+
|
536 |
+
Examples
|
537 |
+
========
|
538 |
+
|
539 |
+
>>> from sympy import Q
|
540 |
+
>>> from sympy.assumptions.cnf import CNF
|
541 |
+
>>> from sympy.assumptions.ask import _ask_single_fact
|
542 |
+
|
543 |
+
If prerequisite of proposition is rejected by the assumption,
|
544 |
+
return ``False``.
|
545 |
+
|
546 |
+
>>> key, assump = Q.zero, ~Q.zero
|
547 |
+
>>> local_facts = CNF.from_prop(assump)
|
548 |
+
>>> _ask_single_fact(key, local_facts)
|
549 |
+
False
|
550 |
+
>>> key, assump = Q.zero, ~Q.even
|
551 |
+
>>> local_facts = CNF.from_prop(assump)
|
552 |
+
>>> _ask_single_fact(key, local_facts)
|
553 |
+
False
|
554 |
+
|
555 |
+
If assumption implies the proposition, return ``True``.
|
556 |
+
|
557 |
+
>>> key, assump = Q.even, Q.zero
|
558 |
+
>>> local_facts = CNF.from_prop(assump)
|
559 |
+
>>> _ask_single_fact(key, local_facts)
|
560 |
+
True
|
561 |
+
|
562 |
+
If proposition rejects the assumption, return ``False``.
|
563 |
+
|
564 |
+
>>> key, assump = Q.even, Q.odd
|
565 |
+
>>> local_facts = CNF.from_prop(assump)
|
566 |
+
>>> _ask_single_fact(key, local_facts)
|
567 |
+
False
|
568 |
+
"""
|
569 |
+
if local_facts.clauses:
|
570 |
+
|
571 |
+
known_facts_dict = get_known_facts_dict()
|
572 |
+
|
573 |
+
if len(local_facts.clauses) == 1:
|
574 |
+
cl, = local_facts.clauses
|
575 |
+
if len(cl) == 1:
|
576 |
+
f, = cl
|
577 |
+
prop_facts = known_facts_dict.get(key, None)
|
578 |
+
prop_req = prop_facts[0] if prop_facts is not None else set()
|
579 |
+
if f.is_Not and f.arg in prop_req:
|
580 |
+
# the prerequisite of proposition is rejected
|
581 |
+
return False
|
582 |
+
|
583 |
+
for clause in local_facts.clauses:
|
584 |
+
if len(clause) == 1:
|
585 |
+
f, = clause
|
586 |
+
prop_facts = known_facts_dict.get(f.arg, None) if not f.is_Not else None
|
587 |
+
if prop_facts is None:
|
588 |
+
continue
|
589 |
+
|
590 |
+
prop_req, prop_rej = prop_facts
|
591 |
+
if key in prop_req:
|
592 |
+
# assumption implies the proposition
|
593 |
+
return True
|
594 |
+
elif key in prop_rej:
|
595 |
+
# proposition rejects the assumption
|
596 |
+
return False
|
597 |
+
|
598 |
+
return None
|
599 |
+
|
600 |
+
|
601 |
+
def register_handler(key, handler):
|
602 |
+
"""
|
603 |
+
Register a handler in the ask system. key must be a string and handler a
|
604 |
+
class inheriting from AskHandler.
|
605 |
+
|
606 |
+
.. deprecated:: 1.8.
|
607 |
+
Use multipledispatch handler instead. See :obj:`~.Predicate`.
|
608 |
+
|
609 |
+
"""
|
610 |
+
sympy_deprecation_warning(
|
611 |
+
"""
|
612 |
+
The AskHandler system is deprecated. The register_handler() function
|
613 |
+
should be replaced with the multipledispatch handler of Predicate.
|
614 |
+
""",
|
615 |
+
deprecated_since_version="1.8",
|
616 |
+
active_deprecations_target='deprecated-askhandler',
|
617 |
+
)
|
618 |
+
if isinstance(key, Predicate):
|
619 |
+
key = key.name.name
|
620 |
+
Qkey = getattr(Q, key, None)
|
621 |
+
if Qkey is not None:
|
622 |
+
Qkey.add_handler(handler)
|
623 |
+
else:
|
624 |
+
setattr(Q, key, Predicate(key, handlers=[handler]))
|
625 |
+
|
626 |
+
|
627 |
+
def remove_handler(key, handler):
|
628 |
+
"""
|
629 |
+
Removes a handler from the ask system.
|
630 |
+
|
631 |
+
.. deprecated:: 1.8.
|
632 |
+
Use multipledispatch handler instead. See :obj:`~.Predicate`.
|
633 |
+
|
634 |
+
"""
|
635 |
+
sympy_deprecation_warning(
|
636 |
+
"""
|
637 |
+
The AskHandler system is deprecated. The remove_handler() function
|
638 |
+
should be replaced with the multipledispatch handler of Predicate.
|
639 |
+
""",
|
640 |
+
deprecated_since_version="1.8",
|
641 |
+
active_deprecations_target='deprecated-askhandler',
|
642 |
+
)
|
643 |
+
if isinstance(key, Predicate):
|
644 |
+
key = key.name.name
|
645 |
+
# Don't show the same warning again recursively
|
646 |
+
with ignore_warnings(SymPyDeprecationWarning):
|
647 |
+
getattr(Q, key).remove_handler(handler)
|
648 |
+
|
649 |
+
|
650 |
+
from sympy.assumptions.ask_generated import (get_all_known_facts,
|
651 |
+
get_known_facts_dict)
|
MLPY/Lib/site-packages/sympy/assumptions/ask_generated.py
ADDED
@@ -0,0 +1,352 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Do NOT manually edit this file.
|
3 |
+
Instead, run ./bin/ask_update.py.
|
4 |
+
"""
|
5 |
+
|
6 |
+
from sympy.assumptions.ask import Q
|
7 |
+
from sympy.assumptions.cnf import Literal
|
8 |
+
from sympy.core.cache import cacheit
|
9 |
+
|
10 |
+
@cacheit
|
11 |
+
def get_all_known_facts():
|
12 |
+
"""
|
13 |
+
Known facts between unary predicates as CNF clauses.
|
14 |
+
"""
|
15 |
+
return {
|
16 |
+
frozenset((Literal(Q.algebraic, False), Literal(Q.imaginary, True), Literal(Q.transcendental, False))),
|
17 |
+
frozenset((Literal(Q.algebraic, False), Literal(Q.negative, True), Literal(Q.transcendental, False))),
|
18 |
+
frozenset((Literal(Q.algebraic, False), Literal(Q.positive, True), Literal(Q.transcendental, False))),
|
19 |
+
frozenset((Literal(Q.algebraic, False), Literal(Q.rational, True))),
|
20 |
+
frozenset((Literal(Q.algebraic, False), Literal(Q.transcendental, False), Literal(Q.zero, True))),
|
21 |
+
frozenset((Literal(Q.algebraic, True), Literal(Q.finite, False))),
|
22 |
+
frozenset((Literal(Q.algebraic, True), Literal(Q.transcendental, True))),
|
23 |
+
frozenset((Literal(Q.antihermitian, False), Literal(Q.hermitian, False), Literal(Q.zero, True))),
|
24 |
+
frozenset((Literal(Q.antihermitian, False), Literal(Q.imaginary, True))),
|
25 |
+
frozenset((Literal(Q.commutative, False), Literal(Q.finite, True))),
|
26 |
+
frozenset((Literal(Q.commutative, False), Literal(Q.infinite, True))),
|
27 |
+
frozenset((Literal(Q.complex_elements, False), Literal(Q.real_elements, True))),
|
28 |
+
frozenset((Literal(Q.composite, False), Literal(Q.even, True), Literal(Q.positive, True), Literal(Q.prime, False))),
|
29 |
+
frozenset((Literal(Q.composite, True), Literal(Q.even, False), Literal(Q.odd, False))),
|
30 |
+
frozenset((Literal(Q.composite, True), Literal(Q.positive, False))),
|
31 |
+
frozenset((Literal(Q.composite, True), Literal(Q.prime, True))),
|
32 |
+
frozenset((Literal(Q.diagonal, False), Literal(Q.lower_triangular, True), Literal(Q.upper_triangular, True))),
|
33 |
+
frozenset((Literal(Q.diagonal, True), Literal(Q.lower_triangular, False))),
|
34 |
+
frozenset((Literal(Q.diagonal, True), Literal(Q.normal, False))),
|
35 |
+
frozenset((Literal(Q.diagonal, True), Literal(Q.symmetric, False))),
|
36 |
+
frozenset((Literal(Q.diagonal, True), Literal(Q.upper_triangular, False))),
|
37 |
+
frozenset((Literal(Q.even, False), Literal(Q.odd, False), Literal(Q.prime, True))),
|
38 |
+
frozenset((Literal(Q.even, False), Literal(Q.zero, True))),
|
39 |
+
frozenset((Literal(Q.even, True), Literal(Q.odd, True))),
|
40 |
+
frozenset((Literal(Q.even, True), Literal(Q.rational, False))),
|
41 |
+
frozenset((Literal(Q.finite, False), Literal(Q.transcendental, True))),
|
42 |
+
frozenset((Literal(Q.finite, True), Literal(Q.infinite, True))),
|
43 |
+
frozenset((Literal(Q.fullrank, False), Literal(Q.invertible, True))),
|
44 |
+
frozenset((Literal(Q.fullrank, True), Literal(Q.invertible, False), Literal(Q.square, True))),
|
45 |
+
frozenset((Literal(Q.hermitian, False), Literal(Q.negative, True))),
|
46 |
+
frozenset((Literal(Q.hermitian, False), Literal(Q.positive, True))),
|
47 |
+
frozenset((Literal(Q.hermitian, False), Literal(Q.zero, True))),
|
48 |
+
frozenset((Literal(Q.imaginary, True), Literal(Q.negative, True))),
|
49 |
+
frozenset((Literal(Q.imaginary, True), Literal(Q.positive, True))),
|
50 |
+
frozenset((Literal(Q.imaginary, True), Literal(Q.zero, True))),
|
51 |
+
frozenset((Literal(Q.infinite, False), Literal(Q.negative_infinite, True))),
|
52 |
+
frozenset((Literal(Q.infinite, False), Literal(Q.positive_infinite, True))),
|
53 |
+
frozenset((Literal(Q.integer_elements, True), Literal(Q.real_elements, False))),
|
54 |
+
frozenset((Literal(Q.invertible, False), Literal(Q.positive_definite, True))),
|
55 |
+
frozenset((Literal(Q.invertible, False), Literal(Q.singular, False))),
|
56 |
+
frozenset((Literal(Q.invertible, False), Literal(Q.unitary, True))),
|
57 |
+
frozenset((Literal(Q.invertible, True), Literal(Q.singular, True))),
|
58 |
+
frozenset((Literal(Q.invertible, True), Literal(Q.square, False))),
|
59 |
+
frozenset((Literal(Q.irrational, False), Literal(Q.negative, True), Literal(Q.rational, False))),
|
60 |
+
frozenset((Literal(Q.irrational, False), Literal(Q.positive, True), Literal(Q.rational, False))),
|
61 |
+
frozenset((Literal(Q.irrational, False), Literal(Q.rational, False), Literal(Q.zero, True))),
|
62 |
+
frozenset((Literal(Q.irrational, True), Literal(Q.negative, False), Literal(Q.positive, False), Literal(Q.zero, False))),
|
63 |
+
frozenset((Literal(Q.irrational, True), Literal(Q.rational, True))),
|
64 |
+
frozenset((Literal(Q.lower_triangular, False), Literal(Q.triangular, True), Literal(Q.upper_triangular, False))),
|
65 |
+
frozenset((Literal(Q.lower_triangular, True), Literal(Q.triangular, False))),
|
66 |
+
frozenset((Literal(Q.negative, False), Literal(Q.positive, False), Literal(Q.rational, True), Literal(Q.zero, False))),
|
67 |
+
frozenset((Literal(Q.negative, True), Literal(Q.negative_infinite, True))),
|
68 |
+
frozenset((Literal(Q.negative, True), Literal(Q.positive, True))),
|
69 |
+
frozenset((Literal(Q.negative, True), Literal(Q.positive_infinite, True))),
|
70 |
+
frozenset((Literal(Q.negative, True), Literal(Q.zero, True))),
|
71 |
+
frozenset((Literal(Q.negative_infinite, True), Literal(Q.positive, True))),
|
72 |
+
frozenset((Literal(Q.negative_infinite, True), Literal(Q.positive_infinite, True))),
|
73 |
+
frozenset((Literal(Q.negative_infinite, True), Literal(Q.zero, True))),
|
74 |
+
frozenset((Literal(Q.normal, False), Literal(Q.unitary, True))),
|
75 |
+
frozenset((Literal(Q.normal, True), Literal(Q.square, False))),
|
76 |
+
frozenset((Literal(Q.odd, True), Literal(Q.rational, False))),
|
77 |
+
frozenset((Literal(Q.orthogonal, False), Literal(Q.real_elements, True), Literal(Q.unitary, True))),
|
78 |
+
frozenset((Literal(Q.orthogonal, True), Literal(Q.positive_definite, False))),
|
79 |
+
frozenset((Literal(Q.orthogonal, True), Literal(Q.unitary, False))),
|
80 |
+
frozenset((Literal(Q.positive, False), Literal(Q.prime, True))),
|
81 |
+
frozenset((Literal(Q.positive, True), Literal(Q.positive_infinite, True))),
|
82 |
+
frozenset((Literal(Q.positive, True), Literal(Q.zero, True))),
|
83 |
+
frozenset((Literal(Q.positive_infinite, True), Literal(Q.zero, True))),
|
84 |
+
frozenset((Literal(Q.square, False), Literal(Q.symmetric, True))),
|
85 |
+
frozenset((Literal(Q.triangular, False), Literal(Q.unit_triangular, True))),
|
86 |
+
frozenset((Literal(Q.triangular, False), Literal(Q.upper_triangular, True)))
|
87 |
+
}
|
88 |
+
|
89 |
+
@cacheit
|
90 |
+
def get_all_known_matrix_facts():
|
91 |
+
"""
|
92 |
+
Known facts between unary predicates for matrices as CNF clauses.
|
93 |
+
"""
|
94 |
+
return {
|
95 |
+
frozenset((Literal(Q.complex_elements, False), Literal(Q.real_elements, True))),
|
96 |
+
frozenset((Literal(Q.diagonal, False), Literal(Q.lower_triangular, True), Literal(Q.upper_triangular, True))),
|
97 |
+
frozenset((Literal(Q.diagonal, True), Literal(Q.lower_triangular, False))),
|
98 |
+
frozenset((Literal(Q.diagonal, True), Literal(Q.normal, False))),
|
99 |
+
frozenset((Literal(Q.diagonal, True), Literal(Q.symmetric, False))),
|
100 |
+
frozenset((Literal(Q.diagonal, True), Literal(Q.upper_triangular, False))),
|
101 |
+
frozenset((Literal(Q.fullrank, False), Literal(Q.invertible, True))),
|
102 |
+
frozenset((Literal(Q.fullrank, True), Literal(Q.invertible, False), Literal(Q.square, True))),
|
103 |
+
frozenset((Literal(Q.integer_elements, True), Literal(Q.real_elements, False))),
|
104 |
+
frozenset((Literal(Q.invertible, False), Literal(Q.positive_definite, True))),
|
105 |
+
frozenset((Literal(Q.invertible, False), Literal(Q.singular, False))),
|
106 |
+
frozenset((Literal(Q.invertible, False), Literal(Q.unitary, True))),
|
107 |
+
frozenset((Literal(Q.invertible, True), Literal(Q.singular, True))),
|
108 |
+
frozenset((Literal(Q.invertible, True), Literal(Q.square, False))),
|
109 |
+
frozenset((Literal(Q.lower_triangular, False), Literal(Q.triangular, True), Literal(Q.upper_triangular, False))),
|
110 |
+
frozenset((Literal(Q.lower_triangular, True), Literal(Q.triangular, False))),
|
111 |
+
frozenset((Literal(Q.normal, False), Literal(Q.unitary, True))),
|
112 |
+
frozenset((Literal(Q.normal, True), Literal(Q.square, False))),
|
113 |
+
frozenset((Literal(Q.orthogonal, False), Literal(Q.real_elements, True), Literal(Q.unitary, True))),
|
114 |
+
frozenset((Literal(Q.orthogonal, True), Literal(Q.positive_definite, False))),
|
115 |
+
frozenset((Literal(Q.orthogonal, True), Literal(Q.unitary, False))),
|
116 |
+
frozenset((Literal(Q.square, False), Literal(Q.symmetric, True))),
|
117 |
+
frozenset((Literal(Q.triangular, False), Literal(Q.unit_triangular, True))),
|
118 |
+
frozenset((Literal(Q.triangular, False), Literal(Q.upper_triangular, True)))
|
119 |
+
}
|
120 |
+
|
121 |
+
@cacheit
|
122 |
+
def get_all_known_number_facts():
|
123 |
+
"""
|
124 |
+
Known facts between unary predicates for numbers as CNF clauses.
|
125 |
+
"""
|
126 |
+
return {
|
127 |
+
frozenset((Literal(Q.algebraic, False), Literal(Q.imaginary, True), Literal(Q.transcendental, False))),
|
128 |
+
frozenset((Literal(Q.algebraic, False), Literal(Q.negative, True), Literal(Q.transcendental, False))),
|
129 |
+
frozenset((Literal(Q.algebraic, False), Literal(Q.positive, True), Literal(Q.transcendental, False))),
|
130 |
+
frozenset((Literal(Q.algebraic, False), Literal(Q.rational, True))),
|
131 |
+
frozenset((Literal(Q.algebraic, False), Literal(Q.transcendental, False), Literal(Q.zero, True))),
|
132 |
+
frozenset((Literal(Q.algebraic, True), Literal(Q.finite, False))),
|
133 |
+
frozenset((Literal(Q.algebraic, True), Literal(Q.transcendental, True))),
|
134 |
+
frozenset((Literal(Q.antihermitian, False), Literal(Q.hermitian, False), Literal(Q.zero, True))),
|
135 |
+
frozenset((Literal(Q.antihermitian, False), Literal(Q.imaginary, True))),
|
136 |
+
frozenset((Literal(Q.commutative, False), Literal(Q.finite, True))),
|
137 |
+
frozenset((Literal(Q.commutative, False), Literal(Q.infinite, True))),
|
138 |
+
frozenset((Literal(Q.composite, False), Literal(Q.even, True), Literal(Q.positive, True), Literal(Q.prime, False))),
|
139 |
+
frozenset((Literal(Q.composite, True), Literal(Q.even, False), Literal(Q.odd, False))),
|
140 |
+
frozenset((Literal(Q.composite, True), Literal(Q.positive, False))),
|
141 |
+
frozenset((Literal(Q.composite, True), Literal(Q.prime, True))),
|
142 |
+
frozenset((Literal(Q.even, False), Literal(Q.odd, False), Literal(Q.prime, True))),
|
143 |
+
frozenset((Literal(Q.even, False), Literal(Q.zero, True))),
|
144 |
+
frozenset((Literal(Q.even, True), Literal(Q.odd, True))),
|
145 |
+
frozenset((Literal(Q.even, True), Literal(Q.rational, False))),
|
146 |
+
frozenset((Literal(Q.finite, False), Literal(Q.transcendental, True))),
|
147 |
+
frozenset((Literal(Q.finite, True), Literal(Q.infinite, True))),
|
148 |
+
frozenset((Literal(Q.hermitian, False), Literal(Q.negative, True))),
|
149 |
+
frozenset((Literal(Q.hermitian, False), Literal(Q.positive, True))),
|
150 |
+
frozenset((Literal(Q.hermitian, False), Literal(Q.zero, True))),
|
151 |
+
frozenset((Literal(Q.imaginary, True), Literal(Q.negative, True))),
|
152 |
+
frozenset((Literal(Q.imaginary, True), Literal(Q.positive, True))),
|
153 |
+
frozenset((Literal(Q.imaginary, True), Literal(Q.zero, True))),
|
154 |
+
frozenset((Literal(Q.infinite, False), Literal(Q.negative_infinite, True))),
|
155 |
+
frozenset((Literal(Q.infinite, False), Literal(Q.positive_infinite, True))),
|
156 |
+
frozenset((Literal(Q.irrational, False), Literal(Q.negative, True), Literal(Q.rational, False))),
|
157 |
+
frozenset((Literal(Q.irrational, False), Literal(Q.positive, True), Literal(Q.rational, False))),
|
158 |
+
frozenset((Literal(Q.irrational, False), Literal(Q.rational, False), Literal(Q.zero, True))),
|
159 |
+
frozenset((Literal(Q.irrational, True), Literal(Q.negative, False), Literal(Q.positive, False), Literal(Q.zero, False))),
|
160 |
+
frozenset((Literal(Q.irrational, True), Literal(Q.rational, True))),
|
161 |
+
frozenset((Literal(Q.negative, False), Literal(Q.positive, False), Literal(Q.rational, True), Literal(Q.zero, False))),
|
162 |
+
frozenset((Literal(Q.negative, True), Literal(Q.negative_infinite, True))),
|
163 |
+
frozenset((Literal(Q.negative, True), Literal(Q.positive, True))),
|
164 |
+
frozenset((Literal(Q.negative, True), Literal(Q.positive_infinite, True))),
|
165 |
+
frozenset((Literal(Q.negative, True), Literal(Q.zero, True))),
|
166 |
+
frozenset((Literal(Q.negative_infinite, True), Literal(Q.positive, True))),
|
167 |
+
frozenset((Literal(Q.negative_infinite, True), Literal(Q.positive_infinite, True))),
|
168 |
+
frozenset((Literal(Q.negative_infinite, True), Literal(Q.zero, True))),
|
169 |
+
frozenset((Literal(Q.odd, True), Literal(Q.rational, False))),
|
170 |
+
frozenset((Literal(Q.positive, False), Literal(Q.prime, True))),
|
171 |
+
frozenset((Literal(Q.positive, True), Literal(Q.positive_infinite, True))),
|
172 |
+
frozenset((Literal(Q.positive, True), Literal(Q.zero, True))),
|
173 |
+
frozenset((Literal(Q.positive_infinite, True), Literal(Q.zero, True)))
|
174 |
+
}
|
175 |
+
|
176 |
+
@cacheit
|
177 |
+
def get_known_facts_dict():
|
178 |
+
"""
|
179 |
+
Logical relations between unary predicates as dictionary.
|
180 |
+
|
181 |
+
Each key is a predicate, and item is two groups of predicates.
|
182 |
+
First group contains the predicates which are implied by the key, and
|
183 |
+
second group contains the predicates which are rejected by the key.
|
184 |
+
|
185 |
+
"""
|
186 |
+
return {
|
187 |
+
Q.algebraic: (set([Q.algebraic, Q.commutative, Q.complex, Q.finite]),
|
188 |
+
set([Q.infinite, Q.negative_infinite, Q.positive_infinite,
|
189 |
+
Q.transcendental])),
|
190 |
+
Q.antihermitian: (set([Q.antihermitian]), set([])),
|
191 |
+
Q.commutative: (set([Q.commutative]), set([])),
|
192 |
+
Q.complex: (set([Q.commutative, Q.complex, Q.finite]),
|
193 |
+
set([Q.infinite, Q.negative_infinite, Q.positive_infinite])),
|
194 |
+
Q.complex_elements: (set([Q.complex_elements]), set([])),
|
195 |
+
Q.composite: (set([Q.algebraic, Q.commutative, Q.complex, Q.composite,
|
196 |
+
Q.extended_nonnegative, Q.extended_nonzero,
|
197 |
+
Q.extended_positive, Q.extended_real, Q.finite, Q.hermitian,
|
198 |
+
Q.integer, Q.nonnegative, Q.nonzero, Q.positive, Q.rational,
|
199 |
+
Q.real]), set([Q.extended_negative, Q.extended_nonpositive,
|
200 |
+
Q.imaginary, Q.infinite, Q.irrational, Q.negative,
|
201 |
+
Q.negative_infinite, Q.nonpositive, Q.positive_infinite,
|
202 |
+
Q.prime, Q.transcendental, Q.zero])),
|
203 |
+
Q.diagonal: (set([Q.diagonal, Q.lower_triangular, Q.normal, Q.square,
|
204 |
+
Q.symmetric, Q.triangular, Q.upper_triangular]), set([])),
|
205 |
+
Q.even: (set([Q.algebraic, Q.commutative, Q.complex, Q.even,
|
206 |
+
Q.extended_real, Q.finite, Q.hermitian, Q.integer, Q.rational,
|
207 |
+
Q.real]), set([Q.imaginary, Q.infinite, Q.irrational,
|
208 |
+
Q.negative_infinite, Q.odd, Q.positive_infinite,
|
209 |
+
Q.transcendental])),
|
210 |
+
Q.extended_negative: (set([Q.commutative, Q.extended_negative,
|
211 |
+
Q.extended_nonpositive, Q.extended_nonzero, Q.extended_real]),
|
212 |
+
set([Q.composite, Q.extended_nonnegative, Q.extended_positive,
|
213 |
+
Q.imaginary, Q.nonnegative, Q.positive, Q.positive_infinite,
|
214 |
+
Q.prime, Q.zero])),
|
215 |
+
Q.extended_nonnegative: (set([Q.commutative, Q.extended_nonnegative,
|
216 |
+
Q.extended_real]), set([Q.extended_negative, Q.imaginary,
|
217 |
+
Q.negative, Q.negative_infinite])),
|
218 |
+
Q.extended_nonpositive: (set([Q.commutative, Q.extended_nonpositive,
|
219 |
+
Q.extended_real]), set([Q.composite, Q.extended_positive,
|
220 |
+
Q.imaginary, Q.positive, Q.positive_infinite, Q.prime])),
|
221 |
+
Q.extended_nonzero: (set([Q.commutative, Q.extended_nonzero,
|
222 |
+
Q.extended_real]), set([Q.imaginary, Q.zero])),
|
223 |
+
Q.extended_positive: (set([Q.commutative, Q.extended_nonnegative,
|
224 |
+
Q.extended_nonzero, Q.extended_positive, Q.extended_real]),
|
225 |
+
set([Q.extended_negative, Q.extended_nonpositive, Q.imaginary,
|
226 |
+
Q.negative, Q.negative_infinite, Q.nonpositive, Q.zero])),
|
227 |
+
Q.extended_real: (set([Q.commutative, Q.extended_real]),
|
228 |
+
set([Q.imaginary])),
|
229 |
+
Q.finite: (set([Q.commutative, Q.finite]), set([Q.infinite,
|
230 |
+
Q.negative_infinite, Q.positive_infinite])),
|
231 |
+
Q.fullrank: (set([Q.fullrank]), set([])),
|
232 |
+
Q.hermitian: (set([Q.hermitian]), set([])),
|
233 |
+
Q.imaginary: (set([Q.antihermitian, Q.commutative, Q.complex,
|
234 |
+
Q.finite, Q.imaginary]), set([Q.composite, Q.even,
|
235 |
+
Q.extended_negative, Q.extended_nonnegative,
|
236 |
+
Q.extended_nonpositive, Q.extended_nonzero,
|
237 |
+
Q.extended_positive, Q.extended_real, Q.infinite, Q.integer,
|
238 |
+
Q.irrational, Q.negative, Q.negative_infinite, Q.nonnegative,
|
239 |
+
Q.nonpositive, Q.nonzero, Q.odd, Q.positive,
|
240 |
+
Q.positive_infinite, Q.prime, Q.rational, Q.real, Q.zero])),
|
241 |
+
Q.infinite: (set([Q.commutative, Q.infinite]), set([Q.algebraic,
|
242 |
+
Q.complex, Q.composite, Q.even, Q.finite, Q.imaginary,
|
243 |
+
Q.integer, Q.irrational, Q.negative, Q.nonnegative,
|
244 |
+
Q.nonpositive, Q.nonzero, Q.odd, Q.positive, Q.prime,
|
245 |
+
Q.rational, Q.real, Q.transcendental, Q.zero])),
|
246 |
+
Q.integer: (set([Q.algebraic, Q.commutative, Q.complex,
|
247 |
+
Q.extended_real, Q.finite, Q.hermitian, Q.integer, Q.rational,
|
248 |
+
Q.real]), set([Q.imaginary, Q.infinite, Q.irrational,
|
249 |
+
Q.negative_infinite, Q.positive_infinite, Q.transcendental])),
|
250 |
+
Q.integer_elements: (set([Q.complex_elements, Q.integer_elements,
|
251 |
+
Q.real_elements]), set([])),
|
252 |
+
Q.invertible: (set([Q.fullrank, Q.invertible, Q.square]),
|
253 |
+
set([Q.singular])),
|
254 |
+
Q.irrational: (set([Q.commutative, Q.complex, Q.extended_nonzero,
|
255 |
+
Q.extended_real, Q.finite, Q.hermitian, Q.irrational,
|
256 |
+
Q.nonzero, Q.real]), set([Q.composite, Q.even, Q.imaginary,
|
257 |
+
Q.infinite, Q.integer, Q.negative_infinite, Q.odd,
|
258 |
+
Q.positive_infinite, Q.prime, Q.rational, Q.zero])),
|
259 |
+
Q.is_true: (set([Q.is_true]), set([])),
|
260 |
+
Q.lower_triangular: (set([Q.lower_triangular, Q.triangular]), set([])),
|
261 |
+
Q.negative: (set([Q.commutative, Q.complex, Q.extended_negative,
|
262 |
+
Q.extended_nonpositive, Q.extended_nonzero, Q.extended_real,
|
263 |
+
Q.finite, Q.hermitian, Q.negative, Q.nonpositive, Q.nonzero,
|
264 |
+
Q.real]), set([Q.composite, Q.extended_nonnegative,
|
265 |
+
Q.extended_positive, Q.imaginary, Q.infinite,
|
266 |
+
Q.negative_infinite, Q.nonnegative, Q.positive,
|
267 |
+
Q.positive_infinite, Q.prime, Q.zero])),
|
268 |
+
Q.negative_infinite: (set([Q.commutative, Q.extended_negative,
|
269 |
+
Q.extended_nonpositive, Q.extended_nonzero, Q.extended_real,
|
270 |
+
Q.infinite, Q.negative_infinite]), set([Q.algebraic,
|
271 |
+
Q.complex, Q.composite, Q.even, Q.extended_nonnegative,
|
272 |
+
Q.extended_positive, Q.finite, Q.imaginary, Q.integer,
|
273 |
+
Q.irrational, Q.negative, Q.nonnegative, Q.nonpositive,
|
274 |
+
Q.nonzero, Q.odd, Q.positive, Q.positive_infinite, Q.prime,
|
275 |
+
Q.rational, Q.real, Q.transcendental, Q.zero])),
|
276 |
+
Q.noninteger: (set([Q.noninteger]), set([])),
|
277 |
+
Q.nonnegative: (set([Q.commutative, Q.complex, Q.extended_nonnegative,
|
278 |
+
Q.extended_real, Q.finite, Q.hermitian, Q.nonnegative,
|
279 |
+
Q.real]), set([Q.extended_negative, Q.imaginary, Q.infinite,
|
280 |
+
Q.negative, Q.negative_infinite, Q.positive_infinite])),
|
281 |
+
Q.nonpositive: (set([Q.commutative, Q.complex, Q.extended_nonpositive,
|
282 |
+
Q.extended_real, Q.finite, Q.hermitian, Q.nonpositive,
|
283 |
+
Q.real]), set([Q.composite, Q.extended_positive, Q.imaginary,
|
284 |
+
Q.infinite, Q.negative_infinite, Q.positive,
|
285 |
+
Q.positive_infinite, Q.prime])),
|
286 |
+
Q.nonzero: (set([Q.commutative, Q.complex, Q.extended_nonzero,
|
287 |
+
Q.extended_real, Q.finite, Q.hermitian, Q.nonzero, Q.real]),
|
288 |
+
set([Q.imaginary, Q.infinite, Q.negative_infinite,
|
289 |
+
Q.positive_infinite, Q.zero])),
|
290 |
+
Q.normal: (set([Q.normal, Q.square]), set([])),
|
291 |
+
Q.odd: (set([Q.algebraic, Q.commutative, Q.complex,
|
292 |
+
Q.extended_nonzero, Q.extended_real, Q.finite, Q.hermitian,
|
293 |
+
Q.integer, Q.nonzero, Q.odd, Q.rational, Q.real]),
|
294 |
+
set([Q.even, Q.imaginary, Q.infinite, Q.irrational,
|
295 |
+
Q.negative_infinite, Q.positive_infinite, Q.transcendental,
|
296 |
+
Q.zero])),
|
297 |
+
Q.orthogonal: (set([Q.fullrank, Q.invertible, Q.normal, Q.orthogonal,
|
298 |
+
Q.positive_definite, Q.square, Q.unitary]), set([Q.singular])),
|
299 |
+
Q.positive: (set([Q.commutative, Q.complex, Q.extended_nonnegative,
|
300 |
+
Q.extended_nonzero, Q.extended_positive, Q.extended_real,
|
301 |
+
Q.finite, Q.hermitian, Q.nonnegative, Q.nonzero, Q.positive,
|
302 |
+
Q.real]), set([Q.extended_negative, Q.extended_nonpositive,
|
303 |
+
Q.imaginary, Q.infinite, Q.negative, Q.negative_infinite,
|
304 |
+
Q.nonpositive, Q.positive_infinite, Q.zero])),
|
305 |
+
Q.positive_definite: (set([Q.fullrank, Q.invertible,
|
306 |
+
Q.positive_definite, Q.square]), set([Q.singular])),
|
307 |
+
Q.positive_infinite: (set([Q.commutative, Q.extended_nonnegative,
|
308 |
+
Q.extended_nonzero, Q.extended_positive, Q.extended_real,
|
309 |
+
Q.infinite, Q.positive_infinite]), set([Q.algebraic,
|
310 |
+
Q.complex, Q.composite, Q.even, Q.extended_negative,
|
311 |
+
Q.extended_nonpositive, Q.finite, Q.imaginary, Q.integer,
|
312 |
+
Q.irrational, Q.negative, Q.negative_infinite, Q.nonnegative,
|
313 |
+
Q.nonpositive, Q.nonzero, Q.odd, Q.positive, Q.prime,
|
314 |
+
Q.rational, Q.real, Q.transcendental, Q.zero])),
|
315 |
+
Q.prime: (set([Q.algebraic, Q.commutative, Q.complex,
|
316 |
+
Q.extended_nonnegative, Q.extended_nonzero,
|
317 |
+
Q.extended_positive, Q.extended_real, Q.finite, Q.hermitian,
|
318 |
+
Q.integer, Q.nonnegative, Q.nonzero, Q.positive, Q.prime,
|
319 |
+
Q.rational, Q.real]), set([Q.composite, Q.extended_negative,
|
320 |
+
Q.extended_nonpositive, Q.imaginary, Q.infinite, Q.irrational,
|
321 |
+
Q.negative, Q.negative_infinite, Q.nonpositive,
|
322 |
+
Q.positive_infinite, Q.transcendental, Q.zero])),
|
323 |
+
Q.rational: (set([Q.algebraic, Q.commutative, Q.complex,
|
324 |
+
Q.extended_real, Q.finite, Q.hermitian, Q.rational, Q.real]),
|
325 |
+
set([Q.imaginary, Q.infinite, Q.irrational,
|
326 |
+
Q.negative_infinite, Q.positive_infinite, Q.transcendental])),
|
327 |
+
Q.real: (set([Q.commutative, Q.complex, Q.extended_real, Q.finite,
|
328 |
+
Q.hermitian, Q.real]), set([Q.imaginary, Q.infinite,
|
329 |
+
Q.negative_infinite, Q.positive_infinite])),
|
330 |
+
Q.real_elements: (set([Q.complex_elements, Q.real_elements]), set([])),
|
331 |
+
Q.singular: (set([Q.singular]), set([Q.invertible, Q.orthogonal,
|
332 |
+
Q.positive_definite, Q.unitary])),
|
333 |
+
Q.square: (set([Q.square]), set([])),
|
334 |
+
Q.symmetric: (set([Q.square, Q.symmetric]), set([])),
|
335 |
+
Q.transcendental: (set([Q.commutative, Q.complex, Q.finite,
|
336 |
+
Q.transcendental]), set([Q.algebraic, Q.composite, Q.even,
|
337 |
+
Q.infinite, Q.integer, Q.negative_infinite, Q.odd,
|
338 |
+
Q.positive_infinite, Q.prime, Q.rational, Q.zero])),
|
339 |
+
Q.triangular: (set([Q.triangular]), set([])),
|
340 |
+
Q.unit_triangular: (set([Q.triangular, Q.unit_triangular]), set([])),
|
341 |
+
Q.unitary: (set([Q.fullrank, Q.invertible, Q.normal, Q.square,
|
342 |
+
Q.unitary]), set([Q.singular])),
|
343 |
+
Q.upper_triangular: (set([Q.triangular, Q.upper_triangular]), set([])),
|
344 |
+
Q.zero: (set([Q.algebraic, Q.commutative, Q.complex, Q.even,
|
345 |
+
Q.extended_nonnegative, Q.extended_nonpositive,
|
346 |
+
Q.extended_real, Q.finite, Q.hermitian, Q.integer,
|
347 |
+
Q.nonnegative, Q.nonpositive, Q.rational, Q.real, Q.zero]),
|
348 |
+
set([Q.composite, Q.extended_negative, Q.extended_nonzero,
|
349 |
+
Q.extended_positive, Q.imaginary, Q.infinite, Q.irrational,
|
350 |
+
Q.negative, Q.negative_infinite, Q.nonzero, Q.odd, Q.positive,
|
351 |
+
Q.positive_infinite, Q.prime, Q.transcendental])),
|
352 |
+
}
|
MLPY/Lib/site-packages/sympy/assumptions/assume.py
ADDED
@@ -0,0 +1,485 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""A module which implements predicates and assumption context."""
|
2 |
+
|
3 |
+
from contextlib import contextmanager
|
4 |
+
import inspect
|
5 |
+
from sympy.core.symbol import Str
|
6 |
+
from sympy.core.sympify import _sympify
|
7 |
+
from sympy.logic.boolalg import Boolean, false, true
|
8 |
+
from sympy.multipledispatch.dispatcher import Dispatcher, str_signature
|
9 |
+
from sympy.utilities.exceptions import sympy_deprecation_warning
|
10 |
+
from sympy.utilities.iterables import is_sequence
|
11 |
+
from sympy.utilities.source import get_class
|
12 |
+
|
13 |
+
|
14 |
+
class AssumptionsContext(set):
|
15 |
+
"""
|
16 |
+
Set containing default assumptions which are applied to the ``ask()``
|
17 |
+
function.
|
18 |
+
|
19 |
+
Explanation
|
20 |
+
===========
|
21 |
+
|
22 |
+
This is used to represent global assumptions, but you can also use this
|
23 |
+
class to create your own local assumptions contexts. It is basically a thin
|
24 |
+
wrapper to Python's set, so see its documentation for advanced usage.
|
25 |
+
|
26 |
+
Examples
|
27 |
+
========
|
28 |
+
|
29 |
+
The default assumption context is ``global_assumptions``, which is initially empty:
|
30 |
+
|
31 |
+
>>> from sympy import ask, Q
|
32 |
+
>>> from sympy.assumptions import global_assumptions
|
33 |
+
>>> global_assumptions
|
34 |
+
AssumptionsContext()
|
35 |
+
|
36 |
+
You can add default assumptions:
|
37 |
+
|
38 |
+
>>> from sympy.abc import x
|
39 |
+
>>> global_assumptions.add(Q.real(x))
|
40 |
+
>>> global_assumptions
|
41 |
+
AssumptionsContext({Q.real(x)})
|
42 |
+
>>> ask(Q.real(x))
|
43 |
+
True
|
44 |
+
|
45 |
+
And remove them:
|
46 |
+
|
47 |
+
>>> global_assumptions.remove(Q.real(x))
|
48 |
+
>>> print(ask(Q.real(x)))
|
49 |
+
None
|
50 |
+
|
51 |
+
The ``clear()`` method removes every assumption:
|
52 |
+
|
53 |
+
>>> global_assumptions.add(Q.positive(x))
|
54 |
+
>>> global_assumptions
|
55 |
+
AssumptionsContext({Q.positive(x)})
|
56 |
+
>>> global_assumptions.clear()
|
57 |
+
>>> global_assumptions
|
58 |
+
AssumptionsContext()
|
59 |
+
|
60 |
+
See Also
|
61 |
+
========
|
62 |
+
|
63 |
+
assuming
|
64 |
+
|
65 |
+
"""
|
66 |
+
|
67 |
+
def add(self, *assumptions):
|
68 |
+
"""Add assumptions."""
|
69 |
+
for a in assumptions:
|
70 |
+
super().add(a)
|
71 |
+
|
72 |
+
def _sympystr(self, printer):
|
73 |
+
if not self:
|
74 |
+
return "%s()" % self.__class__.__name__
|
75 |
+
return "{}({})".format(self.__class__.__name__, printer._print_set(self))
|
76 |
+
|
77 |
+
global_assumptions = AssumptionsContext()
|
78 |
+
|
79 |
+
|
80 |
+
class AppliedPredicate(Boolean):
|
81 |
+
"""
|
82 |
+
The class of expressions resulting from applying ``Predicate`` to
|
83 |
+
the arguments. ``AppliedPredicate`` merely wraps its argument and
|
84 |
+
remain unevaluated. To evaluate it, use the ``ask()`` function.
|
85 |
+
|
86 |
+
Examples
|
87 |
+
========
|
88 |
+
|
89 |
+
>>> from sympy import Q, ask
|
90 |
+
>>> Q.integer(1)
|
91 |
+
Q.integer(1)
|
92 |
+
|
93 |
+
The ``function`` attribute returns the predicate, and the ``arguments``
|
94 |
+
attribute returns the tuple of arguments.
|
95 |
+
|
96 |
+
>>> type(Q.integer(1))
|
97 |
+
<class 'sympy.assumptions.assume.AppliedPredicate'>
|
98 |
+
>>> Q.integer(1).function
|
99 |
+
Q.integer
|
100 |
+
>>> Q.integer(1).arguments
|
101 |
+
(1,)
|
102 |
+
|
103 |
+
Applied predicates can be evaluated to a boolean value with ``ask``:
|
104 |
+
|
105 |
+
>>> ask(Q.integer(1))
|
106 |
+
True
|
107 |
+
|
108 |
+
"""
|
109 |
+
__slots__ = ()
|
110 |
+
|
111 |
+
def __new__(cls, predicate, *args):
|
112 |
+
if not isinstance(predicate, Predicate):
|
113 |
+
raise TypeError("%s is not a Predicate." % predicate)
|
114 |
+
args = map(_sympify, args)
|
115 |
+
return super().__new__(cls, predicate, *args)
|
116 |
+
|
117 |
+
@property
|
118 |
+
def arg(self):
|
119 |
+
"""
|
120 |
+
Return the expression used by this assumption.
|
121 |
+
|
122 |
+
Examples
|
123 |
+
========
|
124 |
+
|
125 |
+
>>> from sympy import Q, Symbol
|
126 |
+
>>> x = Symbol('x')
|
127 |
+
>>> a = Q.integer(x + 1)
|
128 |
+
>>> a.arg
|
129 |
+
x + 1
|
130 |
+
|
131 |
+
"""
|
132 |
+
# Will be deprecated
|
133 |
+
args = self._args
|
134 |
+
if len(args) == 2:
|
135 |
+
# backwards compatibility
|
136 |
+
return args[1]
|
137 |
+
raise TypeError("'arg' property is allowed only for unary predicates.")
|
138 |
+
|
139 |
+
@property
|
140 |
+
def function(self):
|
141 |
+
"""
|
142 |
+
Return the predicate.
|
143 |
+
"""
|
144 |
+
# Will be changed to self.args[0] after args overriding is removed
|
145 |
+
return self._args[0]
|
146 |
+
|
147 |
+
@property
|
148 |
+
def arguments(self):
|
149 |
+
"""
|
150 |
+
Return the arguments which are applied to the predicate.
|
151 |
+
"""
|
152 |
+
# Will be changed to self.args[1:] after args overriding is removed
|
153 |
+
return self._args[1:]
|
154 |
+
|
155 |
+
def _eval_ask(self, assumptions):
|
156 |
+
return self.function.eval(self.arguments, assumptions)
|
157 |
+
|
158 |
+
@property
|
159 |
+
def binary_symbols(self):
|
160 |
+
from .ask import Q
|
161 |
+
if self.function == Q.is_true:
|
162 |
+
i = self.arguments[0]
|
163 |
+
if i.is_Boolean or i.is_Symbol:
|
164 |
+
return i.binary_symbols
|
165 |
+
if self.function in (Q.eq, Q.ne):
|
166 |
+
if true in self.arguments or false in self.arguments:
|
167 |
+
if self.arguments[0].is_Symbol:
|
168 |
+
return {self.arguments[0]}
|
169 |
+
elif self.arguments[1].is_Symbol:
|
170 |
+
return {self.arguments[1]}
|
171 |
+
return set()
|
172 |
+
|
173 |
+
|
174 |
+
class PredicateMeta(type):
|
175 |
+
def __new__(cls, clsname, bases, dct):
|
176 |
+
# If handler is not defined, assign empty dispatcher.
|
177 |
+
if "handler" not in dct:
|
178 |
+
name = f"Ask{clsname.capitalize()}Handler"
|
179 |
+
handler = Dispatcher(name, doc="Handler for key %s" % name)
|
180 |
+
dct["handler"] = handler
|
181 |
+
|
182 |
+
dct["_orig_doc"] = dct.get("__doc__", "")
|
183 |
+
|
184 |
+
return super().__new__(cls, clsname, bases, dct)
|
185 |
+
|
186 |
+
@property
|
187 |
+
def __doc__(cls):
|
188 |
+
handler = cls.handler
|
189 |
+
doc = cls._orig_doc
|
190 |
+
if cls is not Predicate and handler is not None:
|
191 |
+
doc += "Handler\n"
|
192 |
+
doc += " =======\n\n"
|
193 |
+
|
194 |
+
# Append the handler's doc without breaking sphinx documentation.
|
195 |
+
docs = [" Multiply dispatched method: %s" % handler.name]
|
196 |
+
if handler.doc:
|
197 |
+
for line in handler.doc.splitlines():
|
198 |
+
if not line:
|
199 |
+
continue
|
200 |
+
docs.append(" %s" % line)
|
201 |
+
other = []
|
202 |
+
for sig in handler.ordering[::-1]:
|
203 |
+
func = handler.funcs[sig]
|
204 |
+
if func.__doc__:
|
205 |
+
s = ' Inputs: <%s>' % str_signature(sig)
|
206 |
+
lines = []
|
207 |
+
for line in func.__doc__.splitlines():
|
208 |
+
lines.append(" %s" % line)
|
209 |
+
s += "\n".join(lines)
|
210 |
+
docs.append(s)
|
211 |
+
else:
|
212 |
+
other.append(str_signature(sig))
|
213 |
+
if other:
|
214 |
+
othersig = " Other signatures:"
|
215 |
+
for line in other:
|
216 |
+
othersig += "\n * %s" % line
|
217 |
+
docs.append(othersig)
|
218 |
+
|
219 |
+
doc += '\n\n'.join(docs)
|
220 |
+
|
221 |
+
return doc
|
222 |
+
|
223 |
+
|
224 |
+
class Predicate(Boolean, metaclass=PredicateMeta):
|
225 |
+
"""
|
226 |
+
Base class for mathematical predicates. It also serves as a
|
227 |
+
constructor for undefined predicate objects.
|
228 |
+
|
229 |
+
Explanation
|
230 |
+
===========
|
231 |
+
|
232 |
+
Predicate is a function that returns a boolean value [1].
|
233 |
+
|
234 |
+
Predicate function is object, and it is instance of predicate class.
|
235 |
+
When a predicate is applied to arguments, ``AppliedPredicate``
|
236 |
+
instance is returned. This merely wraps the argument and remain
|
237 |
+
unevaluated. To obtain the truth value of applied predicate, use the
|
238 |
+
function ``ask``.
|
239 |
+
|
240 |
+
Evaluation of predicate is done by multiple dispatching. You can
|
241 |
+
register new handler to the predicate to support new types.
|
242 |
+
|
243 |
+
Every predicate in SymPy can be accessed via the property of ``Q``.
|
244 |
+
For example, ``Q.even`` returns the predicate which checks if the
|
245 |
+
argument is even number.
|
246 |
+
|
247 |
+
To define a predicate which can be evaluated, you must subclass this
|
248 |
+
class, make an instance of it, and register it to ``Q``. After then,
|
249 |
+
dispatch the handler by argument types.
|
250 |
+
|
251 |
+
If you directly construct predicate using this class, you will get
|
252 |
+
``UndefinedPredicate`` which cannot be dispatched. This is useful
|
253 |
+
when you are building boolean expressions which do not need to be
|
254 |
+
evaluated.
|
255 |
+
|
256 |
+
Examples
|
257 |
+
========
|
258 |
+
|
259 |
+
Applying and evaluating to boolean value:
|
260 |
+
|
261 |
+
>>> from sympy import Q, ask
|
262 |
+
>>> ask(Q.prime(7))
|
263 |
+
True
|
264 |
+
|
265 |
+
You can define a new predicate by subclassing and dispatching. Here,
|
266 |
+
we define a predicate for sexy primes [2] as an example.
|
267 |
+
|
268 |
+
>>> from sympy import Predicate, Integer
|
269 |
+
>>> class SexyPrimePredicate(Predicate):
|
270 |
+
... name = "sexyprime"
|
271 |
+
>>> Q.sexyprime = SexyPrimePredicate()
|
272 |
+
>>> @Q.sexyprime.register(Integer, Integer)
|
273 |
+
... def _(int1, int2, assumptions):
|
274 |
+
... args = sorted([int1, int2])
|
275 |
+
... if not all(ask(Q.prime(a), assumptions) for a in args):
|
276 |
+
... return False
|
277 |
+
... return args[1] - args[0] == 6
|
278 |
+
>>> ask(Q.sexyprime(5, 11))
|
279 |
+
True
|
280 |
+
|
281 |
+
Direct constructing returns ``UndefinedPredicate``, which can be
|
282 |
+
applied but cannot be dispatched.
|
283 |
+
|
284 |
+
>>> from sympy import Predicate, Integer
|
285 |
+
>>> Q.P = Predicate("P")
|
286 |
+
>>> type(Q.P)
|
287 |
+
<class 'sympy.assumptions.assume.UndefinedPredicate'>
|
288 |
+
>>> Q.P(1)
|
289 |
+
Q.P(1)
|
290 |
+
>>> Q.P.register(Integer)(lambda expr, assump: True)
|
291 |
+
Traceback (most recent call last):
|
292 |
+
...
|
293 |
+
TypeError: <class 'sympy.assumptions.assume.UndefinedPredicate'> cannot be dispatched.
|
294 |
+
|
295 |
+
References
|
296 |
+
==========
|
297 |
+
|
298 |
+
.. [1] https://en.wikipedia.org/wiki/Predicate_%28mathematical_logic%29
|
299 |
+
.. [2] https://en.wikipedia.org/wiki/Sexy_prime
|
300 |
+
|
301 |
+
"""
|
302 |
+
|
303 |
+
is_Atom = True
|
304 |
+
|
305 |
+
def __new__(cls, *args, **kwargs):
|
306 |
+
if cls is Predicate:
|
307 |
+
return UndefinedPredicate(*args, **kwargs)
|
308 |
+
obj = super().__new__(cls, *args)
|
309 |
+
return obj
|
310 |
+
|
311 |
+
@property
|
312 |
+
def name(self):
|
313 |
+
# May be overridden
|
314 |
+
return type(self).__name__
|
315 |
+
|
316 |
+
@classmethod
|
317 |
+
def register(cls, *types, **kwargs):
|
318 |
+
"""
|
319 |
+
Register the signature to the handler.
|
320 |
+
"""
|
321 |
+
if cls.handler is None:
|
322 |
+
raise TypeError("%s cannot be dispatched." % type(cls))
|
323 |
+
return cls.handler.register(*types, **kwargs)
|
324 |
+
|
325 |
+
@classmethod
|
326 |
+
def register_many(cls, *types, **kwargs):
|
327 |
+
"""
|
328 |
+
Register multiple signatures to same handler.
|
329 |
+
"""
|
330 |
+
def _(func):
|
331 |
+
for t in types:
|
332 |
+
if not is_sequence(t):
|
333 |
+
t = (t,) # for convenience, allow passing `type` to mean `(type,)`
|
334 |
+
cls.register(*t, **kwargs)(func)
|
335 |
+
return _
|
336 |
+
|
337 |
+
def __call__(self, *args):
|
338 |
+
return AppliedPredicate(self, *args)
|
339 |
+
|
340 |
+
def eval(self, args, assumptions=True):
|
341 |
+
"""
|
342 |
+
Evaluate ``self(*args)`` under the given assumptions.
|
343 |
+
|
344 |
+
This uses only direct resolution methods, not logical inference.
|
345 |
+
"""
|
346 |
+
result = None
|
347 |
+
try:
|
348 |
+
result = self.handler(*args, assumptions=assumptions)
|
349 |
+
except NotImplementedError:
|
350 |
+
pass
|
351 |
+
return result
|
352 |
+
|
353 |
+
def _eval_refine(self, assumptions):
|
354 |
+
# When Predicate is no longer Boolean, delete this method
|
355 |
+
return self
|
356 |
+
|
357 |
+
|
358 |
+
class UndefinedPredicate(Predicate):
|
359 |
+
"""
|
360 |
+
Predicate without handler.
|
361 |
+
|
362 |
+
Explanation
|
363 |
+
===========
|
364 |
+
|
365 |
+
This predicate is generated by using ``Predicate`` directly for
|
366 |
+
construction. It does not have a handler, and evaluating this with
|
367 |
+
arguments is done by SAT solver.
|
368 |
+
|
369 |
+
Examples
|
370 |
+
========
|
371 |
+
|
372 |
+
>>> from sympy import Predicate, Q
|
373 |
+
>>> Q.P = Predicate('P')
|
374 |
+
>>> Q.P.func
|
375 |
+
<class 'sympy.assumptions.assume.UndefinedPredicate'>
|
376 |
+
>>> Q.P.name
|
377 |
+
Str('P')
|
378 |
+
|
379 |
+
"""
|
380 |
+
|
381 |
+
handler = None
|
382 |
+
|
383 |
+
def __new__(cls, name, handlers=None):
|
384 |
+
# "handlers" parameter supports old design
|
385 |
+
if not isinstance(name, Str):
|
386 |
+
name = Str(name)
|
387 |
+
obj = super(Boolean, cls).__new__(cls, name)
|
388 |
+
obj.handlers = handlers or []
|
389 |
+
return obj
|
390 |
+
|
391 |
+
@property
|
392 |
+
def name(self):
|
393 |
+
return self.args[0]
|
394 |
+
|
395 |
+
def _hashable_content(self):
|
396 |
+
return (self.name,)
|
397 |
+
|
398 |
+
def __getnewargs__(self):
|
399 |
+
return (self.name,)
|
400 |
+
|
401 |
+
def __call__(self, expr):
|
402 |
+
return AppliedPredicate(self, expr)
|
403 |
+
|
404 |
+
def add_handler(self, handler):
|
405 |
+
sympy_deprecation_warning(
|
406 |
+
"""
|
407 |
+
The AskHandler system is deprecated. Predicate.add_handler()
|
408 |
+
should be replaced with the multipledispatch handler of Predicate.
|
409 |
+
""",
|
410 |
+
deprecated_since_version="1.8",
|
411 |
+
active_deprecations_target='deprecated-askhandler',
|
412 |
+
)
|
413 |
+
self.handlers.append(handler)
|
414 |
+
|
415 |
+
def remove_handler(self, handler):
|
416 |
+
sympy_deprecation_warning(
|
417 |
+
"""
|
418 |
+
The AskHandler system is deprecated. Predicate.remove_handler()
|
419 |
+
should be replaced with the multipledispatch handler of Predicate.
|
420 |
+
""",
|
421 |
+
deprecated_since_version="1.8",
|
422 |
+
active_deprecations_target='deprecated-askhandler',
|
423 |
+
)
|
424 |
+
self.handlers.remove(handler)
|
425 |
+
|
426 |
+
def eval(self, args, assumptions=True):
|
427 |
+
# Support for deprecated design
|
428 |
+
# When old design is removed, this will always return None
|
429 |
+
sympy_deprecation_warning(
|
430 |
+
"""
|
431 |
+
The AskHandler system is deprecated. Evaluating UndefinedPredicate
|
432 |
+
objects should be replaced with the multipledispatch handler of
|
433 |
+
Predicate.
|
434 |
+
""",
|
435 |
+
deprecated_since_version="1.8",
|
436 |
+
active_deprecations_target='deprecated-askhandler',
|
437 |
+
stacklevel=5,
|
438 |
+
)
|
439 |
+
expr, = args
|
440 |
+
res, _res = None, None
|
441 |
+
mro = inspect.getmro(type(expr))
|
442 |
+
for handler in self.handlers:
|
443 |
+
cls = get_class(handler)
|
444 |
+
for subclass in mro:
|
445 |
+
eval_ = getattr(cls, subclass.__name__, None)
|
446 |
+
if eval_ is None:
|
447 |
+
continue
|
448 |
+
res = eval_(expr, assumptions)
|
449 |
+
# Do not stop if value returned is None
|
450 |
+
# Try to check for higher classes
|
451 |
+
if res is None:
|
452 |
+
continue
|
453 |
+
if _res is None:
|
454 |
+
_res = res
|
455 |
+
else:
|
456 |
+
# only check consistency if both resolutors have concluded
|
457 |
+
if _res != res:
|
458 |
+
raise ValueError('incompatible resolutors')
|
459 |
+
break
|
460 |
+
return res
|
461 |
+
|
462 |
+
|
463 |
+
@contextmanager
|
464 |
+
def assuming(*assumptions):
|
465 |
+
"""
|
466 |
+
Context manager for assumptions.
|
467 |
+
|
468 |
+
Examples
|
469 |
+
========
|
470 |
+
|
471 |
+
>>> from sympy import assuming, Q, ask
|
472 |
+
>>> from sympy.abc import x, y
|
473 |
+
>>> print(ask(Q.integer(x + y)))
|
474 |
+
None
|
475 |
+
>>> with assuming(Q.integer(x), Q.integer(y)):
|
476 |
+
... print(ask(Q.integer(x + y)))
|
477 |
+
True
|
478 |
+
"""
|
479 |
+
old_global_assumptions = global_assumptions.copy()
|
480 |
+
global_assumptions.update(assumptions)
|
481 |
+
try:
|
482 |
+
yield
|
483 |
+
finally:
|
484 |
+
global_assumptions.clear()
|
485 |
+
global_assumptions.update(old_global_assumptions)
|
MLPY/Lib/site-packages/sympy/assumptions/cnf.py
ADDED
@@ -0,0 +1,445 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
The classes used here are for the internal use of assumptions system
|
3 |
+
only and should not be used anywhere else as these do not possess the
|
4 |
+
signatures common to SymPy objects. For general use of logic constructs
|
5 |
+
please refer to sympy.logic classes And, Or, Not, etc.
|
6 |
+
"""
|
7 |
+
from itertools import combinations, product, zip_longest
|
8 |
+
from sympy.assumptions.assume import AppliedPredicate, Predicate
|
9 |
+
from sympy.core.relational import Eq, Ne, Gt, Lt, Ge, Le
|
10 |
+
from sympy.core.singleton import S
|
11 |
+
from sympy.logic.boolalg import Or, And, Not, Xnor
|
12 |
+
from sympy.logic.boolalg import (Equivalent, ITE, Implies, Nand, Nor, Xor)
|
13 |
+
|
14 |
+
|
15 |
+
class Literal:
|
16 |
+
"""
|
17 |
+
The smallest element of a CNF object.
|
18 |
+
|
19 |
+
Parameters
|
20 |
+
==========
|
21 |
+
|
22 |
+
lit : Boolean expression
|
23 |
+
|
24 |
+
is_Not : bool
|
25 |
+
|
26 |
+
Examples
|
27 |
+
========
|
28 |
+
|
29 |
+
>>> from sympy import Q
|
30 |
+
>>> from sympy.assumptions.cnf import Literal
|
31 |
+
>>> from sympy.abc import x
|
32 |
+
>>> Literal(Q.even(x))
|
33 |
+
Literal(Q.even(x), False)
|
34 |
+
>>> Literal(~Q.even(x))
|
35 |
+
Literal(Q.even(x), True)
|
36 |
+
"""
|
37 |
+
|
38 |
+
def __new__(cls, lit, is_Not=False):
|
39 |
+
if isinstance(lit, Not):
|
40 |
+
lit = lit.args[0]
|
41 |
+
is_Not = True
|
42 |
+
elif isinstance(lit, (AND, OR, Literal)):
|
43 |
+
return ~lit if is_Not else lit
|
44 |
+
obj = super().__new__(cls)
|
45 |
+
obj.lit = lit
|
46 |
+
obj.is_Not = is_Not
|
47 |
+
return obj
|
48 |
+
|
49 |
+
@property
|
50 |
+
def arg(self):
|
51 |
+
return self.lit
|
52 |
+
|
53 |
+
def rcall(self, expr):
|
54 |
+
if callable(self.lit):
|
55 |
+
lit = self.lit(expr)
|
56 |
+
else:
|
57 |
+
lit = self.lit.apply(expr)
|
58 |
+
return type(self)(lit, self.is_Not)
|
59 |
+
|
60 |
+
def __invert__(self):
|
61 |
+
is_Not = not self.is_Not
|
62 |
+
return Literal(self.lit, is_Not)
|
63 |
+
|
64 |
+
def __str__(self):
|
65 |
+
return '{}({}, {})'.format(type(self).__name__, self.lit, self.is_Not)
|
66 |
+
|
67 |
+
__repr__ = __str__
|
68 |
+
|
69 |
+
def __eq__(self, other):
|
70 |
+
return self.arg == other.arg and self.is_Not == other.is_Not
|
71 |
+
|
72 |
+
def __hash__(self):
|
73 |
+
h = hash((type(self).__name__, self.arg, self.is_Not))
|
74 |
+
return h
|
75 |
+
|
76 |
+
|
77 |
+
class OR:
|
78 |
+
"""
|
79 |
+
A low-level implementation for Or
|
80 |
+
"""
|
81 |
+
def __init__(self, *args):
|
82 |
+
self._args = args
|
83 |
+
|
84 |
+
@property
|
85 |
+
def args(self):
|
86 |
+
return sorted(self._args, key=str)
|
87 |
+
|
88 |
+
def rcall(self, expr):
|
89 |
+
return type(self)(*[arg.rcall(expr)
|
90 |
+
for arg in self._args
|
91 |
+
])
|
92 |
+
|
93 |
+
def __invert__(self):
|
94 |
+
return AND(*[~arg for arg in self._args])
|
95 |
+
|
96 |
+
def __hash__(self):
|
97 |
+
return hash((type(self).__name__,) + tuple(self.args))
|
98 |
+
|
99 |
+
def __eq__(self, other):
|
100 |
+
return self.args == other.args
|
101 |
+
|
102 |
+
def __str__(self):
|
103 |
+
s = '(' + ' | '.join([str(arg) for arg in self.args]) + ')'
|
104 |
+
return s
|
105 |
+
|
106 |
+
__repr__ = __str__
|
107 |
+
|
108 |
+
|
109 |
+
class AND:
|
110 |
+
"""
|
111 |
+
A low-level implementation for And
|
112 |
+
"""
|
113 |
+
def __init__(self, *args):
|
114 |
+
self._args = args
|
115 |
+
|
116 |
+
def __invert__(self):
|
117 |
+
return OR(*[~arg for arg in self._args])
|
118 |
+
|
119 |
+
@property
|
120 |
+
def args(self):
|
121 |
+
return sorted(self._args, key=str)
|
122 |
+
|
123 |
+
def rcall(self, expr):
|
124 |
+
return type(self)(*[arg.rcall(expr)
|
125 |
+
for arg in self._args
|
126 |
+
])
|
127 |
+
|
128 |
+
def __hash__(self):
|
129 |
+
return hash((type(self).__name__,) + tuple(self.args))
|
130 |
+
|
131 |
+
def __eq__(self, other):
|
132 |
+
return self.args == other.args
|
133 |
+
|
134 |
+
def __str__(self):
|
135 |
+
s = '('+' & '.join([str(arg) for arg in self.args])+')'
|
136 |
+
return s
|
137 |
+
|
138 |
+
__repr__ = __str__
|
139 |
+
|
140 |
+
|
141 |
+
def to_NNF(expr, composite_map=None):
|
142 |
+
"""
|
143 |
+
Generates the Negation Normal Form of any boolean expression in terms
|
144 |
+
of AND, OR, and Literal objects.
|
145 |
+
|
146 |
+
Examples
|
147 |
+
========
|
148 |
+
|
149 |
+
>>> from sympy import Q, Eq
|
150 |
+
>>> from sympy.assumptions.cnf import to_NNF
|
151 |
+
>>> from sympy.abc import x, y
|
152 |
+
>>> expr = Q.even(x) & ~Q.positive(x)
|
153 |
+
>>> to_NNF(expr)
|
154 |
+
(Literal(Q.even(x), False) & Literal(Q.positive(x), True))
|
155 |
+
|
156 |
+
Supported boolean objects are converted to corresponding predicates.
|
157 |
+
|
158 |
+
>>> to_NNF(Eq(x, y))
|
159 |
+
Literal(Q.eq(x, y), False)
|
160 |
+
|
161 |
+
If ``composite_map`` argument is given, ``to_NNF`` decomposes the
|
162 |
+
specified predicate into a combination of primitive predicates.
|
163 |
+
|
164 |
+
>>> cmap = {Q.nonpositive: Q.negative | Q.zero}
|
165 |
+
>>> to_NNF(Q.nonpositive, cmap)
|
166 |
+
(Literal(Q.negative, False) | Literal(Q.zero, False))
|
167 |
+
>>> to_NNF(Q.nonpositive(x), cmap)
|
168 |
+
(Literal(Q.negative(x), False) | Literal(Q.zero(x), False))
|
169 |
+
"""
|
170 |
+
from sympy.assumptions.ask import Q
|
171 |
+
|
172 |
+
if composite_map is None:
|
173 |
+
composite_map = {}
|
174 |
+
|
175 |
+
|
176 |
+
binrelpreds = {Eq: Q.eq, Ne: Q.ne, Gt: Q.gt, Lt: Q.lt, Ge: Q.ge, Le: Q.le}
|
177 |
+
if type(expr) in binrelpreds:
|
178 |
+
pred = binrelpreds[type(expr)]
|
179 |
+
expr = pred(*expr.args)
|
180 |
+
|
181 |
+
if isinstance(expr, Not):
|
182 |
+
arg = expr.args[0]
|
183 |
+
tmp = to_NNF(arg, composite_map) # Strategy: negate the NNF of expr
|
184 |
+
return ~tmp
|
185 |
+
|
186 |
+
if isinstance(expr, Or):
|
187 |
+
return OR(*[to_NNF(x, composite_map) for x in Or.make_args(expr)])
|
188 |
+
|
189 |
+
if isinstance(expr, And):
|
190 |
+
return AND(*[to_NNF(x, composite_map) for x in And.make_args(expr)])
|
191 |
+
|
192 |
+
if isinstance(expr, Nand):
|
193 |
+
tmp = AND(*[to_NNF(x, composite_map) for x in expr.args])
|
194 |
+
return ~tmp
|
195 |
+
|
196 |
+
if isinstance(expr, Nor):
|
197 |
+
tmp = OR(*[to_NNF(x, composite_map) for x in expr.args])
|
198 |
+
return ~tmp
|
199 |
+
|
200 |
+
if isinstance(expr, Xor):
|
201 |
+
cnfs = []
|
202 |
+
for i in range(0, len(expr.args) + 1, 2):
|
203 |
+
for neg in combinations(expr.args, i):
|
204 |
+
clause = [~to_NNF(s, composite_map) if s in neg else to_NNF(s, composite_map)
|
205 |
+
for s in expr.args]
|
206 |
+
cnfs.append(OR(*clause))
|
207 |
+
return AND(*cnfs)
|
208 |
+
|
209 |
+
if isinstance(expr, Xnor):
|
210 |
+
cnfs = []
|
211 |
+
for i in range(0, len(expr.args) + 1, 2):
|
212 |
+
for neg in combinations(expr.args, i):
|
213 |
+
clause = [~to_NNF(s, composite_map) if s in neg else to_NNF(s, composite_map)
|
214 |
+
for s in expr.args]
|
215 |
+
cnfs.append(OR(*clause))
|
216 |
+
return ~AND(*cnfs)
|
217 |
+
|
218 |
+
if isinstance(expr, Implies):
|
219 |
+
L, R = to_NNF(expr.args[0], composite_map), to_NNF(expr.args[1], composite_map)
|
220 |
+
return OR(~L, R)
|
221 |
+
|
222 |
+
if isinstance(expr, Equivalent):
|
223 |
+
cnfs = []
|
224 |
+
for a, b in zip_longest(expr.args, expr.args[1:], fillvalue=expr.args[0]):
|
225 |
+
a = to_NNF(a, composite_map)
|
226 |
+
b = to_NNF(b, composite_map)
|
227 |
+
cnfs.append(OR(~a, b))
|
228 |
+
return AND(*cnfs)
|
229 |
+
|
230 |
+
if isinstance(expr, ITE):
|
231 |
+
L = to_NNF(expr.args[0], composite_map)
|
232 |
+
M = to_NNF(expr.args[1], composite_map)
|
233 |
+
R = to_NNF(expr.args[2], composite_map)
|
234 |
+
return AND(OR(~L, M), OR(L, R))
|
235 |
+
|
236 |
+
if isinstance(expr, AppliedPredicate):
|
237 |
+
pred, args = expr.function, expr.arguments
|
238 |
+
newpred = composite_map.get(pred, None)
|
239 |
+
if newpred is not None:
|
240 |
+
return to_NNF(newpred.rcall(*args), composite_map)
|
241 |
+
|
242 |
+
if isinstance(expr, Predicate):
|
243 |
+
newpred = composite_map.get(expr, None)
|
244 |
+
if newpred is not None:
|
245 |
+
return to_NNF(newpred, composite_map)
|
246 |
+
|
247 |
+
return Literal(expr)
|
248 |
+
|
249 |
+
|
250 |
+
def distribute_AND_over_OR(expr):
|
251 |
+
"""
|
252 |
+
Distributes AND over OR in the NNF expression.
|
253 |
+
Returns the result( Conjunctive Normal Form of expression)
|
254 |
+
as a CNF object.
|
255 |
+
"""
|
256 |
+
if not isinstance(expr, (AND, OR)):
|
257 |
+
tmp = set()
|
258 |
+
tmp.add(frozenset((expr,)))
|
259 |
+
return CNF(tmp)
|
260 |
+
|
261 |
+
if isinstance(expr, OR):
|
262 |
+
return CNF.all_or(*[distribute_AND_over_OR(arg)
|
263 |
+
for arg in expr._args])
|
264 |
+
|
265 |
+
if isinstance(expr, AND):
|
266 |
+
return CNF.all_and(*[distribute_AND_over_OR(arg)
|
267 |
+
for arg in expr._args])
|
268 |
+
|
269 |
+
|
270 |
+
class CNF:
|
271 |
+
"""
|
272 |
+
Class to represent CNF of a Boolean expression.
|
273 |
+
Consists of set of clauses, which themselves are stored as
|
274 |
+
frozenset of Literal objects.
|
275 |
+
|
276 |
+
Examples
|
277 |
+
========
|
278 |
+
|
279 |
+
>>> from sympy import Q
|
280 |
+
>>> from sympy.assumptions.cnf import CNF
|
281 |
+
>>> from sympy.abc import x
|
282 |
+
>>> cnf = CNF.from_prop(Q.real(x) & ~Q.zero(x))
|
283 |
+
>>> cnf.clauses
|
284 |
+
{frozenset({Literal(Q.zero(x), True)}),
|
285 |
+
frozenset({Literal(Q.negative(x), False),
|
286 |
+
Literal(Q.positive(x), False), Literal(Q.zero(x), False)})}
|
287 |
+
"""
|
288 |
+
def __init__(self, clauses=None):
|
289 |
+
if not clauses:
|
290 |
+
clauses = set()
|
291 |
+
self.clauses = clauses
|
292 |
+
|
293 |
+
def add(self, prop):
|
294 |
+
clauses = CNF.to_CNF(prop).clauses
|
295 |
+
self.add_clauses(clauses)
|
296 |
+
|
297 |
+
def __str__(self):
|
298 |
+
s = ' & '.join(
|
299 |
+
['(' + ' | '.join([str(lit) for lit in clause]) +')'
|
300 |
+
for clause in self.clauses]
|
301 |
+
)
|
302 |
+
return s
|
303 |
+
|
304 |
+
def extend(self, props):
|
305 |
+
for p in props:
|
306 |
+
self.add(p)
|
307 |
+
return self
|
308 |
+
|
309 |
+
def copy(self):
|
310 |
+
return CNF(set(self.clauses))
|
311 |
+
|
312 |
+
def add_clauses(self, clauses):
|
313 |
+
self.clauses |= clauses
|
314 |
+
|
315 |
+
@classmethod
|
316 |
+
def from_prop(cls, prop):
|
317 |
+
res = cls()
|
318 |
+
res.add(prop)
|
319 |
+
return res
|
320 |
+
|
321 |
+
def __iand__(self, other):
|
322 |
+
self.add_clauses(other.clauses)
|
323 |
+
return self
|
324 |
+
|
325 |
+
def all_predicates(self):
|
326 |
+
predicates = set()
|
327 |
+
for c in self.clauses:
|
328 |
+
predicates |= {arg.lit for arg in c}
|
329 |
+
return predicates
|
330 |
+
|
331 |
+
def _or(self, cnf):
|
332 |
+
clauses = set()
|
333 |
+
for a, b in product(self.clauses, cnf.clauses):
|
334 |
+
tmp = set(a)
|
335 |
+
tmp.update(b)
|
336 |
+
clauses.add(frozenset(tmp))
|
337 |
+
return CNF(clauses)
|
338 |
+
|
339 |
+
def _and(self, cnf):
|
340 |
+
clauses = self.clauses.union(cnf.clauses)
|
341 |
+
return CNF(clauses)
|
342 |
+
|
343 |
+
def _not(self):
|
344 |
+
clss = list(self.clauses)
|
345 |
+
ll = {frozenset((~x,)) for x in clss[-1]}
|
346 |
+
ll = CNF(ll)
|
347 |
+
|
348 |
+
for rest in clss[:-1]:
|
349 |
+
p = {frozenset((~x,)) for x in rest}
|
350 |
+
ll = ll._or(CNF(p))
|
351 |
+
return ll
|
352 |
+
|
353 |
+
def rcall(self, expr):
|
354 |
+
clause_list = []
|
355 |
+
for clause in self.clauses:
|
356 |
+
lits = [arg.rcall(expr) for arg in clause]
|
357 |
+
clause_list.append(OR(*lits))
|
358 |
+
expr = AND(*clause_list)
|
359 |
+
return distribute_AND_over_OR(expr)
|
360 |
+
|
361 |
+
@classmethod
|
362 |
+
def all_or(cls, *cnfs):
|
363 |
+
b = cnfs[0].copy()
|
364 |
+
for rest in cnfs[1:]:
|
365 |
+
b = b._or(rest)
|
366 |
+
return b
|
367 |
+
|
368 |
+
@classmethod
|
369 |
+
def all_and(cls, *cnfs):
|
370 |
+
b = cnfs[0].copy()
|
371 |
+
for rest in cnfs[1:]:
|
372 |
+
b = b._and(rest)
|
373 |
+
return b
|
374 |
+
|
375 |
+
@classmethod
|
376 |
+
def to_CNF(cls, expr):
|
377 |
+
from sympy.assumptions.facts import get_composite_predicates
|
378 |
+
expr = to_NNF(expr, get_composite_predicates())
|
379 |
+
expr = distribute_AND_over_OR(expr)
|
380 |
+
return expr
|
381 |
+
|
382 |
+
@classmethod
|
383 |
+
def CNF_to_cnf(cls, cnf):
|
384 |
+
"""
|
385 |
+
Converts CNF object to SymPy's boolean expression
|
386 |
+
retaining the form of expression.
|
387 |
+
"""
|
388 |
+
def remove_literal(arg):
|
389 |
+
return Not(arg.lit) if arg.is_Not else arg.lit
|
390 |
+
|
391 |
+
return And(*(Or(*(remove_literal(arg) for arg in clause)) for clause in cnf.clauses))
|
392 |
+
|
393 |
+
|
394 |
+
class EncodedCNF:
|
395 |
+
"""
|
396 |
+
Class for encoding the CNF expression.
|
397 |
+
"""
|
398 |
+
def __init__(self, data=None, encoding=None):
|
399 |
+
if not data and not encoding:
|
400 |
+
data = []
|
401 |
+
encoding = {}
|
402 |
+
self.data = data
|
403 |
+
self.encoding = encoding
|
404 |
+
self._symbols = list(encoding.keys())
|
405 |
+
|
406 |
+
def from_cnf(self, cnf):
|
407 |
+
self._symbols = list(cnf.all_predicates())
|
408 |
+
n = len(self._symbols)
|
409 |
+
self.encoding = dict(zip(self._symbols, range(1, n + 1)))
|
410 |
+
self.data = [self.encode(clause) for clause in cnf.clauses]
|
411 |
+
|
412 |
+
@property
|
413 |
+
def symbols(self):
|
414 |
+
return self._symbols
|
415 |
+
|
416 |
+
@property
|
417 |
+
def variables(self):
|
418 |
+
return range(1, len(self._symbols) + 1)
|
419 |
+
|
420 |
+
def copy(self):
|
421 |
+
new_data = [set(clause) for clause in self.data]
|
422 |
+
return EncodedCNF(new_data, dict(self.encoding))
|
423 |
+
|
424 |
+
def add_prop(self, prop):
|
425 |
+
cnf = CNF.from_prop(prop)
|
426 |
+
self.add_from_cnf(cnf)
|
427 |
+
|
428 |
+
def add_from_cnf(self, cnf):
|
429 |
+
clauses = [self.encode(clause) for clause in cnf.clauses]
|
430 |
+
self.data += clauses
|
431 |
+
|
432 |
+
def encode_arg(self, arg):
|
433 |
+
literal = arg.lit
|
434 |
+
value = self.encoding.get(literal, None)
|
435 |
+
if value is None:
|
436 |
+
n = len(self._symbols)
|
437 |
+
self._symbols.append(literal)
|
438 |
+
value = self.encoding[literal] = n + 1
|
439 |
+
if arg.is_Not:
|
440 |
+
return -value
|
441 |
+
else:
|
442 |
+
return value
|
443 |
+
|
444 |
+
def encode(self, clause):
|
445 |
+
return {self.encode_arg(arg) if not arg.lit == S.false else 0 for arg in clause}
|
MLPY/Lib/site-packages/sympy/assumptions/facts.py
ADDED
@@ -0,0 +1,270 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Known facts in assumptions module.
|
3 |
+
|
4 |
+
This module defines the facts between unary predicates in ``get_known_facts()``,
|
5 |
+
and supports functions to generate the contents in
|
6 |
+
``sympy.assumptions.ask_generated`` file.
|
7 |
+
"""
|
8 |
+
|
9 |
+
from sympy.assumptions.ask import Q
|
10 |
+
from sympy.assumptions.assume import AppliedPredicate
|
11 |
+
from sympy.core.cache import cacheit
|
12 |
+
from sympy.core.symbol import Symbol
|
13 |
+
from sympy.logic.boolalg import (to_cnf, And, Not, Implies, Equivalent,
|
14 |
+
Exclusive,)
|
15 |
+
from sympy.logic.inference import satisfiable
|
16 |
+
|
17 |
+
|
18 |
+
@cacheit
|
19 |
+
def get_composite_predicates():
|
20 |
+
# To reduce the complexity of sat solver, these predicates are
|
21 |
+
# transformed into the combination of primitive predicates.
|
22 |
+
return {
|
23 |
+
Q.real : Q.negative | Q.zero | Q.positive,
|
24 |
+
Q.integer : Q.even | Q.odd,
|
25 |
+
Q.nonpositive : Q.negative | Q.zero,
|
26 |
+
Q.nonzero : Q.negative | Q.positive,
|
27 |
+
Q.nonnegative : Q.zero | Q.positive,
|
28 |
+
Q.extended_real : Q.negative_infinite | Q.negative | Q.zero | Q.positive | Q.positive_infinite,
|
29 |
+
Q.extended_positive: Q.positive | Q.positive_infinite,
|
30 |
+
Q.extended_negative: Q.negative | Q.negative_infinite,
|
31 |
+
Q.extended_nonzero: Q.negative_infinite | Q.negative | Q.positive | Q.positive_infinite,
|
32 |
+
Q.extended_nonpositive: Q.negative_infinite | Q.negative | Q.zero,
|
33 |
+
Q.extended_nonnegative: Q.zero | Q.positive | Q.positive_infinite,
|
34 |
+
Q.complex : Q.algebraic | Q.transcendental
|
35 |
+
}
|
36 |
+
|
37 |
+
|
38 |
+
@cacheit
|
39 |
+
def get_known_facts(x=None):
|
40 |
+
"""
|
41 |
+
Facts between unary predicates.
|
42 |
+
|
43 |
+
Parameters
|
44 |
+
==========
|
45 |
+
|
46 |
+
x : Symbol, optional
|
47 |
+
Placeholder symbol for unary facts. Default is ``Symbol('x')``.
|
48 |
+
|
49 |
+
Returns
|
50 |
+
=======
|
51 |
+
|
52 |
+
fact : Known facts in conjugated normal form.
|
53 |
+
|
54 |
+
"""
|
55 |
+
if x is None:
|
56 |
+
x = Symbol('x')
|
57 |
+
|
58 |
+
fact = And(
|
59 |
+
get_number_facts(x),
|
60 |
+
get_matrix_facts(x)
|
61 |
+
)
|
62 |
+
return fact
|
63 |
+
|
64 |
+
|
65 |
+
@cacheit
|
66 |
+
def get_number_facts(x = None):
|
67 |
+
"""
|
68 |
+
Facts between unary number predicates.
|
69 |
+
|
70 |
+
Parameters
|
71 |
+
==========
|
72 |
+
|
73 |
+
x : Symbol, optional
|
74 |
+
Placeholder symbol for unary facts. Default is ``Symbol('x')``.
|
75 |
+
|
76 |
+
Returns
|
77 |
+
=======
|
78 |
+
|
79 |
+
fact : Known facts in conjugated normal form.
|
80 |
+
|
81 |
+
"""
|
82 |
+
if x is None:
|
83 |
+
x = Symbol('x')
|
84 |
+
|
85 |
+
fact = And(
|
86 |
+
# primitive predicates for extended real exclude each other.
|
87 |
+
Exclusive(Q.negative_infinite(x), Q.negative(x), Q.zero(x),
|
88 |
+
Q.positive(x), Q.positive_infinite(x)),
|
89 |
+
|
90 |
+
# build complex plane
|
91 |
+
Exclusive(Q.real(x), Q.imaginary(x)),
|
92 |
+
Implies(Q.real(x) | Q.imaginary(x), Q.complex(x)),
|
93 |
+
|
94 |
+
# other subsets of complex
|
95 |
+
Exclusive(Q.transcendental(x), Q.algebraic(x)),
|
96 |
+
Equivalent(Q.real(x), Q.rational(x) | Q.irrational(x)),
|
97 |
+
Exclusive(Q.irrational(x), Q.rational(x)),
|
98 |
+
Implies(Q.rational(x), Q.algebraic(x)),
|
99 |
+
|
100 |
+
# integers
|
101 |
+
Exclusive(Q.even(x), Q.odd(x)),
|
102 |
+
Implies(Q.integer(x), Q.rational(x)),
|
103 |
+
Implies(Q.zero(x), Q.even(x)),
|
104 |
+
Exclusive(Q.composite(x), Q.prime(x)),
|
105 |
+
Implies(Q.composite(x) | Q.prime(x), Q.integer(x) & Q.positive(x)),
|
106 |
+
Implies(Q.even(x) & Q.positive(x) & ~Q.prime(x), Q.composite(x)),
|
107 |
+
|
108 |
+
# hermitian and antihermitian
|
109 |
+
Implies(Q.real(x), Q.hermitian(x)),
|
110 |
+
Implies(Q.imaginary(x), Q.antihermitian(x)),
|
111 |
+
Implies(Q.zero(x), Q.hermitian(x) | Q.antihermitian(x)),
|
112 |
+
|
113 |
+
# define finity and infinity, and build extended real line
|
114 |
+
Exclusive(Q.infinite(x), Q.finite(x)),
|
115 |
+
Implies(Q.complex(x), Q.finite(x)),
|
116 |
+
Implies(Q.negative_infinite(x) | Q.positive_infinite(x), Q.infinite(x)),
|
117 |
+
|
118 |
+
# commutativity
|
119 |
+
Implies(Q.finite(x) | Q.infinite(x), Q.commutative(x)),
|
120 |
+
)
|
121 |
+
return fact
|
122 |
+
|
123 |
+
|
124 |
+
@cacheit
|
125 |
+
def get_matrix_facts(x = None):
|
126 |
+
"""
|
127 |
+
Facts between unary matrix predicates.
|
128 |
+
|
129 |
+
Parameters
|
130 |
+
==========
|
131 |
+
|
132 |
+
x : Symbol, optional
|
133 |
+
Placeholder symbol for unary facts. Default is ``Symbol('x')``.
|
134 |
+
|
135 |
+
Returns
|
136 |
+
=======
|
137 |
+
|
138 |
+
fact : Known facts in conjugated normal form.
|
139 |
+
|
140 |
+
"""
|
141 |
+
if x is None:
|
142 |
+
x = Symbol('x')
|
143 |
+
|
144 |
+
fact = And(
|
145 |
+
# matrices
|
146 |
+
Implies(Q.orthogonal(x), Q.positive_definite(x)),
|
147 |
+
Implies(Q.orthogonal(x), Q.unitary(x)),
|
148 |
+
Implies(Q.unitary(x) & Q.real_elements(x), Q.orthogonal(x)),
|
149 |
+
Implies(Q.unitary(x), Q.normal(x)),
|
150 |
+
Implies(Q.unitary(x), Q.invertible(x)),
|
151 |
+
Implies(Q.normal(x), Q.square(x)),
|
152 |
+
Implies(Q.diagonal(x), Q.normal(x)),
|
153 |
+
Implies(Q.positive_definite(x), Q.invertible(x)),
|
154 |
+
Implies(Q.diagonal(x), Q.upper_triangular(x)),
|
155 |
+
Implies(Q.diagonal(x), Q.lower_triangular(x)),
|
156 |
+
Implies(Q.lower_triangular(x), Q.triangular(x)),
|
157 |
+
Implies(Q.upper_triangular(x), Q.triangular(x)),
|
158 |
+
Implies(Q.triangular(x), Q.upper_triangular(x) | Q.lower_triangular(x)),
|
159 |
+
Implies(Q.upper_triangular(x) & Q.lower_triangular(x), Q.diagonal(x)),
|
160 |
+
Implies(Q.diagonal(x), Q.symmetric(x)),
|
161 |
+
Implies(Q.unit_triangular(x), Q.triangular(x)),
|
162 |
+
Implies(Q.invertible(x), Q.fullrank(x)),
|
163 |
+
Implies(Q.invertible(x), Q.square(x)),
|
164 |
+
Implies(Q.symmetric(x), Q.square(x)),
|
165 |
+
Implies(Q.fullrank(x) & Q.square(x), Q.invertible(x)),
|
166 |
+
Equivalent(Q.invertible(x), ~Q.singular(x)),
|
167 |
+
Implies(Q.integer_elements(x), Q.real_elements(x)),
|
168 |
+
Implies(Q.real_elements(x), Q.complex_elements(x)),
|
169 |
+
)
|
170 |
+
return fact
|
171 |
+
|
172 |
+
|
173 |
+
|
174 |
+
def generate_known_facts_dict(keys, fact):
|
175 |
+
"""
|
176 |
+
Computes and returns a dictionary which contains the relations between
|
177 |
+
unary predicates.
|
178 |
+
|
179 |
+
Each key is a predicate, and item is two groups of predicates.
|
180 |
+
First group contains the predicates which are implied by the key, and
|
181 |
+
second group contains the predicates which are rejected by the key.
|
182 |
+
|
183 |
+
All predicates in *keys* and *fact* must be unary and have same placeholder
|
184 |
+
symbol.
|
185 |
+
|
186 |
+
Parameters
|
187 |
+
==========
|
188 |
+
|
189 |
+
keys : list of AppliedPredicate instances.
|
190 |
+
|
191 |
+
fact : Fact between predicates in conjugated normal form.
|
192 |
+
|
193 |
+
Examples
|
194 |
+
========
|
195 |
+
|
196 |
+
>>> from sympy import Q, And, Implies
|
197 |
+
>>> from sympy.assumptions.facts import generate_known_facts_dict
|
198 |
+
>>> from sympy.abc import x
|
199 |
+
>>> keys = [Q.even(x), Q.odd(x), Q.zero(x)]
|
200 |
+
>>> fact = And(Implies(Q.even(x), ~Q.odd(x)),
|
201 |
+
... Implies(Q.zero(x), Q.even(x)))
|
202 |
+
>>> generate_known_facts_dict(keys, fact)
|
203 |
+
{Q.even: ({Q.even}, {Q.odd}),
|
204 |
+
Q.odd: ({Q.odd}, {Q.even, Q.zero}),
|
205 |
+
Q.zero: ({Q.even, Q.zero}, {Q.odd})}
|
206 |
+
"""
|
207 |
+
fact_cnf = to_cnf(fact)
|
208 |
+
mapping = single_fact_lookup(keys, fact_cnf)
|
209 |
+
|
210 |
+
ret = {}
|
211 |
+
for key, value in mapping.items():
|
212 |
+
implied = set()
|
213 |
+
rejected = set()
|
214 |
+
for expr in value:
|
215 |
+
if isinstance(expr, AppliedPredicate):
|
216 |
+
implied.add(expr.function)
|
217 |
+
elif isinstance(expr, Not):
|
218 |
+
pred = expr.args[0]
|
219 |
+
rejected.add(pred.function)
|
220 |
+
ret[key.function] = (implied, rejected)
|
221 |
+
return ret
|
222 |
+
|
223 |
+
|
224 |
+
@cacheit
|
225 |
+
def get_known_facts_keys():
|
226 |
+
"""
|
227 |
+
Return every unary predicates registered to ``Q``.
|
228 |
+
|
229 |
+
This function is used to generate the keys for
|
230 |
+
``generate_known_facts_dict``.
|
231 |
+
|
232 |
+
"""
|
233 |
+
# exclude polyadic predicates
|
234 |
+
exclude = {Q.eq, Q.ne, Q.gt, Q.lt, Q.ge, Q.le}
|
235 |
+
|
236 |
+
result = []
|
237 |
+
for attr in Q.__class__.__dict__:
|
238 |
+
if attr.startswith('__'):
|
239 |
+
continue
|
240 |
+
pred = getattr(Q, attr)
|
241 |
+
if pred in exclude:
|
242 |
+
continue
|
243 |
+
result.append(pred)
|
244 |
+
return result
|
245 |
+
|
246 |
+
|
247 |
+
def single_fact_lookup(known_facts_keys, known_facts_cnf):
|
248 |
+
# Return the dictionary for quick lookup of single fact
|
249 |
+
mapping = {}
|
250 |
+
for key in known_facts_keys:
|
251 |
+
mapping[key] = {key}
|
252 |
+
for other_key in known_facts_keys:
|
253 |
+
if other_key != key:
|
254 |
+
if ask_full_inference(other_key, key, known_facts_cnf):
|
255 |
+
mapping[key].add(other_key)
|
256 |
+
if ask_full_inference(~other_key, key, known_facts_cnf):
|
257 |
+
mapping[key].add(~other_key)
|
258 |
+
return mapping
|
259 |
+
|
260 |
+
|
261 |
+
def ask_full_inference(proposition, assumptions, known_facts_cnf):
|
262 |
+
"""
|
263 |
+
Method for inferring properties about objects.
|
264 |
+
|
265 |
+
"""
|
266 |
+
if not satisfiable(And(known_facts_cnf, assumptions, proposition)):
|
267 |
+
return False
|
268 |
+
if not satisfiable(And(known_facts_cnf, assumptions, Not(proposition))):
|
269 |
+
return True
|
270 |
+
return None
|
MLPY/Lib/site-packages/sympy/assumptions/handlers/__init__.py
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Multipledispatch handlers for ``Predicate`` are implemented here.
|
3 |
+
Handlers in this module are not directly imported to other modules in
|
4 |
+
order to avoid circular import problem.
|
5 |
+
"""
|
6 |
+
|
7 |
+
from .common import (AskHandler, CommonHandler,
|
8 |
+
test_closed_group)
|
9 |
+
|
10 |
+
__all__ = [
|
11 |
+
'AskHandler', 'CommonHandler',
|
12 |
+
'test_closed_group'
|
13 |
+
]
|
MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (469 Bytes). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/calculus.cpython-39.pyc
ADDED
Binary file (6.38 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/common.cpython-39.pyc
ADDED
Binary file (4.7 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/matrices.cpython-39.pyc
ADDED
Binary file (20.9 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/ntheory.cpython-39.pyc
ADDED
Binary file (6.19 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/order.cpython-39.pyc
ADDED
Binary file (10.7 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/handlers/__pycache__/sets.cpython-39.pyc
ADDED
Binary file (18.6 kB). View file
|
|
MLPY/Lib/site-packages/sympy/assumptions/handlers/calculus.py
ADDED
@@ -0,0 +1,258 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
This module contains query handlers responsible for calculus queries:
|
3 |
+
infinitesimal, finite, etc.
|
4 |
+
"""
|
5 |
+
|
6 |
+
from sympy.assumptions import Q, ask
|
7 |
+
from sympy.core import Add, Mul, Pow, Symbol
|
8 |
+
from sympy.core.numbers import (NegativeInfinity, GoldenRatio,
|
9 |
+
Infinity, Exp1, ComplexInfinity, ImaginaryUnit, NaN, Number, Pi, E,
|
10 |
+
TribonacciConstant)
|
11 |
+
from sympy.functions import cos, exp, log, sign, sin
|
12 |
+
from sympy.logic.boolalg import conjuncts
|
13 |
+
|
14 |
+
from ..predicates.calculus import (FinitePredicate, InfinitePredicate,
|
15 |
+
PositiveInfinitePredicate, NegativeInfinitePredicate)
|
16 |
+
|
17 |
+
|
18 |
+
# FinitePredicate
|
19 |
+
|
20 |
+
|
21 |
+
@FinitePredicate.register(Symbol)
|
22 |
+
def _(expr, assumptions):
|
23 |
+
"""
|
24 |
+
Handles Symbol.
|
25 |
+
"""
|
26 |
+
if expr.is_finite is not None:
|
27 |
+
return expr.is_finite
|
28 |
+
if Q.finite(expr) in conjuncts(assumptions):
|
29 |
+
return True
|
30 |
+
return None
|
31 |
+
|
32 |
+
@FinitePredicate.register(Add)
|
33 |
+
def _(expr, assumptions):
|
34 |
+
"""
|
35 |
+
Return True if expr is bounded, False if not and None if unknown.
|
36 |
+
|
37 |
+
Truth Table:
|
38 |
+
|
39 |
+
+-------+-----+-----------+-----------+
|
40 |
+
| | | | |
|
41 |
+
| | B | U | ? |
|
42 |
+
| | | | |
|
43 |
+
+-------+-----+---+---+---+---+---+---+
|
44 |
+
| | | | | | | | |
|
45 |
+
| | |'+'|'-'|'x'|'+'|'-'|'x'|
|
46 |
+
| | | | | | | | |
|
47 |
+
+-------+-----+---+---+---+---+---+---+
|
48 |
+
| | | | |
|
49 |
+
| B | B | U | ? |
|
50 |
+
| | | | |
|
51 |
+
+---+---+-----+---+---+---+---+---+---+
|
52 |
+
| | | | | | | | | |
|
53 |
+
| |'+'| | U | ? | ? | U | ? | ? |
|
54 |
+
| | | | | | | | | |
|
55 |
+
| +---+-----+---+---+---+---+---+---+
|
56 |
+
| | | | | | | | | |
|
57 |
+
| U |'-'| | ? | U | ? | ? | U | ? |
|
58 |
+
| | | | | | | | | |
|
59 |
+
| +---+-----+---+---+---+---+---+---+
|
60 |
+
| | | | | |
|
61 |
+
| |'x'| | ? | ? |
|
62 |
+
| | | | | |
|
63 |
+
+---+---+-----+---+---+---+---+---+---+
|
64 |
+
| | | | |
|
65 |
+
| ? | | | ? |
|
66 |
+
| | | | |
|
67 |
+
+-------+-----+-----------+---+---+---+
|
68 |
+
|
69 |
+
* 'B' = Bounded
|
70 |
+
|
71 |
+
* 'U' = Unbounded
|
72 |
+
|
73 |
+
* '?' = unknown boundedness
|
74 |
+
|
75 |
+
* '+' = positive sign
|
76 |
+
|
77 |
+
* '-' = negative sign
|
78 |
+
|
79 |
+
* 'x' = sign unknown
|
80 |
+
|
81 |
+
* All Bounded -> True
|
82 |
+
|
83 |
+
* 1 Unbounded and the rest Bounded -> False
|
84 |
+
|
85 |
+
* >1 Unbounded, all with same known sign -> False
|
86 |
+
|
87 |
+
* Any Unknown and unknown sign -> None
|
88 |
+
|
89 |
+
* Else -> None
|
90 |
+
|
91 |
+
When the signs are not the same you can have an undefined
|
92 |
+
result as in oo - oo, hence 'bounded' is also undefined.
|
93 |
+
"""
|
94 |
+
sign = -1 # sign of unknown or infinite
|
95 |
+
result = True
|
96 |
+
for arg in expr.args:
|
97 |
+
_bounded = ask(Q.finite(arg), assumptions)
|
98 |
+
if _bounded:
|
99 |
+
continue
|
100 |
+
s = ask(Q.extended_positive(arg), assumptions)
|
101 |
+
# if there has been more than one sign or if the sign of this arg
|
102 |
+
# is None and Bounded is None or there was already
|
103 |
+
# an unknown sign, return None
|
104 |
+
if sign != -1 and s != sign or \
|
105 |
+
s is None and None in (_bounded, sign):
|
106 |
+
return None
|
107 |
+
else:
|
108 |
+
sign = s
|
109 |
+
# once False, do not change
|
110 |
+
if result is not False:
|
111 |
+
result = _bounded
|
112 |
+
return result
|
113 |
+
|
114 |
+
@FinitePredicate.register(Mul)
|
115 |
+
def _(expr, assumptions):
|
116 |
+
"""
|
117 |
+
Return True if expr is bounded, False if not and None if unknown.
|
118 |
+
|
119 |
+
Truth Table:
|
120 |
+
|
121 |
+
+---+---+---+--------+
|
122 |
+
| | | | |
|
123 |
+
| | B | U | ? |
|
124 |
+
| | | | |
|
125 |
+
+---+---+---+---+----+
|
126 |
+
| | | | | |
|
127 |
+
| | | | s | /s |
|
128 |
+
| | | | | |
|
129 |
+
+---+---+---+---+----+
|
130 |
+
| | | | |
|
131 |
+
| B | B | U | ? |
|
132 |
+
| | | | |
|
133 |
+
+---+---+---+---+----+
|
134 |
+
| | | | | |
|
135 |
+
| U | | U | U | ? |
|
136 |
+
| | | | | |
|
137 |
+
+---+---+---+---+----+
|
138 |
+
| | | | |
|
139 |
+
| ? | | | ? |
|
140 |
+
| | | | |
|
141 |
+
+---+---+---+---+----+
|
142 |
+
|
143 |
+
* B = Bounded
|
144 |
+
|
145 |
+
* U = Unbounded
|
146 |
+
|
147 |
+
* ? = unknown boundedness
|
148 |
+
|
149 |
+
* s = signed (hence nonzero)
|
150 |
+
|
151 |
+
* /s = not signed
|
152 |
+
"""
|
153 |
+
result = True
|
154 |
+
for arg in expr.args:
|
155 |
+
_bounded = ask(Q.finite(arg), assumptions)
|
156 |
+
if _bounded:
|
157 |
+
continue
|
158 |
+
elif _bounded is None:
|
159 |
+
if result is None:
|
160 |
+
return None
|
161 |
+
if ask(Q.extended_nonzero(arg), assumptions) is None:
|
162 |
+
return None
|
163 |
+
if result is not False:
|
164 |
+
result = None
|
165 |
+
else:
|
166 |
+
result = False
|
167 |
+
return result
|
168 |
+
|
169 |
+
@FinitePredicate.register(Pow)
|
170 |
+
def _(expr, assumptions):
|
171 |
+
"""
|
172 |
+
* Unbounded ** NonZero -> Unbounded
|
173 |
+
|
174 |
+
* Bounded ** Bounded -> Bounded
|
175 |
+
|
176 |
+
* Abs()<=1 ** Positive -> Bounded
|
177 |
+
|
178 |
+
* Abs()>=1 ** Negative -> Bounded
|
179 |
+
|
180 |
+
* Otherwise unknown
|
181 |
+
"""
|
182 |
+
if expr.base == E:
|
183 |
+
return ask(Q.finite(expr.exp), assumptions)
|
184 |
+
|
185 |
+
base_bounded = ask(Q.finite(expr.base), assumptions)
|
186 |
+
exp_bounded = ask(Q.finite(expr.exp), assumptions)
|
187 |
+
if base_bounded is None and exp_bounded is None: # Common Case
|
188 |
+
return None
|
189 |
+
if base_bounded is False and ask(Q.extended_nonzero(expr.exp), assumptions):
|
190 |
+
return False
|
191 |
+
if base_bounded and exp_bounded:
|
192 |
+
return True
|
193 |
+
if (abs(expr.base) <= 1) == True and ask(Q.extended_positive(expr.exp), assumptions):
|
194 |
+
return True
|
195 |
+
if (abs(expr.base) >= 1) == True and ask(Q.extended_negative(expr.exp), assumptions):
|
196 |
+
return True
|
197 |
+
if (abs(expr.base) >= 1) == True and exp_bounded is False:
|
198 |
+
return False
|
199 |
+
return None
|
200 |
+
|
201 |
+
@FinitePredicate.register(exp)
|
202 |
+
def _(expr, assumptions):
|
203 |
+
return ask(Q.finite(expr.exp), assumptions)
|
204 |
+
|
205 |
+
@FinitePredicate.register(log)
|
206 |
+
def _(expr, assumptions):
|
207 |
+
# After complex -> finite fact is registered to new assumption system,
|
208 |
+
# querying Q.infinite may be removed.
|
209 |
+
if ask(Q.infinite(expr.args[0]), assumptions):
|
210 |
+
return False
|
211 |
+
return ask(~Q.zero(expr.args[0]), assumptions)
|
212 |
+
|
213 |
+
@FinitePredicate.register_many(cos, sin, Number, Pi, Exp1, GoldenRatio,
|
214 |
+
TribonacciConstant, ImaginaryUnit, sign)
|
215 |
+
def _(expr, assumptions):
|
216 |
+
return True
|
217 |
+
|
218 |
+
@FinitePredicate.register_many(ComplexInfinity, Infinity, NegativeInfinity)
|
219 |
+
def _(expr, assumptions):
|
220 |
+
return False
|
221 |
+
|
222 |
+
@FinitePredicate.register(NaN)
|
223 |
+
def _(expr, assumptions):
|
224 |
+
return None
|
225 |
+
|
226 |
+
|
227 |
+
# InfinitePredicate
|
228 |
+
|
229 |
+
|
230 |
+
@InfinitePredicate.register_many(ComplexInfinity, Infinity, NegativeInfinity)
|
231 |
+
def _(expr, assumptions):
|
232 |
+
return True
|
233 |
+
|
234 |
+
|
235 |
+
# PositiveInfinitePredicate
|
236 |
+
|
237 |
+
|
238 |
+
@PositiveInfinitePredicate.register(Infinity)
|
239 |
+
def _(expr, assumptions):
|
240 |
+
return True
|
241 |
+
|
242 |
+
|
243 |
+
@PositiveInfinitePredicate.register_many(NegativeInfinity, ComplexInfinity)
|
244 |
+
def _(expr, assumptions):
|
245 |
+
return False
|
246 |
+
|
247 |
+
|
248 |
+
# NegativeInfinitePredicate
|
249 |
+
|
250 |
+
|
251 |
+
@NegativeInfinitePredicate.register(NegativeInfinity)
|
252 |
+
def _(expr, assumptions):
|
253 |
+
return True
|
254 |
+
|
255 |
+
|
256 |
+
@NegativeInfinitePredicate.register_many(Infinity, ComplexInfinity)
|
257 |
+
def _(expr, assumptions):
|
258 |
+
return False
|