Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .venv/lib/python3.13/site-packages/sympy/core/benchmarks/bench_arit.py +43 -0
- .venv/lib/python3.13/site-packages/sympy/core/benchmarks/bench_expand.py +23 -0
- .venv/lib/python3.13/site-packages/sympy/core/benchmarks/bench_numbers.py +92 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/__init__.py +0 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_args.py +0 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_arit.py +2489 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_assumptions.py +1335 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_cache.py +91 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_compatibility.py +6 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_complex.py +226 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_constructor_postprocessor.py +87 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_containers.py +217 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_count_ops.py +155 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_diff.py +160 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_equal.py +89 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_eval.py +95 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_evalf.py +738 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_expand.py +364 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_expr.py +2313 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_exprtools.py +493 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_facts.py +312 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_function.py +1459 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_logic.py +198 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_match.py +766 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_noncommutative.py +140 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_numbers.py +2335 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_operations.py +110 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_parameters.py +126 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_power.py +670 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_priority.py +145 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_random.py +61 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_relational.py +1271 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_rules.py +14 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_sorting.py +28 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_subs.py +895 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_symbol.py +421 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_sympify.py +892 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_traversal.py +119 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_truediv.py +54 -0
- .venv/lib/python3.13/site-packages/sympy/core/tests/test_var.py +62 -0
- video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000171.json +5 -0
- video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000201.json +5 -0
- video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000331.json +5 -0
- video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000371.json +5 -0
- video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000521.json +5 -0
- video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000581.json +5 -0
- video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000651.json +5 -0
- video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000721.json +5 -0
- video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000761.json +5 -0
- video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000921.json +5 -0
.venv/lib/python3.13/site-packages/sympy/core/benchmarks/bench_arit.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core import Add, Mul, symbols
|
| 2 |
+
|
| 3 |
+
x, y, z = symbols('x,y,z')
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def timeit_neg():
|
| 7 |
+
-x
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def timeit_Add_x1():
|
| 11 |
+
x + 1
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def timeit_Add_1x():
|
| 15 |
+
1 + x
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def timeit_Add_x05():
|
| 19 |
+
x + 0.5
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def timeit_Add_xy():
|
| 23 |
+
x + y
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def timeit_Add_xyz():
|
| 27 |
+
Add(*[x, y, z])
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def timeit_Mul_xy():
|
| 31 |
+
x*y
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def timeit_Mul_xyz():
|
| 35 |
+
Mul(*[x, y, z])
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def timeit_Div_xy():
|
| 39 |
+
x/y
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def timeit_Div_2y():
|
| 43 |
+
2/y
|
.venv/lib/python3.13/site-packages/sympy/core/benchmarks/bench_expand.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core import symbols, I
|
| 2 |
+
|
| 3 |
+
x, y, z = symbols('x,y,z')
|
| 4 |
+
|
| 5 |
+
p = 3*x**2*y*z**7 + 7*x*y*z**2 + 4*x + x*y**4
|
| 6 |
+
e = (x + y + z + 1)**32
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def timeit_expand_nothing_todo():
|
| 10 |
+
p.expand()
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def bench_expand_32():
|
| 14 |
+
"""(x+y+z+1)**32 -> expand"""
|
| 15 |
+
e.expand()
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def timeit_expand_complex_number_1():
|
| 19 |
+
((2 + 3*I)**1000).expand(complex=True)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def timeit_expand_complex_number_2():
|
| 23 |
+
((2 + 3*I/4)**1000).expand(complex=True)
|
.venv/lib/python3.13/site-packages/sympy/core/benchmarks/bench_numbers.py
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.numbers import Integer, Rational, pi, oo
|
| 2 |
+
from sympy.core.intfunc import integer_nthroot, igcd
|
| 3 |
+
from sympy.core.singleton import S
|
| 4 |
+
|
| 5 |
+
i3 = Integer(3)
|
| 6 |
+
i4 = Integer(4)
|
| 7 |
+
r34 = Rational(3, 4)
|
| 8 |
+
q45 = Rational(4, 5)
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def timeit_Integer_create():
|
| 12 |
+
Integer(2)
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def timeit_Integer_int():
|
| 16 |
+
int(i3)
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def timeit_neg_one():
|
| 20 |
+
-S.One
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def timeit_Integer_neg():
|
| 24 |
+
-i3
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def timeit_Integer_abs():
|
| 28 |
+
abs(i3)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def timeit_Integer_sub():
|
| 32 |
+
i3 - i3
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def timeit_abs_pi():
|
| 36 |
+
abs(pi)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def timeit_neg_oo():
|
| 40 |
+
-oo
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def timeit_Integer_add_i1():
|
| 44 |
+
i3 + 1
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def timeit_Integer_add_ij():
|
| 48 |
+
i3 + i4
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def timeit_Integer_add_Rational():
|
| 52 |
+
i3 + r34
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def timeit_Integer_mul_i4():
|
| 56 |
+
i3*4
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def timeit_Integer_mul_ij():
|
| 60 |
+
i3*i4
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def timeit_Integer_mul_Rational():
|
| 64 |
+
i3*r34
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def timeit_Integer_eq_i3():
|
| 68 |
+
i3 == 3
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def timeit_Integer_ed_Rational():
|
| 72 |
+
i3 == r34
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def timeit_integer_nthroot():
|
| 76 |
+
integer_nthroot(100, 2)
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def timeit_number_igcd_23_17():
|
| 80 |
+
igcd(23, 17)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def timeit_number_igcd_60_3600():
|
| 84 |
+
igcd(60, 3600)
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
def timeit_Rational_add_r1():
|
| 88 |
+
r34 + 1
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def timeit_Rational_add_rq():
|
| 92 |
+
r34 + q45
|
.venv/lib/python3.13/site-packages/sympy/core/tests/__init__.py
ADDED
|
File without changes
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_args.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_arit.py
ADDED
|
@@ -0,0 +1,2489 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.add import Add
|
| 2 |
+
from sympy.core.basic import Basic
|
| 3 |
+
from sympy.core.mod import Mod
|
| 4 |
+
from sympy.core.mul import Mul
|
| 5 |
+
from sympy.core.numbers import (Float, I, Integer, Rational, comp, nan,
|
| 6 |
+
oo, pi, zoo)
|
| 7 |
+
from sympy.core.power import Pow
|
| 8 |
+
from sympy.core.singleton import S
|
| 9 |
+
from sympy.core.symbol import (Dummy, Symbol, symbols)
|
| 10 |
+
from sympy.core.sympify import sympify
|
| 11 |
+
from sympy.functions.combinatorial.factorials import factorial
|
| 12 |
+
from sympy.functions.elementary.complexes import (im, re, sign)
|
| 13 |
+
from sympy.functions.elementary.exponential import (exp, log)
|
| 14 |
+
from sympy.functions.elementary.integers import floor
|
| 15 |
+
from sympy.functions.elementary.miscellaneous import (Max, sqrt)
|
| 16 |
+
from sympy.functions.elementary.trigonometric import (atan, cos, sin)
|
| 17 |
+
from sympy.integrals.integrals import Integral
|
| 18 |
+
from sympy.polys.polytools import Poly
|
| 19 |
+
from sympy.sets.sets import FiniteSet
|
| 20 |
+
|
| 21 |
+
from sympy.core.parameters import distribute, evaluate
|
| 22 |
+
from sympy.core.expr import unchanged
|
| 23 |
+
from sympy.utilities.iterables import permutations
|
| 24 |
+
from sympy.testing.pytest import XFAIL, raises, warns
|
| 25 |
+
from sympy.utilities.exceptions import SymPyDeprecationWarning
|
| 26 |
+
from sympy.core.random import verify_numerically
|
| 27 |
+
from sympy.functions.elementary.trigonometric import asin
|
| 28 |
+
|
| 29 |
+
from itertools import product
|
| 30 |
+
|
| 31 |
+
a, c, x, y, z = symbols('a,c,x,y,z')
|
| 32 |
+
b = Symbol("b", positive=True)
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def same_and_same_prec(a, b):
|
| 36 |
+
# stricter matching for Floats
|
| 37 |
+
return a == b and a._prec == b._prec
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def test_bug1():
|
| 41 |
+
assert re(x) != x
|
| 42 |
+
x.series(x, 0, 1)
|
| 43 |
+
assert re(x) != x
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def test_Symbol():
|
| 47 |
+
e = a*b
|
| 48 |
+
assert e == a*b
|
| 49 |
+
assert a*b*b == a*b**2
|
| 50 |
+
assert a*b*b + c == c + a*b**2
|
| 51 |
+
assert a*b*b - c == -c + a*b**2
|
| 52 |
+
|
| 53 |
+
x = Symbol('x', complex=True, real=False)
|
| 54 |
+
assert x.is_imaginary is None # could be I or 1 + I
|
| 55 |
+
x = Symbol('x', complex=True, imaginary=False)
|
| 56 |
+
assert x.is_real is None # could be 1 or 1 + I
|
| 57 |
+
x = Symbol('x', real=True)
|
| 58 |
+
assert x.is_complex
|
| 59 |
+
x = Symbol('x', imaginary=True)
|
| 60 |
+
assert x.is_complex
|
| 61 |
+
x = Symbol('x', real=False, imaginary=False)
|
| 62 |
+
assert x.is_complex is None # might be a non-number
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def test_arit0():
|
| 66 |
+
p = Rational(5)
|
| 67 |
+
e = a*b
|
| 68 |
+
assert e == a*b
|
| 69 |
+
e = a*b + b*a
|
| 70 |
+
assert e == 2*a*b
|
| 71 |
+
e = a*b + b*a + a*b + p*b*a
|
| 72 |
+
assert e == 8*a*b
|
| 73 |
+
e = a*b + b*a + a*b + p*b*a + a
|
| 74 |
+
assert e == a + 8*a*b
|
| 75 |
+
e = a + a
|
| 76 |
+
assert e == 2*a
|
| 77 |
+
e = a + b + a
|
| 78 |
+
assert e == b + 2*a
|
| 79 |
+
e = a + b*b + a + b*b
|
| 80 |
+
assert e == 2*a + 2*b**2
|
| 81 |
+
e = a + Rational(2) + b*b + a + b*b + p
|
| 82 |
+
assert e == 7 + 2*a + 2*b**2
|
| 83 |
+
e = (a + b*b + a + b*b)*p
|
| 84 |
+
assert e == 5*(2*a + 2*b**2)
|
| 85 |
+
e = (a*b*c + c*b*a + b*a*c)*p
|
| 86 |
+
assert e == 15*a*b*c
|
| 87 |
+
e = (a*b*c + c*b*a + b*a*c)*p - Rational(15)*a*b*c
|
| 88 |
+
assert e == Rational(0)
|
| 89 |
+
e = Rational(50)*(a - a)
|
| 90 |
+
assert e == Rational(0)
|
| 91 |
+
e = b*a - b - a*b + b
|
| 92 |
+
assert e == Rational(0)
|
| 93 |
+
e = a*b + c**p
|
| 94 |
+
assert e == a*b + c**5
|
| 95 |
+
e = a/b
|
| 96 |
+
assert e == a*b**(-1)
|
| 97 |
+
e = a*2*2
|
| 98 |
+
assert e == 4*a
|
| 99 |
+
e = 2 + a*2/2
|
| 100 |
+
assert e == 2 + a
|
| 101 |
+
e = 2 - a - 2
|
| 102 |
+
assert e == -a
|
| 103 |
+
e = 2*a*2
|
| 104 |
+
assert e == 4*a
|
| 105 |
+
e = 2/a/2
|
| 106 |
+
assert e == a**(-1)
|
| 107 |
+
e = 2**a**2
|
| 108 |
+
assert e == 2**(a**2)
|
| 109 |
+
e = -(1 + a)
|
| 110 |
+
assert e == -1 - a
|
| 111 |
+
e = S.Half*(1 + a)
|
| 112 |
+
assert e == S.Half + a/2
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def test_div():
|
| 116 |
+
e = a/b
|
| 117 |
+
assert e == a*b**(-1)
|
| 118 |
+
e = a/b + c/2
|
| 119 |
+
assert e == a*b**(-1) + Rational(1)/2*c
|
| 120 |
+
e = (1 - b)/(b - 1)
|
| 121 |
+
assert e == (1 + -b)*((-1) + b)**(-1)
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def test_pow_arit():
|
| 125 |
+
n1 = Rational(1)
|
| 126 |
+
n2 = Rational(2)
|
| 127 |
+
n5 = Rational(5)
|
| 128 |
+
e = a*a
|
| 129 |
+
assert e == a**2
|
| 130 |
+
e = a*a*a
|
| 131 |
+
assert e == a**3
|
| 132 |
+
e = a*a*a*a**Rational(6)
|
| 133 |
+
assert e == a**9
|
| 134 |
+
e = a*a*a*a**Rational(6) - a**Rational(9)
|
| 135 |
+
assert e == Rational(0)
|
| 136 |
+
e = a**(b - b)
|
| 137 |
+
assert e == Rational(1)
|
| 138 |
+
e = (a + Rational(1) - a)**b
|
| 139 |
+
assert e == Rational(1)
|
| 140 |
+
|
| 141 |
+
e = (a + b + c)**n2
|
| 142 |
+
assert e == (a + b + c)**2
|
| 143 |
+
assert e.expand() == 2*b*c + 2*a*c + 2*a*b + a**2 + c**2 + b**2
|
| 144 |
+
|
| 145 |
+
e = (a + b)**n2
|
| 146 |
+
assert e == (a + b)**2
|
| 147 |
+
assert e.expand() == 2*a*b + a**2 + b**2
|
| 148 |
+
|
| 149 |
+
e = (a + b)**(n1/n2)
|
| 150 |
+
assert e == sqrt(a + b)
|
| 151 |
+
assert e.expand() == sqrt(a + b)
|
| 152 |
+
|
| 153 |
+
n = n5**(n1/n2)
|
| 154 |
+
assert n == sqrt(5)
|
| 155 |
+
e = n*a*b - n*b*a
|
| 156 |
+
assert e == Rational(0)
|
| 157 |
+
e = n*a*b + n*b*a
|
| 158 |
+
assert e == 2*a*b*sqrt(5)
|
| 159 |
+
assert e.diff(a) == 2*b*sqrt(5)
|
| 160 |
+
assert e.diff(a) == 2*b*sqrt(5)
|
| 161 |
+
e = a/b**2
|
| 162 |
+
assert e == a*b**(-2)
|
| 163 |
+
|
| 164 |
+
assert sqrt(2*(1 + sqrt(2))) == (2*(1 + 2**S.Half))**S.Half
|
| 165 |
+
|
| 166 |
+
x = Symbol('x')
|
| 167 |
+
y = Symbol('y')
|
| 168 |
+
|
| 169 |
+
assert ((x*y)**3).expand() == y**3 * x**3
|
| 170 |
+
assert ((x*y)**-3).expand() == y**-3 * x**-3
|
| 171 |
+
|
| 172 |
+
assert (x**5*(3*x)**(3)).expand() == 27 * x**8
|
| 173 |
+
assert (x**5*(-3*x)**(3)).expand() == -27 * x**8
|
| 174 |
+
assert (x**5*(3*x)**(-3)).expand() == x**2 * Rational(1, 27)
|
| 175 |
+
assert (x**5*(-3*x)**(-3)).expand() == x**2 * Rational(-1, 27)
|
| 176 |
+
|
| 177 |
+
# expand_power_exp
|
| 178 |
+
_x = Symbol('x', zero=False)
|
| 179 |
+
_y = Symbol('y', zero=False)
|
| 180 |
+
assert (_x**(y**(x + exp(x + y)) + z)).expand(deep=False) == \
|
| 181 |
+
_x**z*_x**(y**(x + exp(x + y)))
|
| 182 |
+
assert (_x**(_y**(x + exp(x + y)) + z)).expand() == \
|
| 183 |
+
_x**z*_x**(_y**x*_y**(exp(x)*exp(y)))
|
| 184 |
+
|
| 185 |
+
n = Symbol('n', even=False)
|
| 186 |
+
k = Symbol('k', even=True)
|
| 187 |
+
o = Symbol('o', odd=True)
|
| 188 |
+
|
| 189 |
+
assert unchanged(Pow, -1, x)
|
| 190 |
+
assert unchanged(Pow, -1, n)
|
| 191 |
+
assert (-2)**k == 2**k
|
| 192 |
+
assert (-1)**k == 1
|
| 193 |
+
assert (-1)**o == -1
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
def test_pow2():
|
| 197 |
+
# x**(2*y) is always (x**y)**2 but is only (x**2)**y if
|
| 198 |
+
# x.is_positive or y.is_integer
|
| 199 |
+
# let x = 1 to see why the following are not true.
|
| 200 |
+
assert (-x)**Rational(2, 3) != x**Rational(2, 3)
|
| 201 |
+
assert (-x)**Rational(5, 7) != -x**Rational(5, 7)
|
| 202 |
+
assert ((-x)**2)**Rational(1, 3) != ((-x)**Rational(1, 3))**2
|
| 203 |
+
assert sqrt(x**2) != x
|
| 204 |
+
|
| 205 |
+
|
| 206 |
+
def test_pow3():
|
| 207 |
+
assert sqrt(2)**3 == 2 * sqrt(2)
|
| 208 |
+
assert sqrt(2)**3 == sqrt(8)
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
def test_mod_pow():
|
| 212 |
+
for s, t, u, v in [(4, 13, 497, 445), (4, -3, 497, 365),
|
| 213 |
+
(3.2, 2.1, 1.9, 0.1031015682350942), (S(3)/2, 5, S(5)/6, S(3)/32)]:
|
| 214 |
+
assert pow(S(s), t, u) == v
|
| 215 |
+
assert pow(S(s), S(t), u) == v
|
| 216 |
+
assert pow(S(s), t, S(u)) == v
|
| 217 |
+
assert pow(S(s), S(t), S(u)) == v
|
| 218 |
+
assert pow(S(2), S(10000000000), S(3)) == 1
|
| 219 |
+
assert pow(x, y, z) == x**y%z
|
| 220 |
+
raises(TypeError, lambda: pow(S(4), "13", 497))
|
| 221 |
+
raises(TypeError, lambda: pow(S(4), 13, "497"))
|
| 222 |
+
|
| 223 |
+
|
| 224 |
+
def test_pow_E():
|
| 225 |
+
assert 2**(y/log(2)) == S.Exp1**y
|
| 226 |
+
assert 2**(y/log(2)/3) == S.Exp1**(y/3)
|
| 227 |
+
assert 3**(1/log(-3)) != S.Exp1
|
| 228 |
+
assert (3 + 2*I)**(1/(log(-3 - 2*I) + I*pi)) == S.Exp1
|
| 229 |
+
assert (4 + 2*I)**(1/(log(-4 - 2*I) + I*pi)) == S.Exp1
|
| 230 |
+
assert (3 + 2*I)**(1/(log(-3 - 2*I, 3)/2 + I*pi/log(3)/2)) == 9
|
| 231 |
+
assert (3 + 2*I)**(1/(log(3 + 2*I, 3)/2)) == 9
|
| 232 |
+
# every time tests are run they will affirm with a different random
|
| 233 |
+
# value that this identity holds
|
| 234 |
+
while 1:
|
| 235 |
+
b = x._random()
|
| 236 |
+
r, i = b.as_real_imag()
|
| 237 |
+
if i:
|
| 238 |
+
break
|
| 239 |
+
assert verify_numerically(b**(1/(log(-b) + sign(i)*I*pi).n()), S.Exp1)
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
def test_pow_issue_3516():
|
| 243 |
+
assert 4**Rational(1, 4) == sqrt(2)
|
| 244 |
+
|
| 245 |
+
|
| 246 |
+
def test_pow_im():
|
| 247 |
+
for m in (-2, -1, 2):
|
| 248 |
+
for d in (3, 4, 5):
|
| 249 |
+
b = m*I
|
| 250 |
+
for i in range(1, 4*d + 1):
|
| 251 |
+
e = Rational(i, d)
|
| 252 |
+
assert (b**e - b.n()**e.n()).n(2, chop=1e-10) == 0
|
| 253 |
+
|
| 254 |
+
e = Rational(7, 3)
|
| 255 |
+
assert (2*x*I)**e == 4*2**Rational(1, 3)*(I*x)**e # same as Wolfram Alpha
|
| 256 |
+
im = symbols('im', imaginary=True)
|
| 257 |
+
assert (2*im*I)**e == 4*2**Rational(1, 3)*(I*im)**e
|
| 258 |
+
|
| 259 |
+
args = [I, I, I, I, 2]
|
| 260 |
+
e = Rational(1, 3)
|
| 261 |
+
ans = 2**e
|
| 262 |
+
assert Mul(*args, evaluate=False)**e == ans
|
| 263 |
+
assert Mul(*args)**e == ans
|
| 264 |
+
args = [I, I, I, 2]
|
| 265 |
+
e = Rational(1, 3)
|
| 266 |
+
ans = 2**e*(-I)**e
|
| 267 |
+
assert Mul(*args, evaluate=False)**e == ans
|
| 268 |
+
assert Mul(*args)**e == ans
|
| 269 |
+
args.append(-3)
|
| 270 |
+
ans = (6*I)**e
|
| 271 |
+
assert Mul(*args, evaluate=False)**e == ans
|
| 272 |
+
assert Mul(*args)**e == ans
|
| 273 |
+
args.append(-1)
|
| 274 |
+
ans = (-6*I)**e
|
| 275 |
+
assert Mul(*args, evaluate=False)**e == ans
|
| 276 |
+
assert Mul(*args)**e == ans
|
| 277 |
+
|
| 278 |
+
args = [I, I, 2]
|
| 279 |
+
e = Rational(1, 3)
|
| 280 |
+
ans = (-2)**e
|
| 281 |
+
assert Mul(*args, evaluate=False)**e == ans
|
| 282 |
+
assert Mul(*args)**e == ans
|
| 283 |
+
args.append(-3)
|
| 284 |
+
ans = (6)**e
|
| 285 |
+
assert Mul(*args, evaluate=False)**e == ans
|
| 286 |
+
assert Mul(*args)**e == ans
|
| 287 |
+
args.append(-1)
|
| 288 |
+
ans = (-6)**e
|
| 289 |
+
assert Mul(*args, evaluate=False)**e == ans
|
| 290 |
+
assert Mul(*args)**e == ans
|
| 291 |
+
assert Mul(Pow(-1, Rational(3, 2), evaluate=False), I, I) == I
|
| 292 |
+
assert Mul(I*Pow(I, S.Half, evaluate=False)) == sqrt(I)*I
|
| 293 |
+
|
| 294 |
+
|
| 295 |
+
def test_real_mul():
|
| 296 |
+
assert Float(0) * pi * x == 0
|
| 297 |
+
assert set((Float(1) * pi * x).args) == {Float(1), pi, x}
|
| 298 |
+
|
| 299 |
+
|
| 300 |
+
def test_ncmul():
|
| 301 |
+
A = Symbol("A", commutative=False)
|
| 302 |
+
B = Symbol("B", commutative=False)
|
| 303 |
+
C = Symbol("C", commutative=False)
|
| 304 |
+
assert A*B != B*A
|
| 305 |
+
assert A*B*C != C*B*A
|
| 306 |
+
assert A*b*B*3*C == 3*b*A*B*C
|
| 307 |
+
assert A*b*B*3*C != 3*b*B*A*C
|
| 308 |
+
assert A*b*B*3*C == 3*A*B*C*b
|
| 309 |
+
|
| 310 |
+
assert A + B == B + A
|
| 311 |
+
assert (A + B)*C != C*(A + B)
|
| 312 |
+
|
| 313 |
+
assert C*(A + B)*C != C*C*(A + B)
|
| 314 |
+
|
| 315 |
+
assert A*A == A**2
|
| 316 |
+
assert (A + B)*(A + B) == (A + B)**2
|
| 317 |
+
|
| 318 |
+
assert A**-1 * A == 1
|
| 319 |
+
assert A/A == 1
|
| 320 |
+
assert A/(A**2) == 1/A
|
| 321 |
+
|
| 322 |
+
assert A/(1 + A) == A/(1 + A)
|
| 323 |
+
|
| 324 |
+
assert set((A + B + 2*(A + B)).args) == \
|
| 325 |
+
{A, B, 2*(A + B)}
|
| 326 |
+
|
| 327 |
+
|
| 328 |
+
def test_mul_add_identity():
|
| 329 |
+
m = Mul(1, 2)
|
| 330 |
+
assert isinstance(m, Rational) and m.p == 2 and m.q == 1
|
| 331 |
+
m = Mul(1, 2, evaluate=False)
|
| 332 |
+
assert isinstance(m, Mul) and m.args == (1, 2)
|
| 333 |
+
m = Mul(0, 1)
|
| 334 |
+
assert m is S.Zero
|
| 335 |
+
m = Mul(0, 1, evaluate=False)
|
| 336 |
+
assert isinstance(m, Mul) and m.args == (0, 1)
|
| 337 |
+
m = Add(0, 1)
|
| 338 |
+
assert m is S.One
|
| 339 |
+
m = Add(0, 1, evaluate=False)
|
| 340 |
+
assert isinstance(m, Add) and m.args == (0, 1)
|
| 341 |
+
|
| 342 |
+
|
| 343 |
+
def test_ncpow():
|
| 344 |
+
x = Symbol('x', commutative=False)
|
| 345 |
+
y = Symbol('y', commutative=False)
|
| 346 |
+
z = Symbol('z', commutative=False)
|
| 347 |
+
a = Symbol('a')
|
| 348 |
+
b = Symbol('b')
|
| 349 |
+
c = Symbol('c')
|
| 350 |
+
|
| 351 |
+
assert (x**2)*(y**2) != (y**2)*(x**2)
|
| 352 |
+
assert (x**-2)*y != y*(x**2)
|
| 353 |
+
assert 2**x*2**y != 2**(x + y)
|
| 354 |
+
assert 2**x*2**y*2**z != 2**(x + y + z)
|
| 355 |
+
assert 2**x*2**(2*x) == 2**(3*x)
|
| 356 |
+
assert 2**x*2**(2*x)*2**x == 2**(4*x)
|
| 357 |
+
assert exp(x)*exp(y) != exp(y)*exp(x)
|
| 358 |
+
assert exp(x)*exp(y)*exp(z) != exp(y)*exp(x)*exp(z)
|
| 359 |
+
assert exp(x)*exp(y)*exp(z) != exp(x + y + z)
|
| 360 |
+
assert x**a*x**b != x**(a + b)
|
| 361 |
+
assert x**a*x**b*x**c != x**(a + b + c)
|
| 362 |
+
assert x**3*x**4 == x**7
|
| 363 |
+
assert x**3*x**4*x**2 == x**9
|
| 364 |
+
assert x**a*x**(4*a) == x**(5*a)
|
| 365 |
+
assert x**a*x**(4*a)*x**a == x**(6*a)
|
| 366 |
+
|
| 367 |
+
|
| 368 |
+
def test_powerbug():
|
| 369 |
+
x = Symbol("x")
|
| 370 |
+
assert x**1 != (-x)**1
|
| 371 |
+
assert x**2 == (-x)**2
|
| 372 |
+
assert x**3 != (-x)**3
|
| 373 |
+
assert x**4 == (-x)**4
|
| 374 |
+
assert x**5 != (-x)**5
|
| 375 |
+
assert x**6 == (-x)**6
|
| 376 |
+
|
| 377 |
+
assert x**128 == (-x)**128
|
| 378 |
+
assert x**129 != (-x)**129
|
| 379 |
+
|
| 380 |
+
assert (2*x)**2 == (-2*x)**2
|
| 381 |
+
|
| 382 |
+
|
| 383 |
+
def test_Mul_doesnt_expand_exp():
|
| 384 |
+
x = Symbol('x')
|
| 385 |
+
y = Symbol('y')
|
| 386 |
+
assert unchanged(Mul, exp(x), exp(y))
|
| 387 |
+
assert unchanged(Mul, 2**x, 2**y)
|
| 388 |
+
assert x**2*x**3 == x**5
|
| 389 |
+
assert 2**x*3**x == 6**x
|
| 390 |
+
assert x**(y)*x**(2*y) == x**(3*y)
|
| 391 |
+
assert sqrt(2)*sqrt(2) == 2
|
| 392 |
+
assert 2**x*2**(2*x) == 2**(3*x)
|
| 393 |
+
assert sqrt(2)*2**Rational(1, 4)*5**Rational(3, 4) == 10**Rational(3, 4)
|
| 394 |
+
assert (x**(-log(5)/log(3))*x)/(x*x**( - log(5)/log(3))) == sympify(1)
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
def test_Mul_is_integer():
|
| 398 |
+
k = Symbol('k', integer=True)
|
| 399 |
+
n = Symbol('n', integer=True)
|
| 400 |
+
nr = Symbol('nr', rational=False)
|
| 401 |
+
ir = Symbol('ir', irrational=True)
|
| 402 |
+
nz = Symbol('nz', integer=True, zero=False)
|
| 403 |
+
e = Symbol('e', even=True)
|
| 404 |
+
o = Symbol('o', odd=True)
|
| 405 |
+
i2 = Symbol('2', prime=True, even=True)
|
| 406 |
+
|
| 407 |
+
assert (k/3).is_integer is None
|
| 408 |
+
assert (nz/3).is_integer is None
|
| 409 |
+
assert (nr/3).is_integer is False
|
| 410 |
+
assert (ir/3).is_integer is False
|
| 411 |
+
assert (x*k*n).is_integer is None
|
| 412 |
+
assert (e/2).is_integer is True
|
| 413 |
+
assert (e**2/2).is_integer is True
|
| 414 |
+
assert (2/k).is_integer is None
|
| 415 |
+
assert (2/k**2).is_integer is None
|
| 416 |
+
assert ((-1)**k*n).is_integer is True
|
| 417 |
+
assert (3*k*e/2).is_integer is True
|
| 418 |
+
assert (2*k*e/3).is_integer is None
|
| 419 |
+
assert (e/o).is_integer is None
|
| 420 |
+
assert (o/e).is_integer is False
|
| 421 |
+
assert (o/i2).is_integer is False
|
| 422 |
+
assert Mul(k, 1/k, evaluate=False).is_integer is None
|
| 423 |
+
assert Mul(2., S.Half, evaluate=False).is_integer is None
|
| 424 |
+
assert (2*sqrt(k)).is_integer is None
|
| 425 |
+
assert (2*k**n).is_integer is None
|
| 426 |
+
|
| 427 |
+
s = 2**2**2**Pow(2, 1000, evaluate=False)
|
| 428 |
+
m = Mul(s, s, evaluate=False)
|
| 429 |
+
assert m.is_integer
|
| 430 |
+
|
| 431 |
+
# broken in 1.6 and before, see #20161
|
| 432 |
+
xq = Symbol('xq', rational=True)
|
| 433 |
+
yq = Symbol('yq', rational=True)
|
| 434 |
+
assert (xq*yq).is_integer is None
|
| 435 |
+
e_20161 = Mul(-1,Mul(1,Pow(2,-1,evaluate=False),evaluate=False),evaluate=False)
|
| 436 |
+
assert e_20161.is_integer is not True # expand(e_20161) -> -1/2, but no need to see that in the assumption without evaluation
|
| 437 |
+
|
| 438 |
+
|
| 439 |
+
def test_Add_Mul_is_integer():
|
| 440 |
+
x = Symbol('x')
|
| 441 |
+
|
| 442 |
+
k = Symbol('k', integer=True)
|
| 443 |
+
n = Symbol('n', integer=True)
|
| 444 |
+
nk = Symbol('nk', integer=False)
|
| 445 |
+
nr = Symbol('nr', rational=False)
|
| 446 |
+
nz = Symbol('nz', integer=True, zero=False)
|
| 447 |
+
|
| 448 |
+
assert (-nk).is_integer is None
|
| 449 |
+
assert (-nr).is_integer is False
|
| 450 |
+
assert (2*k).is_integer is True
|
| 451 |
+
assert (-k).is_integer is True
|
| 452 |
+
|
| 453 |
+
assert (k + nk).is_integer is False
|
| 454 |
+
assert (k + n).is_integer is True
|
| 455 |
+
assert (k + x).is_integer is None
|
| 456 |
+
assert (k + n*x).is_integer is None
|
| 457 |
+
assert (k + n/3).is_integer is None
|
| 458 |
+
assert (k + nz/3).is_integer is None
|
| 459 |
+
assert (k + nr/3).is_integer is False
|
| 460 |
+
|
| 461 |
+
assert ((1 + sqrt(3))*(-sqrt(3) + 1)).is_integer is not False
|
| 462 |
+
assert (1 + (1 + sqrt(3))*(-sqrt(3) + 1)).is_integer is not False
|
| 463 |
+
|
| 464 |
+
|
| 465 |
+
def test_Add_Mul_is_finite():
|
| 466 |
+
x = Symbol('x', extended_real=True, finite=False)
|
| 467 |
+
|
| 468 |
+
assert sin(x).is_finite is True
|
| 469 |
+
assert (x*sin(x)).is_finite is None
|
| 470 |
+
assert (x*atan(x)).is_finite is False
|
| 471 |
+
assert (1024*sin(x)).is_finite is True
|
| 472 |
+
assert (sin(x)*exp(x)).is_finite is None
|
| 473 |
+
assert (sin(x)*cos(x)).is_finite is True
|
| 474 |
+
assert (x*sin(x)*exp(x)).is_finite is None
|
| 475 |
+
|
| 476 |
+
assert (sin(x) - 67).is_finite is True
|
| 477 |
+
assert (sin(x) + exp(x)).is_finite is not True
|
| 478 |
+
assert (1 + x).is_finite is False
|
| 479 |
+
assert (1 + x**2 + (1 + x)*(1 - x)).is_finite is None
|
| 480 |
+
assert (sqrt(2)*(1 + x)).is_finite is False
|
| 481 |
+
assert (sqrt(2)*(1 + x)*(1 - x)).is_finite is False
|
| 482 |
+
|
| 483 |
+
|
| 484 |
+
def test_Mul_is_even_odd():
|
| 485 |
+
x = Symbol('x', integer=True)
|
| 486 |
+
y = Symbol('y', integer=True)
|
| 487 |
+
|
| 488 |
+
k = Symbol('k', odd=True)
|
| 489 |
+
n = Symbol('n', odd=True)
|
| 490 |
+
m = Symbol('m', even=True)
|
| 491 |
+
|
| 492 |
+
assert (2*x).is_even is True
|
| 493 |
+
assert (2*x).is_odd is False
|
| 494 |
+
|
| 495 |
+
assert (3*x).is_even is None
|
| 496 |
+
assert (3*x).is_odd is None
|
| 497 |
+
|
| 498 |
+
assert (k/3).is_integer is None
|
| 499 |
+
assert (k/3).is_even is None
|
| 500 |
+
assert (k/3).is_odd is None
|
| 501 |
+
|
| 502 |
+
assert (2*n).is_even is True
|
| 503 |
+
assert (2*n).is_odd is False
|
| 504 |
+
|
| 505 |
+
assert (2*m).is_even is True
|
| 506 |
+
assert (2*m).is_odd is False
|
| 507 |
+
|
| 508 |
+
assert (-n).is_even is False
|
| 509 |
+
assert (-n).is_odd is True
|
| 510 |
+
|
| 511 |
+
assert (k*n).is_even is False
|
| 512 |
+
assert (k*n).is_odd is True
|
| 513 |
+
|
| 514 |
+
assert (k*m).is_even is True
|
| 515 |
+
assert (k*m).is_odd is False
|
| 516 |
+
|
| 517 |
+
assert (k*n*m).is_even is True
|
| 518 |
+
assert (k*n*m).is_odd is False
|
| 519 |
+
|
| 520 |
+
assert (k*m*x).is_even is True
|
| 521 |
+
assert (k*m*x).is_odd is False
|
| 522 |
+
|
| 523 |
+
# issue 6791:
|
| 524 |
+
assert (x/2).is_integer is None
|
| 525 |
+
assert (k/2).is_integer is False
|
| 526 |
+
assert (m/2).is_integer is True
|
| 527 |
+
|
| 528 |
+
assert (x*y).is_even is None
|
| 529 |
+
assert (x*x).is_even is None
|
| 530 |
+
assert (x*(x + k)).is_even is True
|
| 531 |
+
assert (x*(x + m)).is_even is None
|
| 532 |
+
|
| 533 |
+
assert (x*y).is_odd is None
|
| 534 |
+
assert (x*x).is_odd is None
|
| 535 |
+
assert (x*(x + k)).is_odd is False
|
| 536 |
+
assert (x*(x + m)).is_odd is None
|
| 537 |
+
|
| 538 |
+
# issue 8648
|
| 539 |
+
assert (m**2/2).is_even
|
| 540 |
+
assert (m**2/3).is_even is False
|
| 541 |
+
assert (2/m**2).is_odd is False
|
| 542 |
+
assert (2/m).is_odd is None
|
| 543 |
+
|
| 544 |
+
|
| 545 |
+
@XFAIL
|
| 546 |
+
def test_evenness_in_ternary_integer_product_with_odd():
|
| 547 |
+
# Tests that oddness inference is independent of term ordering.
|
| 548 |
+
# Term ordering at the point of testing depends on SymPy's symbol order, so
|
| 549 |
+
# we try to force a different order by modifying symbol names.
|
| 550 |
+
x = Symbol('x', integer=True)
|
| 551 |
+
y = Symbol('y', integer=True)
|
| 552 |
+
k = Symbol('k', odd=True)
|
| 553 |
+
assert (x*y*(y + k)).is_even is True
|
| 554 |
+
assert (y*x*(x + k)).is_even is True
|
| 555 |
+
|
| 556 |
+
|
| 557 |
+
def test_evenness_in_ternary_integer_product_with_even():
|
| 558 |
+
x = Symbol('x', integer=True)
|
| 559 |
+
y = Symbol('y', integer=True)
|
| 560 |
+
m = Symbol('m', even=True)
|
| 561 |
+
assert (x*y*(y + m)).is_even is None
|
| 562 |
+
|
| 563 |
+
|
| 564 |
+
@XFAIL
|
| 565 |
+
def test_oddness_in_ternary_integer_product_with_odd():
|
| 566 |
+
# Tests that oddness inference is independent of term ordering.
|
| 567 |
+
# Term ordering at the point of testing depends on SymPy's symbol order, so
|
| 568 |
+
# we try to force a different order by modifying symbol names.
|
| 569 |
+
x = Symbol('x', integer=True)
|
| 570 |
+
y = Symbol('y', integer=True)
|
| 571 |
+
k = Symbol('k', odd=True)
|
| 572 |
+
assert (x*y*(y + k)).is_odd is False
|
| 573 |
+
assert (y*x*(x + k)).is_odd is False
|
| 574 |
+
|
| 575 |
+
|
| 576 |
+
def test_oddness_in_ternary_integer_product_with_even():
|
| 577 |
+
x = Symbol('x', integer=True)
|
| 578 |
+
y = Symbol('y', integer=True)
|
| 579 |
+
m = Symbol('m', even=True)
|
| 580 |
+
assert (x*y*(y + m)).is_odd is None
|
| 581 |
+
|
| 582 |
+
|
| 583 |
+
def test_Mul_is_rational():
|
| 584 |
+
x = Symbol('x')
|
| 585 |
+
n = Symbol('n', integer=True)
|
| 586 |
+
m = Symbol('m', integer=True, nonzero=True)
|
| 587 |
+
|
| 588 |
+
assert (n/m).is_rational is True
|
| 589 |
+
assert (x/pi).is_rational is None
|
| 590 |
+
assert (x/n).is_rational is None
|
| 591 |
+
assert (m/pi).is_rational is False
|
| 592 |
+
|
| 593 |
+
r = Symbol('r', rational=True)
|
| 594 |
+
assert (pi*r).is_rational is None
|
| 595 |
+
|
| 596 |
+
# issue 8008
|
| 597 |
+
z = Symbol('z', zero=True)
|
| 598 |
+
i = Symbol('i', imaginary=True)
|
| 599 |
+
assert (z*i).is_rational is True
|
| 600 |
+
bi = Symbol('i', imaginary=True, finite=True)
|
| 601 |
+
assert (z*bi).is_zero is True
|
| 602 |
+
|
| 603 |
+
|
| 604 |
+
def test_Add_is_rational():
|
| 605 |
+
x = Symbol('x')
|
| 606 |
+
n = Symbol('n', rational=True)
|
| 607 |
+
m = Symbol('m', rational=True)
|
| 608 |
+
|
| 609 |
+
assert (n + m).is_rational is True
|
| 610 |
+
assert (x + pi).is_rational is None
|
| 611 |
+
assert (x + n).is_rational is None
|
| 612 |
+
assert (n + pi).is_rational is False
|
| 613 |
+
|
| 614 |
+
|
| 615 |
+
def test_Add_is_even_odd():
|
| 616 |
+
x = Symbol('x', integer=True)
|
| 617 |
+
|
| 618 |
+
k = Symbol('k', odd=True)
|
| 619 |
+
n = Symbol('n', odd=True)
|
| 620 |
+
m = Symbol('m', even=True)
|
| 621 |
+
|
| 622 |
+
assert (k + 7).is_even is True
|
| 623 |
+
assert (k + 7).is_odd is False
|
| 624 |
+
|
| 625 |
+
assert (-k + 7).is_even is True
|
| 626 |
+
assert (-k + 7).is_odd is False
|
| 627 |
+
|
| 628 |
+
assert (k - 12).is_even is False
|
| 629 |
+
assert (k - 12).is_odd is True
|
| 630 |
+
|
| 631 |
+
assert (-k - 12).is_even is False
|
| 632 |
+
assert (-k - 12).is_odd is True
|
| 633 |
+
|
| 634 |
+
assert (k + n).is_even is True
|
| 635 |
+
assert (k + n).is_odd is False
|
| 636 |
+
|
| 637 |
+
assert (k + m).is_even is False
|
| 638 |
+
assert (k + m).is_odd is True
|
| 639 |
+
|
| 640 |
+
assert (k + n + m).is_even is True
|
| 641 |
+
assert (k + n + m).is_odd is False
|
| 642 |
+
|
| 643 |
+
assert (k + n + x + m).is_even is None
|
| 644 |
+
assert (k + n + x + m).is_odd is None
|
| 645 |
+
|
| 646 |
+
|
| 647 |
+
def test_Mul_is_negative_positive():
|
| 648 |
+
x = Symbol('x', real=True)
|
| 649 |
+
y = Symbol('y', extended_real=False, complex=True)
|
| 650 |
+
z = Symbol('z', zero=True)
|
| 651 |
+
|
| 652 |
+
e = 2*z
|
| 653 |
+
assert e.is_Mul and e.is_positive is False and e.is_negative is False
|
| 654 |
+
|
| 655 |
+
neg = Symbol('neg', negative=True)
|
| 656 |
+
pos = Symbol('pos', positive=True)
|
| 657 |
+
nneg = Symbol('nneg', nonnegative=True)
|
| 658 |
+
npos = Symbol('npos', nonpositive=True)
|
| 659 |
+
|
| 660 |
+
assert neg.is_negative is True
|
| 661 |
+
assert (-neg).is_negative is False
|
| 662 |
+
assert (2*neg).is_negative is True
|
| 663 |
+
|
| 664 |
+
assert (2*pos)._eval_is_extended_negative() is False
|
| 665 |
+
assert (2*pos).is_negative is False
|
| 666 |
+
|
| 667 |
+
assert pos.is_negative is False
|
| 668 |
+
assert (-pos).is_negative is True
|
| 669 |
+
assert (2*pos).is_negative is False
|
| 670 |
+
|
| 671 |
+
assert (pos*neg).is_negative is True
|
| 672 |
+
assert (2*pos*neg).is_negative is True
|
| 673 |
+
assert (-pos*neg).is_negative is False
|
| 674 |
+
assert (pos*neg*y).is_negative is False # y.is_real=F; !real -> !neg
|
| 675 |
+
|
| 676 |
+
assert nneg.is_negative is False
|
| 677 |
+
assert (-nneg).is_negative is None
|
| 678 |
+
assert (2*nneg).is_negative is False
|
| 679 |
+
|
| 680 |
+
assert npos.is_negative is None
|
| 681 |
+
assert (-npos).is_negative is False
|
| 682 |
+
assert (2*npos).is_negative is None
|
| 683 |
+
|
| 684 |
+
assert (nneg*npos).is_negative is None
|
| 685 |
+
|
| 686 |
+
assert (neg*nneg).is_negative is None
|
| 687 |
+
assert (neg*npos).is_negative is False
|
| 688 |
+
|
| 689 |
+
assert (pos*nneg).is_negative is False
|
| 690 |
+
assert (pos*npos).is_negative is None
|
| 691 |
+
|
| 692 |
+
assert (npos*neg*nneg).is_negative is False
|
| 693 |
+
assert (npos*pos*nneg).is_negative is None
|
| 694 |
+
|
| 695 |
+
assert (-npos*neg*nneg).is_negative is None
|
| 696 |
+
assert (-npos*pos*nneg).is_negative is False
|
| 697 |
+
|
| 698 |
+
assert (17*npos*neg*nneg).is_negative is False
|
| 699 |
+
assert (17*npos*pos*nneg).is_negative is None
|
| 700 |
+
|
| 701 |
+
assert (neg*npos*pos*nneg).is_negative is False
|
| 702 |
+
|
| 703 |
+
assert (x*neg).is_negative is None
|
| 704 |
+
assert (nneg*npos*pos*x*neg).is_negative is None
|
| 705 |
+
|
| 706 |
+
assert neg.is_positive is False
|
| 707 |
+
assert (-neg).is_positive is True
|
| 708 |
+
assert (2*neg).is_positive is False
|
| 709 |
+
|
| 710 |
+
assert pos.is_positive is True
|
| 711 |
+
assert (-pos).is_positive is False
|
| 712 |
+
assert (2*pos).is_positive is True
|
| 713 |
+
|
| 714 |
+
assert (pos*neg).is_positive is False
|
| 715 |
+
assert (2*pos*neg).is_positive is False
|
| 716 |
+
assert (-pos*neg).is_positive is True
|
| 717 |
+
assert (-pos*neg*y).is_positive is False # y.is_real=F; !real -> !neg
|
| 718 |
+
|
| 719 |
+
assert nneg.is_positive is None
|
| 720 |
+
assert (-nneg).is_positive is False
|
| 721 |
+
assert (2*nneg).is_positive is None
|
| 722 |
+
|
| 723 |
+
assert npos.is_positive is False
|
| 724 |
+
assert (-npos).is_positive is None
|
| 725 |
+
assert (2*npos).is_positive is False
|
| 726 |
+
|
| 727 |
+
assert (nneg*npos).is_positive is False
|
| 728 |
+
|
| 729 |
+
assert (neg*nneg).is_positive is False
|
| 730 |
+
assert (neg*npos).is_positive is None
|
| 731 |
+
|
| 732 |
+
assert (pos*nneg).is_positive is None
|
| 733 |
+
assert (pos*npos).is_positive is False
|
| 734 |
+
|
| 735 |
+
assert (npos*neg*nneg).is_positive is None
|
| 736 |
+
assert (npos*pos*nneg).is_positive is False
|
| 737 |
+
|
| 738 |
+
assert (-npos*neg*nneg).is_positive is False
|
| 739 |
+
assert (-npos*pos*nneg).is_positive is None
|
| 740 |
+
|
| 741 |
+
assert (17*npos*neg*nneg).is_positive is None
|
| 742 |
+
assert (17*npos*pos*nneg).is_positive is False
|
| 743 |
+
|
| 744 |
+
assert (neg*npos*pos*nneg).is_positive is None
|
| 745 |
+
|
| 746 |
+
assert (x*neg).is_positive is None
|
| 747 |
+
assert (nneg*npos*pos*x*neg).is_positive is None
|
| 748 |
+
|
| 749 |
+
|
| 750 |
+
def test_Mul_is_negative_positive_2():
|
| 751 |
+
a = Symbol('a', nonnegative=True)
|
| 752 |
+
b = Symbol('b', nonnegative=True)
|
| 753 |
+
c = Symbol('c', nonpositive=True)
|
| 754 |
+
d = Symbol('d', nonpositive=True)
|
| 755 |
+
|
| 756 |
+
assert (a*b).is_nonnegative is True
|
| 757 |
+
assert (a*b).is_negative is False
|
| 758 |
+
assert (a*b).is_zero is None
|
| 759 |
+
assert (a*b).is_positive is None
|
| 760 |
+
|
| 761 |
+
assert (c*d).is_nonnegative is True
|
| 762 |
+
assert (c*d).is_negative is False
|
| 763 |
+
assert (c*d).is_zero is None
|
| 764 |
+
assert (c*d).is_positive is None
|
| 765 |
+
|
| 766 |
+
assert (a*c).is_nonpositive is True
|
| 767 |
+
assert (a*c).is_positive is False
|
| 768 |
+
assert (a*c).is_zero is None
|
| 769 |
+
assert (a*c).is_negative is None
|
| 770 |
+
|
| 771 |
+
|
| 772 |
+
def test_Mul_is_nonpositive_nonnegative():
|
| 773 |
+
x = Symbol('x', real=True)
|
| 774 |
+
|
| 775 |
+
k = Symbol('k', negative=True)
|
| 776 |
+
n = Symbol('n', positive=True)
|
| 777 |
+
u = Symbol('u', nonnegative=True)
|
| 778 |
+
v = Symbol('v', nonpositive=True)
|
| 779 |
+
|
| 780 |
+
assert k.is_nonpositive is True
|
| 781 |
+
assert (-k).is_nonpositive is False
|
| 782 |
+
assert (2*k).is_nonpositive is True
|
| 783 |
+
|
| 784 |
+
assert n.is_nonpositive is False
|
| 785 |
+
assert (-n).is_nonpositive is True
|
| 786 |
+
assert (2*n).is_nonpositive is False
|
| 787 |
+
|
| 788 |
+
assert (n*k).is_nonpositive is True
|
| 789 |
+
assert (2*n*k).is_nonpositive is True
|
| 790 |
+
assert (-n*k).is_nonpositive is False
|
| 791 |
+
|
| 792 |
+
assert u.is_nonpositive is None
|
| 793 |
+
assert (-u).is_nonpositive is True
|
| 794 |
+
assert (2*u).is_nonpositive is None
|
| 795 |
+
|
| 796 |
+
assert v.is_nonpositive is True
|
| 797 |
+
assert (-v).is_nonpositive is None
|
| 798 |
+
assert (2*v).is_nonpositive is True
|
| 799 |
+
|
| 800 |
+
assert (u*v).is_nonpositive is True
|
| 801 |
+
|
| 802 |
+
assert (k*u).is_nonpositive is True
|
| 803 |
+
assert (k*v).is_nonpositive is None
|
| 804 |
+
|
| 805 |
+
assert (n*u).is_nonpositive is None
|
| 806 |
+
assert (n*v).is_nonpositive is True
|
| 807 |
+
|
| 808 |
+
assert (v*k*u).is_nonpositive is None
|
| 809 |
+
assert (v*n*u).is_nonpositive is True
|
| 810 |
+
|
| 811 |
+
assert (-v*k*u).is_nonpositive is True
|
| 812 |
+
assert (-v*n*u).is_nonpositive is None
|
| 813 |
+
|
| 814 |
+
assert (17*v*k*u).is_nonpositive is None
|
| 815 |
+
assert (17*v*n*u).is_nonpositive is True
|
| 816 |
+
|
| 817 |
+
assert (k*v*n*u).is_nonpositive is None
|
| 818 |
+
|
| 819 |
+
assert (x*k).is_nonpositive is None
|
| 820 |
+
assert (u*v*n*x*k).is_nonpositive is None
|
| 821 |
+
|
| 822 |
+
assert k.is_nonnegative is False
|
| 823 |
+
assert (-k).is_nonnegative is True
|
| 824 |
+
assert (2*k).is_nonnegative is False
|
| 825 |
+
|
| 826 |
+
assert n.is_nonnegative is True
|
| 827 |
+
assert (-n).is_nonnegative is False
|
| 828 |
+
assert (2*n).is_nonnegative is True
|
| 829 |
+
|
| 830 |
+
assert (n*k).is_nonnegative is False
|
| 831 |
+
assert (2*n*k).is_nonnegative is False
|
| 832 |
+
assert (-n*k).is_nonnegative is True
|
| 833 |
+
|
| 834 |
+
assert u.is_nonnegative is True
|
| 835 |
+
assert (-u).is_nonnegative is None
|
| 836 |
+
assert (2*u).is_nonnegative is True
|
| 837 |
+
|
| 838 |
+
assert v.is_nonnegative is None
|
| 839 |
+
assert (-v).is_nonnegative is True
|
| 840 |
+
assert (2*v).is_nonnegative is None
|
| 841 |
+
|
| 842 |
+
assert (u*v).is_nonnegative is None
|
| 843 |
+
|
| 844 |
+
assert (k*u).is_nonnegative is None
|
| 845 |
+
assert (k*v).is_nonnegative is True
|
| 846 |
+
|
| 847 |
+
assert (n*u).is_nonnegative is True
|
| 848 |
+
assert (n*v).is_nonnegative is None
|
| 849 |
+
|
| 850 |
+
assert (v*k*u).is_nonnegative is True
|
| 851 |
+
assert (v*n*u).is_nonnegative is None
|
| 852 |
+
|
| 853 |
+
assert (-v*k*u).is_nonnegative is None
|
| 854 |
+
assert (-v*n*u).is_nonnegative is True
|
| 855 |
+
|
| 856 |
+
assert (17*v*k*u).is_nonnegative is True
|
| 857 |
+
assert (17*v*n*u).is_nonnegative is None
|
| 858 |
+
|
| 859 |
+
assert (k*v*n*u).is_nonnegative is True
|
| 860 |
+
|
| 861 |
+
assert (x*k).is_nonnegative is None
|
| 862 |
+
assert (u*v*n*x*k).is_nonnegative is None
|
| 863 |
+
|
| 864 |
+
|
| 865 |
+
def test_Add_is_negative_positive():
|
| 866 |
+
x = Symbol('x', real=True)
|
| 867 |
+
|
| 868 |
+
k = Symbol('k', negative=True)
|
| 869 |
+
n = Symbol('n', positive=True)
|
| 870 |
+
u = Symbol('u', nonnegative=True)
|
| 871 |
+
v = Symbol('v', nonpositive=True)
|
| 872 |
+
|
| 873 |
+
assert (k - 2).is_negative is True
|
| 874 |
+
assert (k + 17).is_negative is None
|
| 875 |
+
assert (-k - 5).is_negative is None
|
| 876 |
+
assert (-k + 123).is_negative is False
|
| 877 |
+
|
| 878 |
+
assert (k - n).is_negative is True
|
| 879 |
+
assert (k + n).is_negative is None
|
| 880 |
+
assert (-k - n).is_negative is None
|
| 881 |
+
assert (-k + n).is_negative is False
|
| 882 |
+
|
| 883 |
+
assert (k - n - 2).is_negative is True
|
| 884 |
+
assert (k + n + 17).is_negative is None
|
| 885 |
+
assert (-k - n - 5).is_negative is None
|
| 886 |
+
assert (-k + n + 123).is_negative is False
|
| 887 |
+
|
| 888 |
+
assert (-2*k + 123*n + 17).is_negative is False
|
| 889 |
+
|
| 890 |
+
assert (k + u).is_negative is None
|
| 891 |
+
assert (k + v).is_negative is True
|
| 892 |
+
assert (n + u).is_negative is False
|
| 893 |
+
assert (n + v).is_negative is None
|
| 894 |
+
|
| 895 |
+
assert (u - v).is_negative is False
|
| 896 |
+
assert (u + v).is_negative is None
|
| 897 |
+
assert (-u - v).is_negative is None
|
| 898 |
+
assert (-u + v).is_negative is None
|
| 899 |
+
|
| 900 |
+
assert (u - v + n + 2).is_negative is False
|
| 901 |
+
assert (u + v + n + 2).is_negative is None
|
| 902 |
+
assert (-u - v + n + 2).is_negative is None
|
| 903 |
+
assert (-u + v + n + 2).is_negative is None
|
| 904 |
+
|
| 905 |
+
assert (k + x).is_negative is None
|
| 906 |
+
assert (k + x - n).is_negative is None
|
| 907 |
+
|
| 908 |
+
assert (k - 2).is_positive is False
|
| 909 |
+
assert (k + 17).is_positive is None
|
| 910 |
+
assert (-k - 5).is_positive is None
|
| 911 |
+
assert (-k + 123).is_positive is True
|
| 912 |
+
|
| 913 |
+
assert (k - n).is_positive is False
|
| 914 |
+
assert (k + n).is_positive is None
|
| 915 |
+
assert (-k - n).is_positive is None
|
| 916 |
+
assert (-k + n).is_positive is True
|
| 917 |
+
|
| 918 |
+
assert (k - n - 2).is_positive is False
|
| 919 |
+
assert (k + n + 17).is_positive is None
|
| 920 |
+
assert (-k - n - 5).is_positive is None
|
| 921 |
+
assert (-k + n + 123).is_positive is True
|
| 922 |
+
|
| 923 |
+
assert (-2*k + 123*n + 17).is_positive is True
|
| 924 |
+
|
| 925 |
+
assert (k + u).is_positive is None
|
| 926 |
+
assert (k + v).is_positive is False
|
| 927 |
+
assert (n + u).is_positive is True
|
| 928 |
+
assert (n + v).is_positive is None
|
| 929 |
+
|
| 930 |
+
assert (u - v).is_positive is None
|
| 931 |
+
assert (u + v).is_positive is None
|
| 932 |
+
assert (-u - v).is_positive is None
|
| 933 |
+
assert (-u + v).is_positive is False
|
| 934 |
+
|
| 935 |
+
assert (u - v - n - 2).is_positive is None
|
| 936 |
+
assert (u + v - n - 2).is_positive is None
|
| 937 |
+
assert (-u - v - n - 2).is_positive is None
|
| 938 |
+
assert (-u + v - n - 2).is_positive is False
|
| 939 |
+
|
| 940 |
+
assert (n + x).is_positive is None
|
| 941 |
+
assert (n + x - k).is_positive is None
|
| 942 |
+
|
| 943 |
+
z = (-3 - sqrt(5) + (-sqrt(10)/2 - sqrt(2)/2)**2)
|
| 944 |
+
assert z.is_zero
|
| 945 |
+
z = sqrt(1 + sqrt(3)) + sqrt(3 + 3*sqrt(3)) - sqrt(10 + 6*sqrt(3))
|
| 946 |
+
assert z.is_zero
|
| 947 |
+
|
| 948 |
+
|
| 949 |
+
def test_Add_is_nonpositive_nonnegative():
|
| 950 |
+
x = Symbol('x', real=True)
|
| 951 |
+
|
| 952 |
+
k = Symbol('k', negative=True)
|
| 953 |
+
n = Symbol('n', positive=True)
|
| 954 |
+
u = Symbol('u', nonnegative=True)
|
| 955 |
+
v = Symbol('v', nonpositive=True)
|
| 956 |
+
|
| 957 |
+
assert (u - 2).is_nonpositive is None
|
| 958 |
+
assert (u + 17).is_nonpositive is False
|
| 959 |
+
assert (-u - 5).is_nonpositive is True
|
| 960 |
+
assert (-u + 123).is_nonpositive is None
|
| 961 |
+
|
| 962 |
+
assert (u - v).is_nonpositive is None
|
| 963 |
+
assert (u + v).is_nonpositive is None
|
| 964 |
+
assert (-u - v).is_nonpositive is None
|
| 965 |
+
assert (-u + v).is_nonpositive is True
|
| 966 |
+
|
| 967 |
+
assert (u - v - 2).is_nonpositive is None
|
| 968 |
+
assert (u + v + 17).is_nonpositive is None
|
| 969 |
+
assert (-u - v - 5).is_nonpositive is None
|
| 970 |
+
assert (-u + v - 123).is_nonpositive is True
|
| 971 |
+
|
| 972 |
+
assert (-2*u + 123*v - 17).is_nonpositive is True
|
| 973 |
+
|
| 974 |
+
assert (k + u).is_nonpositive is None
|
| 975 |
+
assert (k + v).is_nonpositive is True
|
| 976 |
+
assert (n + u).is_nonpositive is False
|
| 977 |
+
assert (n + v).is_nonpositive is None
|
| 978 |
+
|
| 979 |
+
assert (k - n).is_nonpositive is True
|
| 980 |
+
assert (k + n).is_nonpositive is None
|
| 981 |
+
assert (-k - n).is_nonpositive is None
|
| 982 |
+
assert (-k + n).is_nonpositive is False
|
| 983 |
+
|
| 984 |
+
assert (k - n + u + 2).is_nonpositive is None
|
| 985 |
+
assert (k + n + u + 2).is_nonpositive is None
|
| 986 |
+
assert (-k - n + u + 2).is_nonpositive is None
|
| 987 |
+
assert (-k + n + u + 2).is_nonpositive is False
|
| 988 |
+
|
| 989 |
+
assert (u + x).is_nonpositive is None
|
| 990 |
+
assert (v - x - n).is_nonpositive is None
|
| 991 |
+
|
| 992 |
+
assert (u - 2).is_nonnegative is None
|
| 993 |
+
assert (u + 17).is_nonnegative is True
|
| 994 |
+
assert (-u - 5).is_nonnegative is False
|
| 995 |
+
assert (-u + 123).is_nonnegative is None
|
| 996 |
+
|
| 997 |
+
assert (u - v).is_nonnegative is True
|
| 998 |
+
assert (u + v).is_nonnegative is None
|
| 999 |
+
assert (-u - v).is_nonnegative is None
|
| 1000 |
+
assert (-u + v).is_nonnegative is None
|
| 1001 |
+
|
| 1002 |
+
assert (u - v + 2).is_nonnegative is True
|
| 1003 |
+
assert (u + v + 17).is_nonnegative is None
|
| 1004 |
+
assert (-u - v - 5).is_nonnegative is None
|
| 1005 |
+
assert (-u + v - 123).is_nonnegative is False
|
| 1006 |
+
|
| 1007 |
+
assert (2*u - 123*v + 17).is_nonnegative is True
|
| 1008 |
+
|
| 1009 |
+
assert (k + u).is_nonnegative is None
|
| 1010 |
+
assert (k + v).is_nonnegative is False
|
| 1011 |
+
assert (n + u).is_nonnegative is True
|
| 1012 |
+
assert (n + v).is_nonnegative is None
|
| 1013 |
+
|
| 1014 |
+
assert (k - n).is_nonnegative is False
|
| 1015 |
+
assert (k + n).is_nonnegative is None
|
| 1016 |
+
assert (-k - n).is_nonnegative is None
|
| 1017 |
+
assert (-k + n).is_nonnegative is True
|
| 1018 |
+
|
| 1019 |
+
assert (k - n - u - 2).is_nonnegative is False
|
| 1020 |
+
assert (k + n - u - 2).is_nonnegative is None
|
| 1021 |
+
assert (-k - n - u - 2).is_nonnegative is None
|
| 1022 |
+
assert (-k + n - u - 2).is_nonnegative is None
|
| 1023 |
+
|
| 1024 |
+
assert (u - x).is_nonnegative is None
|
| 1025 |
+
assert (v + x + n).is_nonnegative is None
|
| 1026 |
+
|
| 1027 |
+
|
| 1028 |
+
def test_Pow_is_integer():
|
| 1029 |
+
x = Symbol('x')
|
| 1030 |
+
|
| 1031 |
+
k = Symbol('k', integer=True)
|
| 1032 |
+
n = Symbol('n', integer=True, nonnegative=True)
|
| 1033 |
+
m = Symbol('m', integer=True, positive=True)
|
| 1034 |
+
|
| 1035 |
+
assert (k**2).is_integer is True
|
| 1036 |
+
assert (k**(-2)).is_integer is None
|
| 1037 |
+
assert ((m + 1)**(-2)).is_integer is False
|
| 1038 |
+
assert (m**(-1)).is_integer is None # issue 8580
|
| 1039 |
+
|
| 1040 |
+
assert (2**k).is_integer is None
|
| 1041 |
+
assert (2**(-k)).is_integer is None
|
| 1042 |
+
|
| 1043 |
+
assert (2**n).is_integer is True
|
| 1044 |
+
assert (2**(-n)).is_integer is None
|
| 1045 |
+
|
| 1046 |
+
assert (2**m).is_integer is True
|
| 1047 |
+
assert (2**(-m)).is_integer is False
|
| 1048 |
+
|
| 1049 |
+
assert (x**2).is_integer is None
|
| 1050 |
+
assert (2**x).is_integer is None
|
| 1051 |
+
|
| 1052 |
+
assert (k**n).is_integer is True
|
| 1053 |
+
assert (k**(-n)).is_integer is None
|
| 1054 |
+
|
| 1055 |
+
assert (k**x).is_integer is None
|
| 1056 |
+
assert (x**k).is_integer is None
|
| 1057 |
+
|
| 1058 |
+
assert (k**(n*m)).is_integer is True
|
| 1059 |
+
assert (k**(-n*m)).is_integer is None
|
| 1060 |
+
|
| 1061 |
+
assert sqrt(3).is_integer is False
|
| 1062 |
+
assert sqrt(.3).is_integer is False
|
| 1063 |
+
assert Pow(3, 2, evaluate=False).is_integer is True
|
| 1064 |
+
assert Pow(3, 0, evaluate=False).is_integer is True
|
| 1065 |
+
assert Pow(3, -2, evaluate=False).is_integer is False
|
| 1066 |
+
assert Pow(S.Half, 3, evaluate=False).is_integer is False
|
| 1067 |
+
# decided by re-evaluating
|
| 1068 |
+
assert Pow(3, S.Half, evaluate=False).is_integer is False
|
| 1069 |
+
assert Pow(3, S.Half, evaluate=False).is_integer is False
|
| 1070 |
+
assert Pow(4, S.Half, evaluate=False).is_integer is True
|
| 1071 |
+
assert Pow(S.Half, -2, evaluate=False).is_integer is True
|
| 1072 |
+
|
| 1073 |
+
assert ((-1)**k).is_integer
|
| 1074 |
+
|
| 1075 |
+
# issue 8641
|
| 1076 |
+
x = Symbol('x', real=True, integer=False)
|
| 1077 |
+
assert (x**2).is_integer is None
|
| 1078 |
+
|
| 1079 |
+
# issue 10458
|
| 1080 |
+
x = Symbol('x', positive=True)
|
| 1081 |
+
assert (1/(x + 1)).is_integer is False
|
| 1082 |
+
assert (1/(-x - 1)).is_integer is False
|
| 1083 |
+
assert (-1/(x + 1)).is_integer is False
|
| 1084 |
+
# issue 23287
|
| 1085 |
+
assert (x**2/2).is_integer is None
|
| 1086 |
+
|
| 1087 |
+
# issue 8648-like
|
| 1088 |
+
k = Symbol('k', even=True)
|
| 1089 |
+
assert (k**3/2).is_integer
|
| 1090 |
+
assert (k**3/8).is_integer
|
| 1091 |
+
assert (k**3/16).is_integer is None
|
| 1092 |
+
assert (2/k).is_integer is None
|
| 1093 |
+
assert (2/k**2).is_integer is False
|
| 1094 |
+
o = Symbol('o', odd=True)
|
| 1095 |
+
assert (k/o).is_integer is None
|
| 1096 |
+
o = Symbol('o', odd=True, prime=True)
|
| 1097 |
+
assert (k/o).is_integer is False
|
| 1098 |
+
|
| 1099 |
+
|
| 1100 |
+
def test_Pow_is_real():
|
| 1101 |
+
x = Symbol('x', real=True)
|
| 1102 |
+
y = Symbol('y', positive=True)
|
| 1103 |
+
|
| 1104 |
+
assert (x**2).is_real is True
|
| 1105 |
+
assert (x**3).is_real is True
|
| 1106 |
+
assert (x**x).is_real is None
|
| 1107 |
+
assert (y**x).is_real is True
|
| 1108 |
+
|
| 1109 |
+
assert (x**Rational(1, 3)).is_real is None
|
| 1110 |
+
assert (y**Rational(1, 3)).is_real is True
|
| 1111 |
+
|
| 1112 |
+
assert sqrt(-1 - sqrt(2)).is_real is False
|
| 1113 |
+
|
| 1114 |
+
i = Symbol('i', imaginary=True)
|
| 1115 |
+
assert (i**i).is_real is None
|
| 1116 |
+
assert (I**i).is_extended_real is True
|
| 1117 |
+
assert ((-I)**i).is_extended_real is True
|
| 1118 |
+
assert (2**i).is_real is None # (2**(pi/log(2) * I)) is real, 2**I is not
|
| 1119 |
+
assert (2**I).is_real is False
|
| 1120 |
+
assert (2**-I).is_real is False
|
| 1121 |
+
assert (i**2).is_extended_real is True
|
| 1122 |
+
assert (i**3).is_extended_real is False
|
| 1123 |
+
assert (i**x).is_real is None # could be (-I)**(2/3)
|
| 1124 |
+
e = Symbol('e', even=True)
|
| 1125 |
+
o = Symbol('o', odd=True)
|
| 1126 |
+
k = Symbol('k', integer=True)
|
| 1127 |
+
assert (i**e).is_extended_real is True
|
| 1128 |
+
assert (i**o).is_extended_real is False
|
| 1129 |
+
assert (i**k).is_real is None
|
| 1130 |
+
assert (i**(4*k)).is_extended_real is True
|
| 1131 |
+
|
| 1132 |
+
x = Symbol("x", nonnegative=True)
|
| 1133 |
+
y = Symbol("y", nonnegative=True)
|
| 1134 |
+
assert im(x**y).expand(complex=True) is S.Zero
|
| 1135 |
+
assert (x**y).is_real is True
|
| 1136 |
+
i = Symbol('i', imaginary=True)
|
| 1137 |
+
assert (exp(i)**I).is_extended_real is True
|
| 1138 |
+
assert log(exp(i)).is_imaginary is None # i could be 2*pi*I
|
| 1139 |
+
c = Symbol('c', complex=True)
|
| 1140 |
+
assert log(c).is_real is None # c could be 0 or 2, too
|
| 1141 |
+
assert log(exp(c)).is_real is None # log(0), log(E), ...
|
| 1142 |
+
n = Symbol('n', negative=False)
|
| 1143 |
+
assert log(n).is_real is None
|
| 1144 |
+
n = Symbol('n', nonnegative=True)
|
| 1145 |
+
assert log(n).is_real is None
|
| 1146 |
+
|
| 1147 |
+
assert sqrt(-I).is_real is False # issue 7843
|
| 1148 |
+
|
| 1149 |
+
i = Symbol('i', integer=True)
|
| 1150 |
+
assert (1/(i-1)).is_real is None
|
| 1151 |
+
assert (1/(i-1)).is_extended_real is None
|
| 1152 |
+
|
| 1153 |
+
# test issue 20715
|
| 1154 |
+
from sympy.core.parameters import evaluate
|
| 1155 |
+
x = S(-1)
|
| 1156 |
+
with evaluate(False):
|
| 1157 |
+
assert x.is_negative is True
|
| 1158 |
+
|
| 1159 |
+
f = Pow(x, -1)
|
| 1160 |
+
with evaluate(False):
|
| 1161 |
+
assert f.is_imaginary is False
|
| 1162 |
+
|
| 1163 |
+
|
| 1164 |
+
def test_real_Pow():
|
| 1165 |
+
k = Symbol('k', integer=True, nonzero=True)
|
| 1166 |
+
assert (k**(I*pi/log(k))).is_real
|
| 1167 |
+
|
| 1168 |
+
|
| 1169 |
+
def test_Pow_is_finite():
|
| 1170 |
+
xe = Symbol('xe', extended_real=True)
|
| 1171 |
+
xr = Symbol('xr', real=True)
|
| 1172 |
+
p = Symbol('p', positive=True)
|
| 1173 |
+
n = Symbol('n', negative=True)
|
| 1174 |
+
i = Symbol('i', integer=True)
|
| 1175 |
+
|
| 1176 |
+
assert (xe**2).is_finite is None # xe could be oo
|
| 1177 |
+
assert (xr**2).is_finite is True
|
| 1178 |
+
|
| 1179 |
+
assert (xe**xe).is_finite is None
|
| 1180 |
+
assert (xr**xe).is_finite is None
|
| 1181 |
+
assert (xe**xr).is_finite is None
|
| 1182 |
+
# FIXME: The line below should be True rather than None
|
| 1183 |
+
# assert (xr**xr).is_finite is True
|
| 1184 |
+
assert (xr**xr).is_finite is None
|
| 1185 |
+
|
| 1186 |
+
assert (p**xe).is_finite is None
|
| 1187 |
+
assert (p**xr).is_finite is True
|
| 1188 |
+
|
| 1189 |
+
assert (n**xe).is_finite is None
|
| 1190 |
+
assert (n**xr).is_finite is True
|
| 1191 |
+
|
| 1192 |
+
assert (sin(xe)**2).is_finite is True
|
| 1193 |
+
assert (sin(xr)**2).is_finite is True
|
| 1194 |
+
|
| 1195 |
+
assert (sin(xe)**xe).is_finite is None # xe, xr could be -pi
|
| 1196 |
+
assert (sin(xr)**xr).is_finite is None
|
| 1197 |
+
|
| 1198 |
+
# FIXME: Should the line below be True rather than None?
|
| 1199 |
+
assert (sin(xe)**exp(xe)).is_finite is None
|
| 1200 |
+
assert (sin(xr)**exp(xr)).is_finite is True
|
| 1201 |
+
|
| 1202 |
+
assert (1/sin(xe)).is_finite is None # if zero, no, otherwise yes
|
| 1203 |
+
assert (1/sin(xr)).is_finite is None
|
| 1204 |
+
|
| 1205 |
+
assert (1/exp(xe)).is_finite is None # xe could be -oo
|
| 1206 |
+
assert (1/exp(xr)).is_finite is True
|
| 1207 |
+
|
| 1208 |
+
assert (1/S.Pi).is_finite is True
|
| 1209 |
+
|
| 1210 |
+
assert (1/(i-1)).is_finite is None
|
| 1211 |
+
|
| 1212 |
+
|
| 1213 |
+
def test_Pow_is_even_odd():
|
| 1214 |
+
x = Symbol('x')
|
| 1215 |
+
|
| 1216 |
+
k = Symbol('k', even=True)
|
| 1217 |
+
n = Symbol('n', odd=True)
|
| 1218 |
+
m = Symbol('m', integer=True, nonnegative=True)
|
| 1219 |
+
p = Symbol('p', integer=True, positive=True)
|
| 1220 |
+
|
| 1221 |
+
assert ((-1)**n).is_odd
|
| 1222 |
+
assert ((-1)**k).is_odd
|
| 1223 |
+
assert ((-1)**(m - p)).is_odd
|
| 1224 |
+
|
| 1225 |
+
assert (k**2).is_even is True
|
| 1226 |
+
assert (n**2).is_even is False
|
| 1227 |
+
assert (2**k).is_even is None
|
| 1228 |
+
assert (x**2).is_even is None
|
| 1229 |
+
|
| 1230 |
+
assert (k**m).is_even is None
|
| 1231 |
+
assert (n**m).is_even is False
|
| 1232 |
+
|
| 1233 |
+
assert (k**p).is_even is True
|
| 1234 |
+
assert (n**p).is_even is False
|
| 1235 |
+
|
| 1236 |
+
assert (m**k).is_even is None
|
| 1237 |
+
assert (p**k).is_even is None
|
| 1238 |
+
|
| 1239 |
+
assert (m**n).is_even is None
|
| 1240 |
+
assert (p**n).is_even is None
|
| 1241 |
+
|
| 1242 |
+
assert (k**x).is_even is None
|
| 1243 |
+
assert (n**x).is_even is None
|
| 1244 |
+
|
| 1245 |
+
assert (k**2).is_odd is False
|
| 1246 |
+
assert (n**2).is_odd is True
|
| 1247 |
+
assert (3**k).is_odd is None
|
| 1248 |
+
|
| 1249 |
+
assert (k**m).is_odd is None
|
| 1250 |
+
assert (n**m).is_odd is True
|
| 1251 |
+
|
| 1252 |
+
assert (k**p).is_odd is False
|
| 1253 |
+
assert (n**p).is_odd is True
|
| 1254 |
+
|
| 1255 |
+
assert (m**k).is_odd is None
|
| 1256 |
+
assert (p**k).is_odd is None
|
| 1257 |
+
|
| 1258 |
+
assert (m**n).is_odd is None
|
| 1259 |
+
assert (p**n).is_odd is None
|
| 1260 |
+
|
| 1261 |
+
assert (k**x).is_odd is None
|
| 1262 |
+
assert (n**x).is_odd is None
|
| 1263 |
+
|
| 1264 |
+
|
| 1265 |
+
def test_Pow_is_negative_positive():
|
| 1266 |
+
r = Symbol('r', real=True)
|
| 1267 |
+
|
| 1268 |
+
k = Symbol('k', integer=True, positive=True)
|
| 1269 |
+
n = Symbol('n', even=True)
|
| 1270 |
+
m = Symbol('m', odd=True)
|
| 1271 |
+
|
| 1272 |
+
x = Symbol('x')
|
| 1273 |
+
|
| 1274 |
+
assert (2**r).is_positive is True
|
| 1275 |
+
assert ((-2)**r).is_positive is None
|
| 1276 |
+
assert ((-2)**n).is_positive is True
|
| 1277 |
+
assert ((-2)**m).is_positive is False
|
| 1278 |
+
|
| 1279 |
+
assert (k**2).is_positive is True
|
| 1280 |
+
assert (k**(-2)).is_positive is True
|
| 1281 |
+
|
| 1282 |
+
assert (k**r).is_positive is True
|
| 1283 |
+
assert ((-k)**r).is_positive is None
|
| 1284 |
+
assert ((-k)**n).is_positive is True
|
| 1285 |
+
assert ((-k)**m).is_positive is False
|
| 1286 |
+
|
| 1287 |
+
assert (2**r).is_negative is False
|
| 1288 |
+
assert ((-2)**r).is_negative is None
|
| 1289 |
+
assert ((-2)**n).is_negative is False
|
| 1290 |
+
assert ((-2)**m).is_negative is True
|
| 1291 |
+
|
| 1292 |
+
assert (k**2).is_negative is False
|
| 1293 |
+
assert (k**(-2)).is_negative is False
|
| 1294 |
+
|
| 1295 |
+
assert (k**r).is_negative is False
|
| 1296 |
+
assert ((-k)**r).is_negative is None
|
| 1297 |
+
assert ((-k)**n).is_negative is False
|
| 1298 |
+
assert ((-k)**m).is_negative is True
|
| 1299 |
+
|
| 1300 |
+
assert (2**x).is_positive is None
|
| 1301 |
+
assert (2**x).is_negative is None
|
| 1302 |
+
|
| 1303 |
+
|
| 1304 |
+
def test_Pow_is_zero():
|
| 1305 |
+
z = Symbol('z', zero=True)
|
| 1306 |
+
e = z**2
|
| 1307 |
+
assert e.is_zero
|
| 1308 |
+
assert e.is_positive is False
|
| 1309 |
+
assert e.is_negative is False
|
| 1310 |
+
|
| 1311 |
+
assert Pow(0, 0, evaluate=False).is_zero is False
|
| 1312 |
+
assert Pow(0, 3, evaluate=False).is_zero
|
| 1313 |
+
assert Pow(0, oo, evaluate=False).is_zero
|
| 1314 |
+
assert Pow(0, -3, evaluate=False).is_zero is False
|
| 1315 |
+
assert Pow(0, -oo, evaluate=False).is_zero is False
|
| 1316 |
+
assert Pow(2, 2, evaluate=False).is_zero is False
|
| 1317 |
+
|
| 1318 |
+
a = Symbol('a', zero=False)
|
| 1319 |
+
assert Pow(a, 3).is_zero is False # issue 7965
|
| 1320 |
+
|
| 1321 |
+
assert Pow(2, oo, evaluate=False).is_zero is False
|
| 1322 |
+
assert Pow(2, -oo, evaluate=False).is_zero
|
| 1323 |
+
assert Pow(S.Half, oo, evaluate=False).is_zero
|
| 1324 |
+
assert Pow(S.Half, -oo, evaluate=False).is_zero is False
|
| 1325 |
+
|
| 1326 |
+
# All combinations of real/complex base/exponent
|
| 1327 |
+
h = S.Half
|
| 1328 |
+
T = True
|
| 1329 |
+
F = False
|
| 1330 |
+
N = None
|
| 1331 |
+
|
| 1332 |
+
pow_iszero = [
|
| 1333 |
+
['**', 0, h, 1, 2, -h, -1,-2,-2*I,-I/2,I/2,1+I,oo,-oo,zoo],
|
| 1334 |
+
[ 0, F, T, T, T, F, F, F, F, F, F, N, T, F, N],
|
| 1335 |
+
[ h, F, F, F, F, F, F, F, F, F, F, F, T, F, N],
|
| 1336 |
+
[ 1, F, F, F, F, F, F, F, F, F, F, F, F, F, N],
|
| 1337 |
+
[ 2, F, F, F, F, F, F, F, F, F, F, F, F, T, N],
|
| 1338 |
+
[ -h, F, F, F, F, F, F, F, F, F, F, F, T, F, N],
|
| 1339 |
+
[ -1, F, F, F, F, F, F, F, F, F, F, F, F, F, N],
|
| 1340 |
+
[ -2, F, F, F, F, F, F, F, F, F, F, F, F, T, N],
|
| 1341 |
+
[-2*I, F, F, F, F, F, F, F, F, F, F, F, F, T, N],
|
| 1342 |
+
[-I/2, F, F, F, F, F, F, F, F, F, F, F, T, F, N],
|
| 1343 |
+
[ I/2, F, F, F, F, F, F, F, F, F, F, F, T, F, N],
|
| 1344 |
+
[ 1+I, F, F, F, F, F, F, F, F, F, F, F, F, T, N],
|
| 1345 |
+
[ oo, F, F, F, F, T, T, T, F, F, F, F, F, T, N],
|
| 1346 |
+
[ -oo, F, F, F, F, T, T, T, F, F, F, F, F, T, N],
|
| 1347 |
+
[ zoo, F, F, F, F, T, T, T, N, N, N, N, F, T, N]
|
| 1348 |
+
]
|
| 1349 |
+
|
| 1350 |
+
def test_table(table):
|
| 1351 |
+
n = len(table[0])
|
| 1352 |
+
for row in range(1, n):
|
| 1353 |
+
base = table[row][0]
|
| 1354 |
+
for col in range(1, n):
|
| 1355 |
+
exp = table[0][col]
|
| 1356 |
+
is_zero = table[row][col]
|
| 1357 |
+
# The actual test here:
|
| 1358 |
+
assert Pow(base, exp, evaluate=False).is_zero is is_zero
|
| 1359 |
+
|
| 1360 |
+
test_table(pow_iszero)
|
| 1361 |
+
|
| 1362 |
+
# A zero symbol...
|
| 1363 |
+
zo, zo2 = symbols('zo, zo2', zero=True)
|
| 1364 |
+
|
| 1365 |
+
# All combinations of finite symbols
|
| 1366 |
+
zf, zf2 = symbols('zf, zf2', finite=True)
|
| 1367 |
+
wf, wf2 = symbols('wf, wf2', nonzero=True)
|
| 1368 |
+
xf, xf2 = symbols('xf, xf2', real=True)
|
| 1369 |
+
yf, yf2 = symbols('yf, yf2', nonzero=True)
|
| 1370 |
+
af, af2 = symbols('af, af2', positive=True)
|
| 1371 |
+
bf, bf2 = symbols('bf, bf2', nonnegative=True)
|
| 1372 |
+
cf, cf2 = symbols('cf, cf2', negative=True)
|
| 1373 |
+
df, df2 = symbols('df, df2', nonpositive=True)
|
| 1374 |
+
|
| 1375 |
+
# Without finiteness:
|
| 1376 |
+
zi, zi2 = symbols('zi, zi2')
|
| 1377 |
+
wi, wi2 = symbols('wi, wi2', zero=False)
|
| 1378 |
+
xi, xi2 = symbols('xi, xi2', extended_real=True)
|
| 1379 |
+
yi, yi2 = symbols('yi, yi2', zero=False, extended_real=True)
|
| 1380 |
+
ai, ai2 = symbols('ai, ai2', extended_positive=True)
|
| 1381 |
+
bi, bi2 = symbols('bi, bi2', extended_nonnegative=True)
|
| 1382 |
+
ci, ci2 = symbols('ci, ci2', extended_negative=True)
|
| 1383 |
+
di, di2 = symbols('di, di2', extended_nonpositive=True)
|
| 1384 |
+
|
| 1385 |
+
pow_iszero_sym = [
|
| 1386 |
+
['**',zo,wf,yf,af,cf,zf,xf,bf,df,zi,wi,xi,yi,ai,bi,ci,di],
|
| 1387 |
+
[ zo2, F, N, N, T, F, N, N, N, F, N, N, N, N, T, N, F, F],
|
| 1388 |
+
[ wf2, F, F, F, F, F, F, F, F, F, N, N, N, N, N, N, N, N],
|
| 1389 |
+
[ yf2, F, F, F, F, F, F, F, F, F, N, N, N, N, N, N, N, N],
|
| 1390 |
+
[ af2, F, F, F, F, F, F, F, F, F, N, N, N, N, N, N, N, N],
|
| 1391 |
+
[ cf2, F, F, F, F, F, F, F, F, F, N, N, N, N, N, N, N, N],
|
| 1392 |
+
[ zf2, N, N, N, N, F, N, N, N, N, N, N, N, N, N, N, N, N],
|
| 1393 |
+
[ xf2, N, N, N, N, F, N, N, N, N, N, N, N, N, N, N, N, N],
|
| 1394 |
+
[ bf2, N, N, N, N, F, N, N, N, N, N, N, N, N, N, N, N, N],
|
| 1395 |
+
[ df2, N, N, N, N, F, N, N, N, N, N, N, N, N, N, N, N, N],
|
| 1396 |
+
[ zi2, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N],
|
| 1397 |
+
[ wi2, F, N, N, F, N, N, N, F, N, N, N, N, N, N, N, N, N],
|
| 1398 |
+
[ xi2, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N],
|
| 1399 |
+
[ yi2, F, N, N, F, N, N, N, F, N, N, N, N, N, N, N, N, N],
|
| 1400 |
+
[ ai2, F, N, N, F, N, N, N, F, N, N, N, N, N, N, N, N, N],
|
| 1401 |
+
[ bi2, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N],
|
| 1402 |
+
[ ci2, F, N, N, F, N, N, N, F, N, N, N, N, N, N, N, N, N],
|
| 1403 |
+
[ di2, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N]
|
| 1404 |
+
]
|
| 1405 |
+
|
| 1406 |
+
test_table(pow_iszero_sym)
|
| 1407 |
+
|
| 1408 |
+
# In some cases (x**x).is_zero is different from (x**y).is_zero even if y
|
| 1409 |
+
# has the same assumptions as x.
|
| 1410 |
+
assert (zo ** zo).is_zero is False
|
| 1411 |
+
assert (wf ** wf).is_zero is False
|
| 1412 |
+
assert (yf ** yf).is_zero is False
|
| 1413 |
+
assert (af ** af).is_zero is False
|
| 1414 |
+
assert (cf ** cf).is_zero is False
|
| 1415 |
+
assert (zf ** zf).is_zero is None
|
| 1416 |
+
assert (xf ** xf).is_zero is None
|
| 1417 |
+
assert (bf ** bf).is_zero is False # None in table
|
| 1418 |
+
assert (df ** df).is_zero is None
|
| 1419 |
+
assert (zi ** zi).is_zero is None
|
| 1420 |
+
assert (wi ** wi).is_zero is None
|
| 1421 |
+
assert (xi ** xi).is_zero is None
|
| 1422 |
+
assert (yi ** yi).is_zero is None
|
| 1423 |
+
assert (ai ** ai).is_zero is False # None in table
|
| 1424 |
+
assert (bi ** bi).is_zero is False # None in table
|
| 1425 |
+
assert (ci ** ci).is_zero is None
|
| 1426 |
+
assert (di ** di).is_zero is None
|
| 1427 |
+
|
| 1428 |
+
|
| 1429 |
+
def test_Pow_is_nonpositive_nonnegative():
|
| 1430 |
+
x = Symbol('x', real=True)
|
| 1431 |
+
|
| 1432 |
+
k = Symbol('k', integer=True, nonnegative=True)
|
| 1433 |
+
l = Symbol('l', integer=True, positive=True)
|
| 1434 |
+
n = Symbol('n', even=True)
|
| 1435 |
+
m = Symbol('m', odd=True)
|
| 1436 |
+
|
| 1437 |
+
assert (x**(4*k)).is_nonnegative is True
|
| 1438 |
+
assert (2**x).is_nonnegative is True
|
| 1439 |
+
assert ((-2)**x).is_nonnegative is None
|
| 1440 |
+
assert ((-2)**n).is_nonnegative is True
|
| 1441 |
+
assert ((-2)**m).is_nonnegative is False
|
| 1442 |
+
|
| 1443 |
+
assert (k**2).is_nonnegative is True
|
| 1444 |
+
assert (k**(-2)).is_nonnegative is None
|
| 1445 |
+
assert (k**k).is_nonnegative is True
|
| 1446 |
+
|
| 1447 |
+
assert (k**x).is_nonnegative is None # NOTE (0**x).is_real = U
|
| 1448 |
+
assert (l**x).is_nonnegative is True
|
| 1449 |
+
assert (l**x).is_positive is True
|
| 1450 |
+
assert ((-k)**x).is_nonnegative is None
|
| 1451 |
+
|
| 1452 |
+
assert ((-k)**m).is_nonnegative is None
|
| 1453 |
+
|
| 1454 |
+
assert (2**x).is_nonpositive is False
|
| 1455 |
+
assert ((-2)**x).is_nonpositive is None
|
| 1456 |
+
assert ((-2)**n).is_nonpositive is False
|
| 1457 |
+
assert ((-2)**m).is_nonpositive is True
|
| 1458 |
+
|
| 1459 |
+
assert (k**2).is_nonpositive is None
|
| 1460 |
+
assert (k**(-2)).is_nonpositive is None
|
| 1461 |
+
|
| 1462 |
+
assert (k**x).is_nonpositive is None
|
| 1463 |
+
assert ((-k)**x).is_nonpositive is None
|
| 1464 |
+
assert ((-k)**n).is_nonpositive is None
|
| 1465 |
+
|
| 1466 |
+
|
| 1467 |
+
assert (x**2).is_nonnegative is True
|
| 1468 |
+
i = symbols('i', imaginary=True)
|
| 1469 |
+
assert (i**2).is_nonpositive is True
|
| 1470 |
+
assert (i**4).is_nonpositive is False
|
| 1471 |
+
assert (i**3).is_nonpositive is False
|
| 1472 |
+
assert (I**i).is_nonnegative is True
|
| 1473 |
+
assert (exp(I)**i).is_nonnegative is True
|
| 1474 |
+
|
| 1475 |
+
assert ((-l)**n).is_nonnegative is True
|
| 1476 |
+
assert ((-l)**m).is_nonpositive is True
|
| 1477 |
+
assert ((-k)**n).is_nonnegative is None
|
| 1478 |
+
assert ((-k)**m).is_nonpositive is None
|
| 1479 |
+
|
| 1480 |
+
|
| 1481 |
+
def test_Mul_is_imaginary_real():
|
| 1482 |
+
r = Symbol('r', real=True)
|
| 1483 |
+
p = Symbol('p', positive=True)
|
| 1484 |
+
i1 = Symbol('i1', imaginary=True)
|
| 1485 |
+
i2 = Symbol('i2', imaginary=True)
|
| 1486 |
+
x = Symbol('x')
|
| 1487 |
+
|
| 1488 |
+
assert I.is_imaginary is True
|
| 1489 |
+
assert I.is_real is False
|
| 1490 |
+
assert (-I).is_imaginary is True
|
| 1491 |
+
assert (-I).is_real is False
|
| 1492 |
+
assert (3*I).is_imaginary is True
|
| 1493 |
+
assert (3*I).is_real is False
|
| 1494 |
+
assert (I*I).is_imaginary is False
|
| 1495 |
+
assert (I*I).is_real is True
|
| 1496 |
+
|
| 1497 |
+
e = (p + p*I)
|
| 1498 |
+
j = Symbol('j', integer=True, zero=False)
|
| 1499 |
+
assert (e**j).is_real is None
|
| 1500 |
+
assert (e**(2*j)).is_real is None
|
| 1501 |
+
assert (e**j).is_imaginary is None
|
| 1502 |
+
assert (e**(2*j)).is_imaginary is None
|
| 1503 |
+
|
| 1504 |
+
assert (e**-1).is_imaginary is False
|
| 1505 |
+
assert (e**2).is_imaginary
|
| 1506 |
+
assert (e**3).is_imaginary is False
|
| 1507 |
+
assert (e**4).is_imaginary is False
|
| 1508 |
+
assert (e**5).is_imaginary is False
|
| 1509 |
+
assert (e**-1).is_real is False
|
| 1510 |
+
assert (e**2).is_real is False
|
| 1511 |
+
assert (e**3).is_real is False
|
| 1512 |
+
assert (e**4).is_real is True
|
| 1513 |
+
assert (e**5).is_real is False
|
| 1514 |
+
assert (e**3).is_complex
|
| 1515 |
+
|
| 1516 |
+
assert (r*i1).is_imaginary is None
|
| 1517 |
+
assert (r*i1).is_real is None
|
| 1518 |
+
|
| 1519 |
+
assert (x*i1).is_imaginary is None
|
| 1520 |
+
assert (x*i1).is_real is None
|
| 1521 |
+
|
| 1522 |
+
assert (i1*i2).is_imaginary is False
|
| 1523 |
+
assert (i1*i2).is_real is True
|
| 1524 |
+
|
| 1525 |
+
assert (r*i1*i2).is_imaginary is False
|
| 1526 |
+
assert (r*i1*i2).is_real is True
|
| 1527 |
+
|
| 1528 |
+
# Github's issue 5874:
|
| 1529 |
+
nr = Symbol('nr', real=False, complex=True) # e.g. I or 1 + I
|
| 1530 |
+
a = Symbol('a', real=True, nonzero=True)
|
| 1531 |
+
b = Symbol('b', real=True)
|
| 1532 |
+
assert (i1*nr).is_real is None
|
| 1533 |
+
assert (a*nr).is_real is False
|
| 1534 |
+
assert (b*nr).is_real is None
|
| 1535 |
+
|
| 1536 |
+
ni = Symbol('ni', imaginary=False, complex=True) # e.g. 2 or 1 + I
|
| 1537 |
+
a = Symbol('a', real=True, nonzero=True)
|
| 1538 |
+
b = Symbol('b', real=True)
|
| 1539 |
+
assert (i1*ni).is_real is False
|
| 1540 |
+
assert (a*ni).is_real is None
|
| 1541 |
+
assert (b*ni).is_real is None
|
| 1542 |
+
|
| 1543 |
+
|
| 1544 |
+
def test_Mul_hermitian_antihermitian():
|
| 1545 |
+
xz, yz = symbols('xz, yz', zero=True, antihermitian=True)
|
| 1546 |
+
xf, yf = symbols('xf, yf', hermitian=False, antihermitian=False, finite=True)
|
| 1547 |
+
xh, yh = symbols('xh, yh', hermitian=True, antihermitian=False, nonzero=True)
|
| 1548 |
+
xa, ya = symbols('xa, ya', hermitian=False, antihermitian=True, zero=False, finite=True)
|
| 1549 |
+
assert (xz*xh).is_hermitian is True
|
| 1550 |
+
assert (xz*xh).is_antihermitian is True
|
| 1551 |
+
assert (xz*xa).is_hermitian is True
|
| 1552 |
+
assert (xz*xa).is_antihermitian is True
|
| 1553 |
+
assert (xf*yf).is_hermitian is None
|
| 1554 |
+
assert (xf*yf).is_antihermitian is None
|
| 1555 |
+
assert (xh*yh).is_hermitian is True
|
| 1556 |
+
assert (xh*yh).is_antihermitian is False
|
| 1557 |
+
assert (xh*ya).is_hermitian is False
|
| 1558 |
+
assert (xh*ya).is_antihermitian is True
|
| 1559 |
+
assert (xa*ya).is_hermitian is True
|
| 1560 |
+
assert (xa*ya).is_antihermitian is False
|
| 1561 |
+
|
| 1562 |
+
a = Symbol('a', hermitian=True, zero=False)
|
| 1563 |
+
b = Symbol('b', hermitian=True)
|
| 1564 |
+
c = Symbol('c', hermitian=False)
|
| 1565 |
+
d = Symbol('d', antihermitian=True)
|
| 1566 |
+
e1 = Mul(a, b, c, evaluate=False)
|
| 1567 |
+
e2 = Mul(b, a, c, evaluate=False)
|
| 1568 |
+
e3 = Mul(a, b, c, d, evaluate=False)
|
| 1569 |
+
e4 = Mul(b, a, c, d, evaluate=False)
|
| 1570 |
+
e5 = Mul(a, c, evaluate=False)
|
| 1571 |
+
e6 = Mul(a, c, d, evaluate=False)
|
| 1572 |
+
assert e1.is_hermitian is None
|
| 1573 |
+
assert e2.is_hermitian is None
|
| 1574 |
+
assert e1.is_antihermitian is None
|
| 1575 |
+
assert e2.is_antihermitian is None
|
| 1576 |
+
assert e3.is_antihermitian is None
|
| 1577 |
+
assert e4.is_antihermitian is None
|
| 1578 |
+
assert e5.is_antihermitian is None
|
| 1579 |
+
assert e6.is_antihermitian is None
|
| 1580 |
+
|
| 1581 |
+
|
| 1582 |
+
def test_Add_is_comparable():
|
| 1583 |
+
assert (x + y).is_comparable is False
|
| 1584 |
+
assert (x + 1).is_comparable is False
|
| 1585 |
+
assert (Rational(1, 3) - sqrt(8)).is_comparable is True
|
| 1586 |
+
|
| 1587 |
+
|
| 1588 |
+
def test_Mul_is_comparable():
|
| 1589 |
+
assert (x*y).is_comparable is False
|
| 1590 |
+
assert (x*2).is_comparable is False
|
| 1591 |
+
assert (sqrt(2)*Rational(1, 3)).is_comparable is True
|
| 1592 |
+
|
| 1593 |
+
|
| 1594 |
+
def test_Pow_is_comparable():
|
| 1595 |
+
assert (x**y).is_comparable is False
|
| 1596 |
+
assert (x**2).is_comparable is False
|
| 1597 |
+
assert (sqrt(Rational(1, 3))).is_comparable is True
|
| 1598 |
+
|
| 1599 |
+
|
| 1600 |
+
def test_Add_is_positive_2():
|
| 1601 |
+
e = Rational(1, 3) - sqrt(8)
|
| 1602 |
+
assert e.is_positive is False
|
| 1603 |
+
assert e.is_negative is True
|
| 1604 |
+
|
| 1605 |
+
e = pi - 1
|
| 1606 |
+
assert e.is_positive is True
|
| 1607 |
+
assert e.is_negative is False
|
| 1608 |
+
|
| 1609 |
+
|
| 1610 |
+
def test_Add_is_irrational():
|
| 1611 |
+
i = Symbol('i', irrational=True)
|
| 1612 |
+
|
| 1613 |
+
assert i.is_irrational is True
|
| 1614 |
+
assert i.is_rational is False
|
| 1615 |
+
|
| 1616 |
+
assert (i + 1).is_irrational is True
|
| 1617 |
+
assert (i + 1).is_rational is False
|
| 1618 |
+
|
| 1619 |
+
|
| 1620 |
+
def test_Mul_is_irrational():
|
| 1621 |
+
expr = Mul(1, 2, 3, evaluate=False)
|
| 1622 |
+
assert expr.is_irrational is False
|
| 1623 |
+
expr = Mul(1, I, I, evaluate=False)
|
| 1624 |
+
assert expr.is_rational is None # I * I = -1 but *no evaluation allowed*
|
| 1625 |
+
# sqrt(2) * I * I = -sqrt(2) is irrational but
|
| 1626 |
+
# this can't be determined without evaluating the
|
| 1627 |
+
# expression and the eval_is routines shouldn't do that
|
| 1628 |
+
expr = Mul(sqrt(2), I, I, evaluate=False)
|
| 1629 |
+
assert expr.is_irrational is None
|
| 1630 |
+
|
| 1631 |
+
|
| 1632 |
+
def test_issue_3531():
|
| 1633 |
+
# https://github.com/sympy/sympy/issues/3531
|
| 1634 |
+
# https://github.com/sympy/sympy/pull/18116
|
| 1635 |
+
class MightyNumeric(tuple):
|
| 1636 |
+
__slots__ = ()
|
| 1637 |
+
|
| 1638 |
+
def __rtruediv__(self, other):
|
| 1639 |
+
return "something"
|
| 1640 |
+
|
| 1641 |
+
assert sympify(1)/MightyNumeric((1, 2)) == "something"
|
| 1642 |
+
|
| 1643 |
+
|
| 1644 |
+
def test_issue_3531b():
|
| 1645 |
+
class Foo:
|
| 1646 |
+
def __init__(self):
|
| 1647 |
+
self.field = 1.0
|
| 1648 |
+
|
| 1649 |
+
def __mul__(self, other):
|
| 1650 |
+
self.field = self.field * other
|
| 1651 |
+
|
| 1652 |
+
def __rmul__(self, other):
|
| 1653 |
+
self.field = other * self.field
|
| 1654 |
+
f = Foo()
|
| 1655 |
+
x = Symbol("x")
|
| 1656 |
+
assert f*x == x*f
|
| 1657 |
+
|
| 1658 |
+
|
| 1659 |
+
def test_bug3():
|
| 1660 |
+
a = Symbol("a")
|
| 1661 |
+
b = Symbol("b", positive=True)
|
| 1662 |
+
e = 2*a + b
|
| 1663 |
+
f = b + 2*a
|
| 1664 |
+
assert e == f
|
| 1665 |
+
|
| 1666 |
+
|
| 1667 |
+
def test_suppressed_evaluation():
|
| 1668 |
+
a = Add(0, 3, 2, evaluate=False)
|
| 1669 |
+
b = Mul(1, 3, 2, evaluate=False)
|
| 1670 |
+
c = Pow(3, 2, evaluate=False)
|
| 1671 |
+
assert a != 6
|
| 1672 |
+
assert a.func is Add
|
| 1673 |
+
assert a.args == (0, 3, 2)
|
| 1674 |
+
assert b != 6
|
| 1675 |
+
assert b.func is Mul
|
| 1676 |
+
assert b.args == (1, 3, 2)
|
| 1677 |
+
assert c != 9
|
| 1678 |
+
assert c.func is Pow
|
| 1679 |
+
assert c.args == (3, 2)
|
| 1680 |
+
|
| 1681 |
+
|
| 1682 |
+
def test_AssocOp_doit():
|
| 1683 |
+
a = Add(x,x, evaluate=False)
|
| 1684 |
+
b = Mul(y,y, evaluate=False)
|
| 1685 |
+
c = Add(b,b, evaluate=False)
|
| 1686 |
+
d = Mul(a,a, evaluate=False)
|
| 1687 |
+
assert c.doit(deep=False).func == Mul
|
| 1688 |
+
assert c.doit(deep=False).args == (2,y,y)
|
| 1689 |
+
assert c.doit().func == Mul
|
| 1690 |
+
assert c.doit().args == (2, Pow(y,2))
|
| 1691 |
+
assert d.doit(deep=False).func == Pow
|
| 1692 |
+
assert d.doit(deep=False).args == (a, 2*S.One)
|
| 1693 |
+
assert d.doit().func == Mul
|
| 1694 |
+
assert d.doit().args == (4*S.One, Pow(x,2))
|
| 1695 |
+
|
| 1696 |
+
|
| 1697 |
+
def test_Add_Mul_Expr_args():
|
| 1698 |
+
nonexpr = [Basic(), Poly(x, x), FiniteSet(x)]
|
| 1699 |
+
for typ in [Add, Mul]:
|
| 1700 |
+
for obj in nonexpr:
|
| 1701 |
+
# The cache can mess with the stacklevel check
|
| 1702 |
+
with warns(SymPyDeprecationWarning, test_stacklevel=False):
|
| 1703 |
+
typ(obj, 1)
|
| 1704 |
+
|
| 1705 |
+
|
| 1706 |
+
def test_Add_as_coeff_mul():
|
| 1707 |
+
# issue 5524. These should all be (1, self)
|
| 1708 |
+
assert (x + 1).as_coeff_mul() == (1, (x + 1,))
|
| 1709 |
+
assert (x + 2).as_coeff_mul() == (1, (x + 2,))
|
| 1710 |
+
assert (x + 3).as_coeff_mul() == (1, (x + 3,))
|
| 1711 |
+
|
| 1712 |
+
assert (x - 1).as_coeff_mul() == (1, (x - 1,))
|
| 1713 |
+
assert (x - 2).as_coeff_mul() == (1, (x - 2,))
|
| 1714 |
+
assert (x - 3).as_coeff_mul() == (1, (x - 3,))
|
| 1715 |
+
|
| 1716 |
+
n = Symbol('n', integer=True)
|
| 1717 |
+
assert (n + 1).as_coeff_mul() == (1, (n + 1,))
|
| 1718 |
+
assert (n + 2).as_coeff_mul() == (1, (n + 2,))
|
| 1719 |
+
assert (n + 3).as_coeff_mul() == (1, (n + 3,))
|
| 1720 |
+
|
| 1721 |
+
assert (n - 1).as_coeff_mul() == (1, (n - 1,))
|
| 1722 |
+
assert (n - 2).as_coeff_mul() == (1, (n - 2,))
|
| 1723 |
+
assert (n - 3).as_coeff_mul() == (1, (n - 3,))
|
| 1724 |
+
|
| 1725 |
+
|
| 1726 |
+
def test_Pow_as_coeff_mul_doesnt_expand():
|
| 1727 |
+
assert exp(x + y).as_coeff_mul() == (1, (exp(x + y),))
|
| 1728 |
+
assert exp(x + exp(x + y)) != exp(x + exp(x)*exp(y))
|
| 1729 |
+
|
| 1730 |
+
def test_issue_24751():
|
| 1731 |
+
expr = Add(-2, -3, evaluate=False)
|
| 1732 |
+
expr1 = Add(-1, expr, evaluate=False)
|
| 1733 |
+
assert int(expr1) == int((-3 - 2) - 1)
|
| 1734 |
+
|
| 1735 |
+
|
| 1736 |
+
def test_issue_3514_18626():
|
| 1737 |
+
assert sqrt(S.Half) * sqrt(6) == 2 * sqrt(3)/2
|
| 1738 |
+
assert S.Half*sqrt(6)*sqrt(2) == sqrt(3)
|
| 1739 |
+
assert sqrt(6)/2*sqrt(2) == sqrt(3)
|
| 1740 |
+
assert sqrt(6)*sqrt(2)/2 == sqrt(3)
|
| 1741 |
+
assert sqrt(8)**Rational(2, 3) == 2
|
| 1742 |
+
|
| 1743 |
+
|
| 1744 |
+
def test_make_args():
|
| 1745 |
+
assert Add.make_args(x) == (x,)
|
| 1746 |
+
assert Mul.make_args(x) == (x,)
|
| 1747 |
+
|
| 1748 |
+
assert Add.make_args(x*y*z) == (x*y*z,)
|
| 1749 |
+
assert Mul.make_args(x*y*z) == (x*y*z).args
|
| 1750 |
+
|
| 1751 |
+
assert Add.make_args(x + y + z) == (x + y + z).args
|
| 1752 |
+
assert Mul.make_args(x + y + z) == (x + y + z,)
|
| 1753 |
+
|
| 1754 |
+
assert Add.make_args((x + y)**z) == ((x + y)**z,)
|
| 1755 |
+
assert Mul.make_args((x + y)**z) == ((x + y)**z,)
|
| 1756 |
+
|
| 1757 |
+
|
| 1758 |
+
def test_issue_5126():
|
| 1759 |
+
assert (-2)**x*(-3)**x != 6**x
|
| 1760 |
+
i = Symbol('i', integer=1)
|
| 1761 |
+
assert (-2)**i*(-3)**i == 6**i
|
| 1762 |
+
|
| 1763 |
+
|
| 1764 |
+
def test_Rational_as_content_primitive():
|
| 1765 |
+
c, p = S.One, S.Zero
|
| 1766 |
+
assert (c*p).as_content_primitive() == (c, p)
|
| 1767 |
+
c, p = S.Half, S.One
|
| 1768 |
+
assert (c*p).as_content_primitive() == (c, p)
|
| 1769 |
+
|
| 1770 |
+
|
| 1771 |
+
def test_Add_as_content_primitive():
|
| 1772 |
+
assert (x + 2).as_content_primitive() == (1, x + 2)
|
| 1773 |
+
|
| 1774 |
+
assert (3*x + 2).as_content_primitive() == (1, 3*x + 2)
|
| 1775 |
+
assert (3*x + 3).as_content_primitive() == (3, x + 1)
|
| 1776 |
+
assert (3*x + 6).as_content_primitive() == (3, x + 2)
|
| 1777 |
+
|
| 1778 |
+
assert (3*x + 2*y).as_content_primitive() == (1, 3*x + 2*y)
|
| 1779 |
+
assert (3*x + 3*y).as_content_primitive() == (3, x + y)
|
| 1780 |
+
assert (3*x + 6*y).as_content_primitive() == (3, x + 2*y)
|
| 1781 |
+
|
| 1782 |
+
assert (3/x + 2*x*y*z**2).as_content_primitive() == (1, 3/x + 2*x*y*z**2)
|
| 1783 |
+
assert (3/x + 3*x*y*z**2).as_content_primitive() == (3, 1/x + x*y*z**2)
|
| 1784 |
+
assert (3/x + 6*x*y*z**2).as_content_primitive() == (3, 1/x + 2*x*y*z**2)
|
| 1785 |
+
|
| 1786 |
+
assert (2*x/3 + 4*y/9).as_content_primitive() == \
|
| 1787 |
+
(Rational(2, 9), 3*x + 2*y)
|
| 1788 |
+
assert (2*x/3 + 2.5*y).as_content_primitive() == \
|
| 1789 |
+
(Rational(1, 3), 2*x + 7.5*y)
|
| 1790 |
+
|
| 1791 |
+
# the coefficient may sort to a position other than 0
|
| 1792 |
+
p = 3 + x + y
|
| 1793 |
+
assert (2*p).expand().as_content_primitive() == (2, p)
|
| 1794 |
+
assert (2.0*p).expand().as_content_primitive() == (1, 2.*p)
|
| 1795 |
+
p *= -1
|
| 1796 |
+
assert (2*p).expand().as_content_primitive() == (2, p)
|
| 1797 |
+
|
| 1798 |
+
|
| 1799 |
+
def test_Mul_as_content_primitive():
|
| 1800 |
+
assert (2*x).as_content_primitive() == (2, x)
|
| 1801 |
+
assert (x*(2 + 2*x)).as_content_primitive() == (2, x*(1 + x))
|
| 1802 |
+
assert (x*(2 + 2*y)*(3*x + 3)**2).as_content_primitive() == \
|
| 1803 |
+
(18, x*(1 + y)*(x + 1)**2)
|
| 1804 |
+
assert ((2 + 2*x)**2*(3 + 6*x) + S.Half).as_content_primitive() == \
|
| 1805 |
+
(S.Half, 24*(x + 1)**2*(2*x + 1) + 1)
|
| 1806 |
+
|
| 1807 |
+
|
| 1808 |
+
def test_Pow_as_content_primitive():
|
| 1809 |
+
assert (x**y).as_content_primitive() == (1, x**y)
|
| 1810 |
+
assert ((2*x + 2)**y).as_content_primitive() == \
|
| 1811 |
+
(1, (Mul(2, (x + 1), evaluate=False))**y)
|
| 1812 |
+
assert ((2*x + 2)**3).as_content_primitive() == (8, (x + 1)**3)
|
| 1813 |
+
|
| 1814 |
+
|
| 1815 |
+
def test_issue_5460():
|
| 1816 |
+
u = Mul(2, (1 + x), evaluate=False)
|
| 1817 |
+
assert (2 + u).args == (2, u)
|
| 1818 |
+
|
| 1819 |
+
|
| 1820 |
+
def test_product_irrational():
|
| 1821 |
+
assert (I*pi).is_irrational is False
|
| 1822 |
+
# The following used to be deduced from the above bug:
|
| 1823 |
+
assert (I*pi).is_positive is False
|
| 1824 |
+
|
| 1825 |
+
|
| 1826 |
+
def test_issue_5919():
|
| 1827 |
+
assert (x/(y*(1 + y))).expand() == x/(y**2 + y)
|
| 1828 |
+
|
| 1829 |
+
|
| 1830 |
+
def test_Mod():
|
| 1831 |
+
assert Mod(x, 1).func is Mod
|
| 1832 |
+
assert pi % pi is S.Zero
|
| 1833 |
+
assert Mod(5, 3) == 2
|
| 1834 |
+
assert Mod(-5, 3) == 1
|
| 1835 |
+
assert Mod(5, -3) == -1
|
| 1836 |
+
assert Mod(-5, -3) == -2
|
| 1837 |
+
assert type(Mod(3.2, 2, evaluate=False)) == Mod
|
| 1838 |
+
assert 5 % x == Mod(5, x)
|
| 1839 |
+
assert x % 5 == Mod(x, 5)
|
| 1840 |
+
assert x % y == Mod(x, y)
|
| 1841 |
+
assert (x % y).subs({x: 5, y: 3}) == 2
|
| 1842 |
+
assert Mod(nan, 1) is nan
|
| 1843 |
+
assert Mod(1, nan) is nan
|
| 1844 |
+
assert Mod(nan, nan) is nan
|
| 1845 |
+
|
| 1846 |
+
assert Mod(0, x) == 0
|
| 1847 |
+
with raises(ZeroDivisionError):
|
| 1848 |
+
Mod(x, 0)
|
| 1849 |
+
|
| 1850 |
+
k = Symbol('k', integer=True)
|
| 1851 |
+
m = Symbol('m', integer=True, positive=True)
|
| 1852 |
+
assert (x**m % x).func is Mod
|
| 1853 |
+
assert (k**(-m) % k).func is Mod
|
| 1854 |
+
assert k**m % k == 0
|
| 1855 |
+
assert (-2*k)**m % k == 0
|
| 1856 |
+
|
| 1857 |
+
# Float handling
|
| 1858 |
+
point3 = Float(3.3) % 1
|
| 1859 |
+
assert (x - 3.3) % 1 == Mod(1.*x + 1 - point3, 1)
|
| 1860 |
+
assert Mod(-3.3, 1) == 1 - point3
|
| 1861 |
+
assert Mod(0.7, 1) == Float(0.7)
|
| 1862 |
+
e = Mod(1.3, 1)
|
| 1863 |
+
assert comp(e, .3) and e.is_Float
|
| 1864 |
+
e = Mod(1.3, .7)
|
| 1865 |
+
assert comp(e, .6) and e.is_Float
|
| 1866 |
+
e = Mod(1.3, Rational(7, 10))
|
| 1867 |
+
assert comp(e, .6) and e.is_Float
|
| 1868 |
+
e = Mod(Rational(13, 10), 0.7)
|
| 1869 |
+
assert comp(e, .6) and e.is_Float
|
| 1870 |
+
e = Mod(Rational(13, 10), Rational(7, 10))
|
| 1871 |
+
assert comp(e, .6) and e.is_Rational
|
| 1872 |
+
|
| 1873 |
+
# check that sign is right
|
| 1874 |
+
r2 = sqrt(2)
|
| 1875 |
+
r3 = sqrt(3)
|
| 1876 |
+
for i in [-r3, -r2, r2, r3]:
|
| 1877 |
+
for j in [-r3, -r2, r2, r3]:
|
| 1878 |
+
assert verify_numerically(i % j, i.n() % j.n())
|
| 1879 |
+
for _x in range(4):
|
| 1880 |
+
for _y in range(9):
|
| 1881 |
+
reps = [(x, _x), (y, _y)]
|
| 1882 |
+
assert Mod(3*x + y, 9).subs(reps) == (3*_x + _y) % 9
|
| 1883 |
+
|
| 1884 |
+
# denesting
|
| 1885 |
+
t = Symbol('t', real=True)
|
| 1886 |
+
assert Mod(Mod(x, t), t) == Mod(x, t)
|
| 1887 |
+
assert Mod(-Mod(x, t), t) == Mod(-x, t)
|
| 1888 |
+
assert Mod(Mod(x, 2*t), t) == Mod(x, t)
|
| 1889 |
+
assert Mod(-Mod(x, 2*t), t) == Mod(-x, t)
|
| 1890 |
+
assert Mod(Mod(x, t), 2*t) == Mod(x, t)
|
| 1891 |
+
assert Mod(-Mod(x, t), -2*t) == -Mod(x, t)
|
| 1892 |
+
for i in [-4, -2, 2, 4]:
|
| 1893 |
+
for j in [-4, -2, 2, 4]:
|
| 1894 |
+
for k in range(4):
|
| 1895 |
+
assert Mod(Mod(x, i), j).subs({x: k}) == (k % i) % j
|
| 1896 |
+
assert Mod(-Mod(x, i), j).subs({x: k}) == -(k % i) % j
|
| 1897 |
+
|
| 1898 |
+
# known difference
|
| 1899 |
+
assert Mod(5*sqrt(2), sqrt(5)) == 5*sqrt(2) - 3*sqrt(5)
|
| 1900 |
+
p = symbols('p', positive=True)
|
| 1901 |
+
assert Mod(2, p + 3) == 2
|
| 1902 |
+
assert Mod(-2, p + 3) == p + 1
|
| 1903 |
+
assert Mod(2, -p - 3) == -p - 1
|
| 1904 |
+
assert Mod(-2, -p - 3) == -2
|
| 1905 |
+
assert Mod(p + 5, p + 3) == 2
|
| 1906 |
+
assert Mod(-p - 5, p + 3) == p + 1
|
| 1907 |
+
assert Mod(p + 5, -p - 3) == -p - 1
|
| 1908 |
+
assert Mod(-p - 5, -p - 3) == -2
|
| 1909 |
+
assert Mod(p + 1, p - 1).func is Mod
|
| 1910 |
+
|
| 1911 |
+
# issue 27749
|
| 1912 |
+
n = symbols('n', integer=True, positive=True)
|
| 1913 |
+
assert unchanged(Mod, 1, n)
|
| 1914 |
+
n = symbols('n', prime=True)
|
| 1915 |
+
assert Mod(1, n) == 1
|
| 1916 |
+
|
| 1917 |
+
# handling sums
|
| 1918 |
+
assert (x + 3) % 1 == Mod(x, 1)
|
| 1919 |
+
assert (x + 3.0) % 1 == Mod(1.*x, 1)
|
| 1920 |
+
assert (x - S(33)/10) % 1 == Mod(x + S(7)/10, 1)
|
| 1921 |
+
|
| 1922 |
+
a = Mod(.6*x + y, .3*y)
|
| 1923 |
+
b = Mod(0.1*y + 0.6*x, 0.3*y)
|
| 1924 |
+
# Test that a, b are equal, with 1e-14 accuracy in coefficients
|
| 1925 |
+
eps = 1e-14
|
| 1926 |
+
assert abs((a.args[0] - b.args[0]).subs({x: 1, y: 1})) < eps
|
| 1927 |
+
assert abs((a.args[1] - b.args[1]).subs({x: 1, y: 1})) < eps
|
| 1928 |
+
|
| 1929 |
+
assert (x + 1) % x == 1 % x
|
| 1930 |
+
assert (x + y) % x == y % x
|
| 1931 |
+
assert (x + y + 2) % x == (y + 2) % x
|
| 1932 |
+
assert (a + 3*x + 1) % (2*x) == Mod(a + x + 1, 2*x)
|
| 1933 |
+
assert (12*x + 18*y) % (3*x) == 3*Mod(6*y, x)
|
| 1934 |
+
|
| 1935 |
+
# gcd extraction
|
| 1936 |
+
assert (-3*x) % (-2*y) == -Mod(3*x, 2*y)
|
| 1937 |
+
assert (.6*pi) % (.3*x*pi) == 0.3*pi*Mod(2, x)
|
| 1938 |
+
assert (.6*pi) % (.31*x*pi) == pi*Mod(0.6, 0.31*x)
|
| 1939 |
+
assert (6*pi) % (.3*x*pi) == 0.3*pi*Mod(20, x)
|
| 1940 |
+
assert (6*pi) % (.31*x*pi) == pi*Mod(6, 0.31*x)
|
| 1941 |
+
assert (6*pi) % (.42*x*pi) == pi*Mod(6, 0.42*x)
|
| 1942 |
+
assert (12*x) % (2*y) == 2*Mod(6*x, y)
|
| 1943 |
+
assert (12*x) % (3*5*y) == 3*Mod(4*x, 5*y)
|
| 1944 |
+
assert (12*x) % (15*x*y) == 3*x*Mod(4, 5*y)
|
| 1945 |
+
assert (-2*pi) % (3*pi) == pi
|
| 1946 |
+
assert (2*x + 2) % (x + 1) == 0
|
| 1947 |
+
assert (x*(x + 1)) % (x + 1) == (x + 1)*Mod(x, 1)
|
| 1948 |
+
assert Mod(5.0*x, 0.1*y) == 0.1*Mod(50*x, y)
|
| 1949 |
+
i = Symbol('i', integer=True)
|
| 1950 |
+
assert (3*i*x) % (2*i*y) == i*Mod(3*x, 2*y)
|
| 1951 |
+
assert Mod(4*i, 4) == 0
|
| 1952 |
+
|
| 1953 |
+
# issue 8677
|
| 1954 |
+
n = Symbol('n', integer=True, positive=True)
|
| 1955 |
+
assert factorial(n) % n == 0
|
| 1956 |
+
assert factorial(n + 2) % n == 0
|
| 1957 |
+
assert (factorial(n + 4) % (n + 5)).func is Mod
|
| 1958 |
+
|
| 1959 |
+
# Wilson's theorem
|
| 1960 |
+
assert factorial(18042, evaluate=False) % 18043 == 18042
|
| 1961 |
+
p = Symbol('n', prime=True)
|
| 1962 |
+
assert factorial(p - 1) % p == p - 1
|
| 1963 |
+
assert factorial(p - 1) % -p == -1
|
| 1964 |
+
assert (factorial(3, evaluate=False) % 4).doit() == 2
|
| 1965 |
+
n = Symbol('n', composite=True, odd=True)
|
| 1966 |
+
assert factorial(n - 1) % n == 0
|
| 1967 |
+
|
| 1968 |
+
# symbolic with known parity
|
| 1969 |
+
n = Symbol('n', even=True)
|
| 1970 |
+
assert Mod(n, 2) == 0
|
| 1971 |
+
n = Symbol('n', odd=True)
|
| 1972 |
+
assert Mod(n, 2) == 1
|
| 1973 |
+
|
| 1974 |
+
# issue 10963
|
| 1975 |
+
assert (x**6000%400).args[1] == 400
|
| 1976 |
+
|
| 1977 |
+
#issue 13543
|
| 1978 |
+
assert Mod(Mod(x + 1, 2) + 1, 2) == Mod(x, 2)
|
| 1979 |
+
|
| 1980 |
+
x1 = Symbol('x1', integer=True)
|
| 1981 |
+
assert Mod(Mod(x1 + 2, 4)*(x1 + 4), 4) == Mod(x1*(x1 + 2), 4)
|
| 1982 |
+
assert Mod(Mod(x1 + 2, 4)*4, 4) == 0
|
| 1983 |
+
|
| 1984 |
+
# issue 15493
|
| 1985 |
+
i, j = symbols('i j', integer=True, positive=True)
|
| 1986 |
+
assert Mod(3*i, 2) == Mod(i, 2)
|
| 1987 |
+
assert Mod(8*i/j, 4) == 4*Mod(2*i/j, 1)
|
| 1988 |
+
assert Mod(8*i, 4) == 0
|
| 1989 |
+
|
| 1990 |
+
# rewrite
|
| 1991 |
+
assert Mod(x, y).rewrite(floor) == x - y*floor(x/y)
|
| 1992 |
+
assert ((x - Mod(x, y))/y).rewrite(floor) == floor(x/y)
|
| 1993 |
+
|
| 1994 |
+
# issue 21373
|
| 1995 |
+
from sympy.functions.elementary.hyperbolic import sinh
|
| 1996 |
+
from sympy.functions.elementary.piecewise import Piecewise
|
| 1997 |
+
|
| 1998 |
+
x_r, y_r = symbols('x_r y_r', real=True)
|
| 1999 |
+
assert (Piecewise((x_r, y_r > x_r), (y_r, True)) / z) % 1
|
| 2000 |
+
expr = exp(sinh(Piecewise((x_r, y_r > x_r), (y_r, True)) / z))
|
| 2001 |
+
expr.subs({1: 1.0})
|
| 2002 |
+
sinh(Piecewise((x_r, y_r > x_r), (y_r, True)) * z ** -1.0).is_zero
|
| 2003 |
+
|
| 2004 |
+
# issue 24215
|
| 2005 |
+
from sympy.abc import phi
|
| 2006 |
+
assert Mod(4.0*Mod(phi, 1) , 2) == 2.0*(Mod(2*(Mod(phi, 1)), 1))
|
| 2007 |
+
|
| 2008 |
+
xi = symbols('x', integer=True)
|
| 2009 |
+
assert unchanged(Mod, xi, 2)
|
| 2010 |
+
assert Mod(3*xi, 2) == Mod(xi, 2)
|
| 2011 |
+
assert unchanged(Mod, 3*x, 2)
|
| 2012 |
+
|
| 2013 |
+
|
| 2014 |
+
def test_Mod_Pow():
|
| 2015 |
+
# modular exponentiation
|
| 2016 |
+
assert isinstance(Mod(Pow(2, 2, evaluate=False), 3), Integer)
|
| 2017 |
+
|
| 2018 |
+
assert Mod(Pow(4, 13, evaluate=False), 497) == Mod(Pow(4, 13), 497)
|
| 2019 |
+
assert Mod(Pow(2, 10000000000, evaluate=False), 3) == 1
|
| 2020 |
+
assert Mod(Pow(32131231232, 9**10**6, evaluate=False),10**12) == \
|
| 2021 |
+
pow(32131231232,9**10**6,10**12)
|
| 2022 |
+
assert Mod(Pow(33284959323, 123**999, evaluate=False),11**13) == \
|
| 2023 |
+
pow(33284959323,123**999,11**13)
|
| 2024 |
+
assert Mod(Pow(78789849597, 333**555, evaluate=False),12**9) == \
|
| 2025 |
+
pow(78789849597,333**555,12**9)
|
| 2026 |
+
|
| 2027 |
+
# modular nested exponentiation
|
| 2028 |
+
expr = Pow(2, 2, evaluate=False)
|
| 2029 |
+
expr = Pow(2, expr, evaluate=False)
|
| 2030 |
+
assert Mod(expr, 3**10) == 16
|
| 2031 |
+
expr = Pow(2, expr, evaluate=False)
|
| 2032 |
+
assert Mod(expr, 3**10) == 6487
|
| 2033 |
+
expr = Pow(2, expr, evaluate=False)
|
| 2034 |
+
assert Mod(expr, 3**10) == 32191
|
| 2035 |
+
expr = Pow(2, expr, evaluate=False)
|
| 2036 |
+
assert Mod(expr, 3**10) == 18016
|
| 2037 |
+
expr = Pow(2, expr, evaluate=False)
|
| 2038 |
+
assert Mod(expr, 3**10) == 5137
|
| 2039 |
+
|
| 2040 |
+
expr = Pow(2, 2, evaluate=False)
|
| 2041 |
+
expr = Pow(expr, 2, evaluate=False)
|
| 2042 |
+
assert Mod(expr, 3**10) == 16
|
| 2043 |
+
expr = Pow(expr, 2, evaluate=False)
|
| 2044 |
+
assert Mod(expr, 3**10) == 256
|
| 2045 |
+
expr = Pow(expr, 2, evaluate=False)
|
| 2046 |
+
assert Mod(expr, 3**10) == 6487
|
| 2047 |
+
expr = Pow(expr, 2, evaluate=False)
|
| 2048 |
+
assert Mod(expr, 3**10) == 38281
|
| 2049 |
+
expr = Pow(expr, 2, evaluate=False)
|
| 2050 |
+
assert Mod(expr, 3**10) == 15928
|
| 2051 |
+
|
| 2052 |
+
expr = Pow(2, 2, evaluate=False)
|
| 2053 |
+
expr = Pow(expr, expr, evaluate=False)
|
| 2054 |
+
assert Mod(expr, 3**10) == 256
|
| 2055 |
+
expr = Pow(expr, expr, evaluate=False)
|
| 2056 |
+
assert Mod(expr, 3**10) == 9229
|
| 2057 |
+
expr = Pow(expr, expr, evaluate=False)
|
| 2058 |
+
assert Mod(expr, 3**10) == 25708
|
| 2059 |
+
expr = Pow(expr, expr, evaluate=False)
|
| 2060 |
+
assert Mod(expr, 3**10) == 26608
|
| 2061 |
+
expr = Pow(expr, expr, evaluate=False)
|
| 2062 |
+
# XXX This used to fail in a nondeterministic way because of overflow
|
| 2063 |
+
# error.
|
| 2064 |
+
assert Mod(expr, 3**10) == 1966
|
| 2065 |
+
|
| 2066 |
+
|
| 2067 |
+
def test_Mod_is_integer():
|
| 2068 |
+
p = Symbol('p', integer=True)
|
| 2069 |
+
q1 = Symbol('q1', integer=True)
|
| 2070 |
+
q2 = Symbol('q2', integer=True, nonzero=True)
|
| 2071 |
+
assert Mod(x, y).is_integer is None
|
| 2072 |
+
assert Mod(p, q1).is_integer is None
|
| 2073 |
+
assert Mod(x, q2).is_integer is None
|
| 2074 |
+
assert Mod(p, q2).is_integer
|
| 2075 |
+
|
| 2076 |
+
|
| 2077 |
+
def test_Mod_is_nonposneg():
|
| 2078 |
+
n = Symbol('n', integer=True)
|
| 2079 |
+
k = Symbol('k', integer=True, positive=True)
|
| 2080 |
+
assert (n%3).is_nonnegative
|
| 2081 |
+
assert Mod(n, -3).is_nonpositive
|
| 2082 |
+
assert Mod(n, k).is_nonnegative
|
| 2083 |
+
assert Mod(n, -k).is_nonpositive
|
| 2084 |
+
assert Mod(k, n).is_nonnegative is None
|
| 2085 |
+
|
| 2086 |
+
|
| 2087 |
+
def test_issue_6001():
|
| 2088 |
+
A = Symbol("A", commutative=False)
|
| 2089 |
+
eq = A + A**2
|
| 2090 |
+
# it doesn't matter whether it's True or False; they should
|
| 2091 |
+
# just all be the same
|
| 2092 |
+
assert (
|
| 2093 |
+
eq.is_commutative ==
|
| 2094 |
+
(eq + 1).is_commutative ==
|
| 2095 |
+
(A + 1).is_commutative)
|
| 2096 |
+
|
| 2097 |
+
B = Symbol("B", commutative=False)
|
| 2098 |
+
# Although commutative terms could cancel we return True
|
| 2099 |
+
# meaning "there are non-commutative symbols; aftersubstitution
|
| 2100 |
+
# that definition can change, e.g. (A*B).subs(B,A**-1) -> 1
|
| 2101 |
+
assert (sqrt(2)*A).is_commutative is False
|
| 2102 |
+
assert (sqrt(2)*A*B).is_commutative is False
|
| 2103 |
+
|
| 2104 |
+
|
| 2105 |
+
def test_polar():
|
| 2106 |
+
from sympy.functions.elementary.complexes import polar_lift
|
| 2107 |
+
p = Symbol('p', polar=True)
|
| 2108 |
+
x = Symbol('x')
|
| 2109 |
+
assert p.is_polar
|
| 2110 |
+
assert x.is_polar is None
|
| 2111 |
+
assert S.One.is_polar is None
|
| 2112 |
+
assert (p**x).is_polar is True
|
| 2113 |
+
assert (x**p).is_polar is None
|
| 2114 |
+
assert ((2*p)**x).is_polar is True
|
| 2115 |
+
assert (2*p).is_polar is True
|
| 2116 |
+
assert (-2*p).is_polar is not True
|
| 2117 |
+
assert (polar_lift(-2)*p).is_polar is True
|
| 2118 |
+
|
| 2119 |
+
q = Symbol('q', polar=True)
|
| 2120 |
+
assert (p*q)**2 == p**2 * q**2
|
| 2121 |
+
assert (2*q)**2 == 4 * q**2
|
| 2122 |
+
assert ((p*q)**x).expand() == p**x * q**x
|
| 2123 |
+
|
| 2124 |
+
|
| 2125 |
+
def test_issue_6040():
|
| 2126 |
+
a, b = Pow(1, 2, evaluate=False), S.One
|
| 2127 |
+
assert a != b
|
| 2128 |
+
assert b != a
|
| 2129 |
+
assert not (a == b)
|
| 2130 |
+
assert not (b == a)
|
| 2131 |
+
|
| 2132 |
+
|
| 2133 |
+
def test_issue_6082():
|
| 2134 |
+
# Comparison is symmetric
|
| 2135 |
+
assert Basic.compare(Max(x, 1), Max(x, 2)) == \
|
| 2136 |
+
- Basic.compare(Max(x, 2), Max(x, 1))
|
| 2137 |
+
# Equal expressions compare equal
|
| 2138 |
+
assert Basic.compare(Max(x, 1), Max(x, 1)) == 0
|
| 2139 |
+
# Basic subtypes (such as Max) compare different than standard types
|
| 2140 |
+
assert Basic.compare(Max(1, x), frozenset((1, x))) != 0
|
| 2141 |
+
|
| 2142 |
+
|
| 2143 |
+
def test_issue_6077():
|
| 2144 |
+
assert x**2.0/x == x**1.0
|
| 2145 |
+
assert x/x**2.0 == x**-1.0
|
| 2146 |
+
assert x*x**2.0 == x**3.0
|
| 2147 |
+
assert x**1.5*x**2.5 == x**4.0
|
| 2148 |
+
|
| 2149 |
+
assert 2**(2.0*x)/2**x == 2**(1.0*x)
|
| 2150 |
+
assert 2**x/2**(2.0*x) == 2**(-1.0*x)
|
| 2151 |
+
assert 2**x*2**(2.0*x) == 2**(3.0*x)
|
| 2152 |
+
assert 2**(1.5*x)*2**(2.5*x) == 2**(4.0*x)
|
| 2153 |
+
|
| 2154 |
+
|
| 2155 |
+
def test_mul_flatten_oo():
|
| 2156 |
+
p = symbols('p', positive=True)
|
| 2157 |
+
n, m = symbols('n,m', negative=True)
|
| 2158 |
+
x_im = symbols('x_im', imaginary=True)
|
| 2159 |
+
assert n*oo is -oo
|
| 2160 |
+
assert n*m*oo is oo
|
| 2161 |
+
assert p*oo is oo
|
| 2162 |
+
assert x_im*oo != I*oo # i could be +/- 3*I -> +/-oo
|
| 2163 |
+
|
| 2164 |
+
|
| 2165 |
+
def test_add_flatten():
|
| 2166 |
+
# see https://github.com/sympy/sympy/issues/2633#issuecomment-29545524
|
| 2167 |
+
a = oo + I*oo
|
| 2168 |
+
b = oo - I*oo
|
| 2169 |
+
assert a + b is nan
|
| 2170 |
+
assert a - b is nan
|
| 2171 |
+
# FIXME: This evaluates as:
|
| 2172 |
+
# >>> 1/a
|
| 2173 |
+
# 0*(oo + oo*I)
|
| 2174 |
+
# which should not simplify to 0. Should be fixed in Pow.eval
|
| 2175 |
+
#assert (1/a).simplify() == (1/b).simplify() == 0
|
| 2176 |
+
|
| 2177 |
+
a = Pow(2, 3, evaluate=False)
|
| 2178 |
+
assert a + a == 16
|
| 2179 |
+
|
| 2180 |
+
|
| 2181 |
+
def test_issue_5160_6087_6089_6090():
|
| 2182 |
+
# issue 6087
|
| 2183 |
+
assert ((-2*x*y**y)**3.2).n(2) == (2**3.2*(-x*y**y)**3.2).n(2)
|
| 2184 |
+
# issue 6089
|
| 2185 |
+
A, B, C = symbols('A,B,C', commutative=False)
|
| 2186 |
+
assert (2.*B*C)**3 == 8.0*(B*C)**3
|
| 2187 |
+
assert (-2.*B*C)**3 == -8.0*(B*C)**3
|
| 2188 |
+
assert (-2*B*C)**2 == 4*(B*C)**2
|
| 2189 |
+
# issue 5160
|
| 2190 |
+
assert sqrt(-1.0*x) == 1.0*sqrt(-x)
|
| 2191 |
+
assert sqrt(1.0*x) == 1.0*sqrt(x)
|
| 2192 |
+
# issue 6090
|
| 2193 |
+
assert (-2*x*y*A*B)**2 == 4*x**2*y**2*(A*B)**2
|
| 2194 |
+
|
| 2195 |
+
|
| 2196 |
+
def test_float_int_round():
|
| 2197 |
+
assert int(float(sqrt(10))) == int(sqrt(10))
|
| 2198 |
+
assert int(pi**1000) % 10 == 2
|
| 2199 |
+
assert int(Float('1.123456789012345678901234567890e20', '')) == \
|
| 2200 |
+
int(112345678901234567890)
|
| 2201 |
+
assert int(Float('1.123456789012345678901234567890e25', '')) == \
|
| 2202 |
+
int(11234567890123456789012345)
|
| 2203 |
+
# decimal forces float so it's not an exact integer ending in 000000
|
| 2204 |
+
assert int(Float('1.123456789012345678901234567890e35', '')) == \
|
| 2205 |
+
112345678901234567890123456789000192
|
| 2206 |
+
assert int(Float('123456789012345678901234567890e5', '')) == \
|
| 2207 |
+
12345678901234567890123456789000000
|
| 2208 |
+
assert Integer(Float('1.123456789012345678901234567890e20', '')) == \
|
| 2209 |
+
112345678901234567890
|
| 2210 |
+
assert Integer(Float('1.123456789012345678901234567890e25', '')) == \
|
| 2211 |
+
11234567890123456789012345
|
| 2212 |
+
# decimal forces float so it's not an exact integer ending in 000000
|
| 2213 |
+
assert Integer(Float('1.123456789012345678901234567890e35', '')) == \
|
| 2214 |
+
112345678901234567890123456789000192
|
| 2215 |
+
assert Integer(Float('123456789012345678901234567890e5', '')) == \
|
| 2216 |
+
12345678901234567890123456789000000
|
| 2217 |
+
assert same_and_same_prec(Float('123000e-2',''), Float('1230.00', ''))
|
| 2218 |
+
assert same_and_same_prec(Float('123000e2',''), Float('12300000', ''))
|
| 2219 |
+
|
| 2220 |
+
assert int(1 + Rational('.9999999999999999999999999')) == 1
|
| 2221 |
+
assert int(pi/1e20) == 0
|
| 2222 |
+
assert int(1 + pi/1e20) == 1
|
| 2223 |
+
assert int(Add(1.2, -2, evaluate=False)) == int(1.2 - 2)
|
| 2224 |
+
assert int(Add(1.2, +2, evaluate=False)) == int(1.2 + 2)
|
| 2225 |
+
assert int(Add(1 + Float('.99999999999999999', ''), evaluate=False)) == 1
|
| 2226 |
+
raises(TypeError, lambda: float(x))
|
| 2227 |
+
raises(TypeError, lambda: float(sqrt(-1)))
|
| 2228 |
+
|
| 2229 |
+
assert int(12345678901234567890 + cos(1)**2 + sin(1)**2) == \
|
| 2230 |
+
12345678901234567891
|
| 2231 |
+
|
| 2232 |
+
|
| 2233 |
+
def test_issue_6611a():
|
| 2234 |
+
assert Mul.flatten([3**Rational(1, 3),
|
| 2235 |
+
Pow(-Rational(1, 9), Rational(2, 3), evaluate=False)]) == \
|
| 2236 |
+
([Rational(1, 3), (-1)**Rational(2, 3)], [], None)
|
| 2237 |
+
|
| 2238 |
+
|
| 2239 |
+
def test_denest_add_mul():
|
| 2240 |
+
# when working with evaluated expressions make sure they denest
|
| 2241 |
+
eq = x + 1
|
| 2242 |
+
eq = Add(eq, 2, evaluate=False)
|
| 2243 |
+
eq = Add(eq, 2, evaluate=False)
|
| 2244 |
+
assert Add(*eq.args) == x + 5
|
| 2245 |
+
eq = x*2
|
| 2246 |
+
eq = Mul(eq, 2, evaluate=False)
|
| 2247 |
+
eq = Mul(eq, 2, evaluate=False)
|
| 2248 |
+
assert Mul(*eq.args) == 8*x
|
| 2249 |
+
# but don't let them denest unnecessarily
|
| 2250 |
+
eq = Mul(-2, x - 2, evaluate=False)
|
| 2251 |
+
assert 2*eq == Mul(-4, x - 2, evaluate=False)
|
| 2252 |
+
assert -eq == Mul(2, x - 2, evaluate=False)
|
| 2253 |
+
|
| 2254 |
+
|
| 2255 |
+
def test_mul_coeff():
|
| 2256 |
+
# It is important that all Numbers be removed from the seq;
|
| 2257 |
+
# This can be tricky when powers combine to produce those numbers
|
| 2258 |
+
p = exp(I*pi/3)
|
| 2259 |
+
assert p**2*x*p*y*p*x*p**2 == x**2*y
|
| 2260 |
+
|
| 2261 |
+
|
| 2262 |
+
def test_mul_zero_detection():
|
| 2263 |
+
nz = Dummy(real=True, zero=False)
|
| 2264 |
+
r = Dummy(extended_real=True)
|
| 2265 |
+
c = Dummy(real=False, complex=True)
|
| 2266 |
+
c2 = Dummy(real=False, complex=True)
|
| 2267 |
+
i = Dummy(imaginary=True)
|
| 2268 |
+
e = nz*r*c
|
| 2269 |
+
assert e.is_imaginary is None
|
| 2270 |
+
assert e.is_extended_real is None
|
| 2271 |
+
e = nz*c
|
| 2272 |
+
assert e.is_imaginary is None
|
| 2273 |
+
assert e.is_extended_real is False
|
| 2274 |
+
e = nz*i*c
|
| 2275 |
+
assert e.is_imaginary is False
|
| 2276 |
+
assert e.is_extended_real is None
|
| 2277 |
+
# check for more than one complex; it is important to use
|
| 2278 |
+
# uniquely named Symbols to ensure that two factors appear
|
| 2279 |
+
# e.g. if the symbols have the same name they just become
|
| 2280 |
+
# a single factor, a power.
|
| 2281 |
+
e = nz*i*c*c2
|
| 2282 |
+
assert e.is_imaginary is None
|
| 2283 |
+
assert e.is_extended_real is None
|
| 2284 |
+
|
| 2285 |
+
# _eval_is_extended_real and _eval_is_zero both employ trapping of the
|
| 2286 |
+
# zero value so args should be tested in both directions and
|
| 2287 |
+
# TO AVOID GETTING THE CACHED RESULT, Dummy MUST BE USED
|
| 2288 |
+
|
| 2289 |
+
# real is unknown
|
| 2290 |
+
def test(z, b, e):
|
| 2291 |
+
if z.is_zero and b.is_finite:
|
| 2292 |
+
assert e.is_extended_real and e.is_zero
|
| 2293 |
+
else:
|
| 2294 |
+
assert e.is_extended_real is None
|
| 2295 |
+
if b.is_finite:
|
| 2296 |
+
if z.is_zero:
|
| 2297 |
+
assert e.is_zero
|
| 2298 |
+
else:
|
| 2299 |
+
assert e.is_zero is None
|
| 2300 |
+
elif b.is_finite is False:
|
| 2301 |
+
if z.is_zero is None:
|
| 2302 |
+
assert e.is_zero is None
|
| 2303 |
+
else:
|
| 2304 |
+
assert e.is_zero is False
|
| 2305 |
+
|
| 2306 |
+
|
| 2307 |
+
for iz, ib in product(*[[True, False, None]]*2):
|
| 2308 |
+
z = Dummy('z', nonzero=iz)
|
| 2309 |
+
b = Dummy('f', finite=ib)
|
| 2310 |
+
e = Mul(z, b, evaluate=False)
|
| 2311 |
+
test(z, b, e)
|
| 2312 |
+
z = Dummy('nz', nonzero=iz)
|
| 2313 |
+
b = Dummy('f', finite=ib)
|
| 2314 |
+
e = Mul(b, z, evaluate=False)
|
| 2315 |
+
test(z, b, e)
|
| 2316 |
+
|
| 2317 |
+
# real is True
|
| 2318 |
+
def test(z, b, e):
|
| 2319 |
+
if z.is_zero and not b.is_finite:
|
| 2320 |
+
assert e.is_extended_real is None
|
| 2321 |
+
else:
|
| 2322 |
+
assert e.is_extended_real is True
|
| 2323 |
+
|
| 2324 |
+
for iz, ib in product(*[[True, False, None]]*2):
|
| 2325 |
+
z = Dummy('z', nonzero=iz, extended_real=True)
|
| 2326 |
+
b = Dummy('b', finite=ib, extended_real=True)
|
| 2327 |
+
e = Mul(z, b, evaluate=False)
|
| 2328 |
+
test(z, b, e)
|
| 2329 |
+
z = Dummy('z', nonzero=iz, extended_real=True)
|
| 2330 |
+
b = Dummy('b', finite=ib, extended_real=True)
|
| 2331 |
+
e = Mul(b, z, evaluate=False)
|
| 2332 |
+
test(z, b, e)
|
| 2333 |
+
|
| 2334 |
+
|
| 2335 |
+
def test_Mul_with_zero_infinite():
|
| 2336 |
+
zer = Dummy(zero=True)
|
| 2337 |
+
inf = Dummy(finite=False)
|
| 2338 |
+
|
| 2339 |
+
e = Mul(zer, inf, evaluate=False)
|
| 2340 |
+
assert e.is_extended_positive is None
|
| 2341 |
+
assert e.is_hermitian is None
|
| 2342 |
+
|
| 2343 |
+
e = Mul(inf, zer, evaluate=False)
|
| 2344 |
+
assert e.is_extended_positive is None
|
| 2345 |
+
assert e.is_hermitian is None
|
| 2346 |
+
|
| 2347 |
+
|
| 2348 |
+
def test_Mul_does_not_cancel_infinities():
|
| 2349 |
+
a, b = symbols('a b')
|
| 2350 |
+
assert ((zoo + 3*a)/(3*a + zoo)) is nan
|
| 2351 |
+
assert ((b - oo)/(b - oo)) is nan
|
| 2352 |
+
# issue 13904
|
| 2353 |
+
expr = (1/(a+b) + 1/(a-b))/(1/(a+b) - 1/(a-b))
|
| 2354 |
+
assert expr.subs(b, a) is nan
|
| 2355 |
+
|
| 2356 |
+
|
| 2357 |
+
def test_Mul_does_not_distribute_infinity():
|
| 2358 |
+
a, b = symbols('a b')
|
| 2359 |
+
assert ((1 + I)*oo).is_Mul
|
| 2360 |
+
assert ((a + b)*(-oo)).is_Mul
|
| 2361 |
+
assert ((a + 1)*zoo).is_Mul
|
| 2362 |
+
assert ((1 + I)*oo).is_finite is False
|
| 2363 |
+
z = (1 + I)*oo
|
| 2364 |
+
assert ((1 - I)*z).expand() is oo
|
| 2365 |
+
|
| 2366 |
+
|
| 2367 |
+
def test_Mul_does_not_let_0_trump_inf():
|
| 2368 |
+
assert Mul(*[0, a + zoo]) is S.NaN
|
| 2369 |
+
assert Mul(*[0, a + oo]) is S.NaN
|
| 2370 |
+
assert Mul(*[0, a + Integral(1/x**2, (x, 1, oo))]) is S.Zero
|
| 2371 |
+
# Integral is treated like an unknown like 0*x -> 0
|
| 2372 |
+
assert Mul(*[0, a + Integral(x, (x, 1, oo))]) is S.Zero
|
| 2373 |
+
|
| 2374 |
+
|
| 2375 |
+
def test_issue_8247_8354():
|
| 2376 |
+
from sympy.functions.elementary.trigonometric import tan
|
| 2377 |
+
z = sqrt(1 + sqrt(3)) + sqrt(3 + 3*sqrt(3)) - sqrt(10 + 6*sqrt(3))
|
| 2378 |
+
assert z.is_positive is False # it's 0
|
| 2379 |
+
z = S('''-2**(1/3)*(3*sqrt(93) + 29)**2 - 4*(3*sqrt(93) + 29)**(4/3) +
|
| 2380 |
+
12*sqrt(93)*(3*sqrt(93) + 29)**(1/3) + 116*(3*sqrt(93) + 29)**(1/3) +
|
| 2381 |
+
174*2**(1/3)*sqrt(93) + 1678*2**(1/3)''')
|
| 2382 |
+
assert z.is_positive is False # it's 0
|
| 2383 |
+
z = 2*(-3*tan(19*pi/90) + sqrt(3))*cos(11*pi/90)*cos(19*pi/90) - \
|
| 2384 |
+
sqrt(3)*(-3 + 4*cos(19*pi/90)**2)
|
| 2385 |
+
assert z.is_positive is not True # it's zero and it shouldn't hang
|
| 2386 |
+
z = S('''9*(3*sqrt(93) + 29)**(2/3)*((3*sqrt(93) +
|
| 2387 |
+
29)**(1/3)*(-2**(2/3)*(3*sqrt(93) + 29)**(1/3) - 2) - 2*2**(1/3))**3 +
|
| 2388 |
+
72*(3*sqrt(93) + 29)**(2/3)*(81*sqrt(93) + 783) + (162*sqrt(93) +
|
| 2389 |
+
1566)*((3*sqrt(93) + 29)**(1/3)*(-2**(2/3)*(3*sqrt(93) + 29)**(1/3) -
|
| 2390 |
+
2) - 2*2**(1/3))**2''')
|
| 2391 |
+
assert z.is_positive is False # it's 0 (and a single _mexpand isn't enough)
|
| 2392 |
+
|
| 2393 |
+
|
| 2394 |
+
def test_Add_is_zero():
|
| 2395 |
+
x, y = symbols('x y', zero=True)
|
| 2396 |
+
assert (x + y).is_zero
|
| 2397 |
+
|
| 2398 |
+
# Issue 15873
|
| 2399 |
+
e = -2*I + (1 + I)**2
|
| 2400 |
+
assert e.is_zero is None
|
| 2401 |
+
|
| 2402 |
+
|
| 2403 |
+
def test_issue_14392():
|
| 2404 |
+
assert (sin(zoo)**2).as_real_imag() == (nan, nan)
|
| 2405 |
+
|
| 2406 |
+
|
| 2407 |
+
def test_divmod():
|
| 2408 |
+
assert divmod(x, y) == (x//y, x % y)
|
| 2409 |
+
assert divmod(x, 3) == (x//3, x % 3)
|
| 2410 |
+
assert divmod(3, x) == (3//x, 3 % x)
|
| 2411 |
+
|
| 2412 |
+
|
| 2413 |
+
def test__neg__():
|
| 2414 |
+
assert -(x*y) == -x*y
|
| 2415 |
+
assert -(-x*y) == x*y
|
| 2416 |
+
assert -(1.*x) == -1.*x
|
| 2417 |
+
assert -(-1.*x) == 1.*x
|
| 2418 |
+
assert -(2.*x) == -2.*x
|
| 2419 |
+
assert -(-2.*x) == 2.*x
|
| 2420 |
+
with distribute(False):
|
| 2421 |
+
eq = -(x + y)
|
| 2422 |
+
assert eq.is_Mul and eq.args == (-1, x + y)
|
| 2423 |
+
with evaluate(False):
|
| 2424 |
+
eq = -(x + y)
|
| 2425 |
+
assert eq.is_Mul and eq.args == (-1, x + y)
|
| 2426 |
+
|
| 2427 |
+
|
| 2428 |
+
def test_issue_18507():
|
| 2429 |
+
assert Mul(zoo, zoo, 0) is nan
|
| 2430 |
+
|
| 2431 |
+
|
| 2432 |
+
def test_issue_17130():
|
| 2433 |
+
e = Add(b, -b, I, -I, evaluate=False)
|
| 2434 |
+
assert e.is_zero is None # ideally this would be True
|
| 2435 |
+
|
| 2436 |
+
|
| 2437 |
+
def test_issue_21034():
|
| 2438 |
+
e = -I*log((re(asin(5)) + I*im(asin(5)))/sqrt(re(asin(5))**2 + im(asin(5))**2))/pi
|
| 2439 |
+
assert e.round(2)
|
| 2440 |
+
|
| 2441 |
+
|
| 2442 |
+
def test_issue_22021():
|
| 2443 |
+
from sympy.calculus.accumulationbounds import AccumBounds
|
| 2444 |
+
# these objects are special cases in Mul
|
| 2445 |
+
from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads
|
| 2446 |
+
L = TensorIndexType("L")
|
| 2447 |
+
i = tensor_indices("i", L)
|
| 2448 |
+
A, B = tensor_heads("A B", [L])
|
| 2449 |
+
e = A(i) + B(i)
|
| 2450 |
+
assert -e == -1*e
|
| 2451 |
+
e = zoo + x
|
| 2452 |
+
assert -e == -1*e
|
| 2453 |
+
a = AccumBounds(1, 2)
|
| 2454 |
+
e = a + x
|
| 2455 |
+
assert -e == -1*e
|
| 2456 |
+
for args in permutations((zoo, a, x)):
|
| 2457 |
+
e = Add(*args, evaluate=False)
|
| 2458 |
+
assert -e == -1*e
|
| 2459 |
+
assert 2*Add(1, x, x, evaluate=False) == 4*x + 2
|
| 2460 |
+
|
| 2461 |
+
|
| 2462 |
+
def test_issue_22244():
|
| 2463 |
+
assert -(zoo*x) == zoo*x
|
| 2464 |
+
|
| 2465 |
+
|
| 2466 |
+
def test_issue_22453():
|
| 2467 |
+
from sympy.utilities.iterables import cartes
|
| 2468 |
+
e = Symbol('e', extended_positive=True)
|
| 2469 |
+
for a, b in cartes(*[[oo, -oo, 3]]*2):
|
| 2470 |
+
if a == b == 3:
|
| 2471 |
+
continue
|
| 2472 |
+
i = a + I*b
|
| 2473 |
+
assert i**(1 + e) is S.ComplexInfinity
|
| 2474 |
+
assert i**-e is S.Zero
|
| 2475 |
+
assert unchanged(Pow, i, e)
|
| 2476 |
+
assert 1/(oo + I*oo) is S.Zero
|
| 2477 |
+
r, i = [Dummy(infinite=True, extended_real=True) for _ in range(2)]
|
| 2478 |
+
assert 1/(r + I*i) is S.Zero
|
| 2479 |
+
assert 1/(3 + I*i) is S.Zero
|
| 2480 |
+
assert 1/(r + I*3) is S.Zero
|
| 2481 |
+
|
| 2482 |
+
|
| 2483 |
+
def test_issue_22613():
|
| 2484 |
+
assert (0**(x - 2)).as_content_primitive() == (1, 0**(x - 2))
|
| 2485 |
+
assert (0**(x + 2)).as_content_primitive() == (1, 0**(x + 2))
|
| 2486 |
+
|
| 2487 |
+
|
| 2488 |
+
def test_issue_25176():
|
| 2489 |
+
assert sqrt(-4*3**(S(3)/4)*I/3) == 2*3**(S(7)/8)*sqrt(-I)/3
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_assumptions.py
ADDED
|
@@ -0,0 +1,1335 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.mod import Mod
|
| 2 |
+
from sympy.core.numbers import (I, oo, pi)
|
| 3 |
+
from sympy.functions.combinatorial.factorials import factorial
|
| 4 |
+
from sympy.functions.elementary.exponential import (exp, log)
|
| 5 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 6 |
+
from sympy.functions.elementary.trigonometric import (asin, sin)
|
| 7 |
+
from sympy.simplify.simplify import simplify
|
| 8 |
+
from sympy.core import Symbol, S, Rational, Integer, Dummy, Wild, Pow
|
| 9 |
+
from sympy.core.assumptions import (assumptions, check_assumptions,
|
| 10 |
+
failing_assumptions, common_assumptions, _generate_assumption_rules,
|
| 11 |
+
_load_pre_generated_assumption_rules)
|
| 12 |
+
from sympy.core.facts import InconsistentAssumptions
|
| 13 |
+
from sympy.core.random import seed
|
| 14 |
+
from sympy.combinatorics import Permutation
|
| 15 |
+
from sympy.combinatorics.perm_groups import PermutationGroup
|
| 16 |
+
|
| 17 |
+
from sympy.testing.pytest import raises, XFAIL
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def test_symbol_unset():
|
| 21 |
+
x = Symbol('x', real=True, integer=True)
|
| 22 |
+
assert x.is_real is True
|
| 23 |
+
assert x.is_integer is True
|
| 24 |
+
assert x.is_imaginary is False
|
| 25 |
+
assert x.is_noninteger is False
|
| 26 |
+
assert x.is_number is False
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def test_zero():
|
| 30 |
+
z = Integer(0)
|
| 31 |
+
assert z.is_commutative is True
|
| 32 |
+
assert z.is_integer is True
|
| 33 |
+
assert z.is_rational is True
|
| 34 |
+
assert z.is_algebraic is True
|
| 35 |
+
assert z.is_transcendental is False
|
| 36 |
+
assert z.is_real is True
|
| 37 |
+
assert z.is_complex is True
|
| 38 |
+
assert z.is_noninteger is False
|
| 39 |
+
assert z.is_irrational is False
|
| 40 |
+
assert z.is_imaginary is False
|
| 41 |
+
assert z.is_positive is False
|
| 42 |
+
assert z.is_negative is False
|
| 43 |
+
assert z.is_nonpositive is True
|
| 44 |
+
assert z.is_nonnegative is True
|
| 45 |
+
assert z.is_even is True
|
| 46 |
+
assert z.is_odd is False
|
| 47 |
+
assert z.is_finite is True
|
| 48 |
+
assert z.is_infinite is False
|
| 49 |
+
assert z.is_comparable is True
|
| 50 |
+
assert z.is_prime is False
|
| 51 |
+
assert z.is_composite is False
|
| 52 |
+
assert z.is_number is True
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def test_one():
|
| 56 |
+
z = Integer(1)
|
| 57 |
+
assert z.is_commutative is True
|
| 58 |
+
assert z.is_integer is True
|
| 59 |
+
assert z.is_rational is True
|
| 60 |
+
assert z.is_algebraic is True
|
| 61 |
+
assert z.is_transcendental is False
|
| 62 |
+
assert z.is_real is True
|
| 63 |
+
assert z.is_complex is True
|
| 64 |
+
assert z.is_noninteger is False
|
| 65 |
+
assert z.is_irrational is False
|
| 66 |
+
assert z.is_imaginary is False
|
| 67 |
+
assert z.is_positive is True
|
| 68 |
+
assert z.is_negative is False
|
| 69 |
+
assert z.is_nonpositive is False
|
| 70 |
+
assert z.is_nonnegative is True
|
| 71 |
+
assert z.is_even is False
|
| 72 |
+
assert z.is_odd is True
|
| 73 |
+
assert z.is_finite is True
|
| 74 |
+
assert z.is_infinite is False
|
| 75 |
+
assert z.is_comparable is True
|
| 76 |
+
assert z.is_prime is False
|
| 77 |
+
assert z.is_number is True
|
| 78 |
+
assert z.is_composite is False # issue 8807
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def test_negativeone():
|
| 82 |
+
z = Integer(-1)
|
| 83 |
+
assert z.is_commutative is True
|
| 84 |
+
assert z.is_integer is True
|
| 85 |
+
assert z.is_rational is True
|
| 86 |
+
assert z.is_algebraic is True
|
| 87 |
+
assert z.is_transcendental is False
|
| 88 |
+
assert z.is_real is True
|
| 89 |
+
assert z.is_complex is True
|
| 90 |
+
assert z.is_noninteger is False
|
| 91 |
+
assert z.is_irrational is False
|
| 92 |
+
assert z.is_imaginary is False
|
| 93 |
+
assert z.is_positive is False
|
| 94 |
+
assert z.is_negative is True
|
| 95 |
+
assert z.is_nonpositive is True
|
| 96 |
+
assert z.is_nonnegative is False
|
| 97 |
+
assert z.is_even is False
|
| 98 |
+
assert z.is_odd is True
|
| 99 |
+
assert z.is_finite is True
|
| 100 |
+
assert z.is_infinite is False
|
| 101 |
+
assert z.is_comparable is True
|
| 102 |
+
assert z.is_prime is False
|
| 103 |
+
assert z.is_composite is False
|
| 104 |
+
assert z.is_number is True
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def test_infinity():
|
| 108 |
+
oo = S.Infinity
|
| 109 |
+
|
| 110 |
+
assert oo.is_commutative is True
|
| 111 |
+
assert oo.is_integer is False
|
| 112 |
+
assert oo.is_rational is False
|
| 113 |
+
assert oo.is_algebraic is False
|
| 114 |
+
assert oo.is_transcendental is False
|
| 115 |
+
assert oo.is_extended_real is True
|
| 116 |
+
assert oo.is_real is False
|
| 117 |
+
assert oo.is_complex is False
|
| 118 |
+
assert oo.is_noninteger is True
|
| 119 |
+
assert oo.is_irrational is False
|
| 120 |
+
assert oo.is_imaginary is False
|
| 121 |
+
assert oo.is_nonzero is False
|
| 122 |
+
assert oo.is_positive is False
|
| 123 |
+
assert oo.is_negative is False
|
| 124 |
+
assert oo.is_nonpositive is False
|
| 125 |
+
assert oo.is_nonnegative is False
|
| 126 |
+
assert oo.is_extended_nonzero is True
|
| 127 |
+
assert oo.is_extended_positive is True
|
| 128 |
+
assert oo.is_extended_negative is False
|
| 129 |
+
assert oo.is_extended_nonpositive is False
|
| 130 |
+
assert oo.is_extended_nonnegative is True
|
| 131 |
+
assert oo.is_even is False
|
| 132 |
+
assert oo.is_odd is False
|
| 133 |
+
assert oo.is_finite is False
|
| 134 |
+
assert oo.is_infinite is True
|
| 135 |
+
assert oo.is_comparable is True
|
| 136 |
+
assert oo.is_prime is False
|
| 137 |
+
assert oo.is_composite is False
|
| 138 |
+
assert oo.is_number is True
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def test_neg_infinity():
|
| 142 |
+
mm = S.NegativeInfinity
|
| 143 |
+
|
| 144 |
+
assert mm.is_commutative is True
|
| 145 |
+
assert mm.is_integer is False
|
| 146 |
+
assert mm.is_rational is False
|
| 147 |
+
assert mm.is_algebraic is False
|
| 148 |
+
assert mm.is_transcendental is False
|
| 149 |
+
assert mm.is_extended_real is True
|
| 150 |
+
assert mm.is_real is False
|
| 151 |
+
assert mm.is_complex is False
|
| 152 |
+
assert mm.is_noninteger is True
|
| 153 |
+
assert mm.is_irrational is False
|
| 154 |
+
assert mm.is_imaginary is False
|
| 155 |
+
assert mm.is_nonzero is False
|
| 156 |
+
assert mm.is_positive is False
|
| 157 |
+
assert mm.is_negative is False
|
| 158 |
+
assert mm.is_nonpositive is False
|
| 159 |
+
assert mm.is_nonnegative is False
|
| 160 |
+
assert mm.is_extended_nonzero is True
|
| 161 |
+
assert mm.is_extended_positive is False
|
| 162 |
+
assert mm.is_extended_negative is True
|
| 163 |
+
assert mm.is_extended_nonpositive is True
|
| 164 |
+
assert mm.is_extended_nonnegative is False
|
| 165 |
+
assert mm.is_even is False
|
| 166 |
+
assert mm.is_odd is False
|
| 167 |
+
assert mm.is_finite is False
|
| 168 |
+
assert mm.is_infinite is True
|
| 169 |
+
assert mm.is_comparable is True
|
| 170 |
+
assert mm.is_prime is False
|
| 171 |
+
assert mm.is_composite is False
|
| 172 |
+
assert mm.is_number is True
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
def test_zoo():
|
| 176 |
+
zoo = S.ComplexInfinity
|
| 177 |
+
assert zoo.is_complex is False
|
| 178 |
+
assert zoo.is_real is False
|
| 179 |
+
assert zoo.is_prime is False
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
def test_nan():
|
| 183 |
+
nan = S.NaN
|
| 184 |
+
|
| 185 |
+
assert nan.is_commutative is True
|
| 186 |
+
assert nan.is_integer is None
|
| 187 |
+
assert nan.is_rational is None
|
| 188 |
+
assert nan.is_algebraic is None
|
| 189 |
+
assert nan.is_transcendental is None
|
| 190 |
+
assert nan.is_real is None
|
| 191 |
+
assert nan.is_complex is None
|
| 192 |
+
assert nan.is_noninteger is None
|
| 193 |
+
assert nan.is_irrational is None
|
| 194 |
+
assert nan.is_imaginary is None
|
| 195 |
+
assert nan.is_positive is None
|
| 196 |
+
assert nan.is_negative is None
|
| 197 |
+
assert nan.is_nonpositive is None
|
| 198 |
+
assert nan.is_nonnegative is None
|
| 199 |
+
assert nan.is_even is None
|
| 200 |
+
assert nan.is_odd is None
|
| 201 |
+
assert nan.is_finite is None
|
| 202 |
+
assert nan.is_infinite is None
|
| 203 |
+
assert nan.is_comparable is False
|
| 204 |
+
assert nan.is_prime is None
|
| 205 |
+
assert nan.is_composite is None
|
| 206 |
+
assert nan.is_number is True
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
def test_pos_rational():
|
| 210 |
+
r = Rational(3, 4)
|
| 211 |
+
assert r.is_commutative is True
|
| 212 |
+
assert r.is_integer is False
|
| 213 |
+
assert r.is_rational is True
|
| 214 |
+
assert r.is_algebraic is True
|
| 215 |
+
assert r.is_transcendental is False
|
| 216 |
+
assert r.is_real is True
|
| 217 |
+
assert r.is_complex is True
|
| 218 |
+
assert r.is_noninteger is True
|
| 219 |
+
assert r.is_irrational is False
|
| 220 |
+
assert r.is_imaginary is False
|
| 221 |
+
assert r.is_positive is True
|
| 222 |
+
assert r.is_negative is False
|
| 223 |
+
assert r.is_nonpositive is False
|
| 224 |
+
assert r.is_nonnegative is True
|
| 225 |
+
assert r.is_even is False
|
| 226 |
+
assert r.is_odd is False
|
| 227 |
+
assert r.is_finite is True
|
| 228 |
+
assert r.is_infinite is False
|
| 229 |
+
assert r.is_comparable is True
|
| 230 |
+
assert r.is_prime is False
|
| 231 |
+
assert r.is_composite is False
|
| 232 |
+
|
| 233 |
+
r = Rational(1, 4)
|
| 234 |
+
assert r.is_nonpositive is False
|
| 235 |
+
assert r.is_positive is True
|
| 236 |
+
assert r.is_negative is False
|
| 237 |
+
assert r.is_nonnegative is True
|
| 238 |
+
r = Rational(5, 4)
|
| 239 |
+
assert r.is_negative is False
|
| 240 |
+
assert r.is_positive is True
|
| 241 |
+
assert r.is_nonpositive is False
|
| 242 |
+
assert r.is_nonnegative is True
|
| 243 |
+
r = Rational(5, 3)
|
| 244 |
+
assert r.is_nonnegative is True
|
| 245 |
+
assert r.is_positive is True
|
| 246 |
+
assert r.is_negative is False
|
| 247 |
+
assert r.is_nonpositive is False
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
def test_neg_rational():
|
| 251 |
+
r = Rational(-3, 4)
|
| 252 |
+
assert r.is_positive is False
|
| 253 |
+
assert r.is_nonpositive is True
|
| 254 |
+
assert r.is_negative is True
|
| 255 |
+
assert r.is_nonnegative is False
|
| 256 |
+
r = Rational(-1, 4)
|
| 257 |
+
assert r.is_nonpositive is True
|
| 258 |
+
assert r.is_positive is False
|
| 259 |
+
assert r.is_negative is True
|
| 260 |
+
assert r.is_nonnegative is False
|
| 261 |
+
r = Rational(-5, 4)
|
| 262 |
+
assert r.is_negative is True
|
| 263 |
+
assert r.is_positive is False
|
| 264 |
+
assert r.is_nonpositive is True
|
| 265 |
+
assert r.is_nonnegative is False
|
| 266 |
+
r = Rational(-5, 3)
|
| 267 |
+
assert r.is_nonnegative is False
|
| 268 |
+
assert r.is_positive is False
|
| 269 |
+
assert r.is_negative is True
|
| 270 |
+
assert r.is_nonpositive is True
|
| 271 |
+
|
| 272 |
+
|
| 273 |
+
def test_pi():
|
| 274 |
+
z = S.Pi
|
| 275 |
+
assert z.is_commutative is True
|
| 276 |
+
assert z.is_integer is False
|
| 277 |
+
assert z.is_rational is False
|
| 278 |
+
assert z.is_algebraic is False
|
| 279 |
+
assert z.is_transcendental is True
|
| 280 |
+
assert z.is_real is True
|
| 281 |
+
assert z.is_complex is True
|
| 282 |
+
assert z.is_noninteger is True
|
| 283 |
+
assert z.is_irrational is True
|
| 284 |
+
assert z.is_imaginary is False
|
| 285 |
+
assert z.is_positive is True
|
| 286 |
+
assert z.is_negative is False
|
| 287 |
+
assert z.is_nonpositive is False
|
| 288 |
+
assert z.is_nonnegative is True
|
| 289 |
+
assert z.is_even is False
|
| 290 |
+
assert z.is_odd is False
|
| 291 |
+
assert z.is_finite is True
|
| 292 |
+
assert z.is_infinite is False
|
| 293 |
+
assert z.is_comparable is True
|
| 294 |
+
assert z.is_prime is False
|
| 295 |
+
assert z.is_composite is False
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
def test_E():
|
| 299 |
+
z = S.Exp1
|
| 300 |
+
assert z.is_commutative is True
|
| 301 |
+
assert z.is_integer is False
|
| 302 |
+
assert z.is_rational is False
|
| 303 |
+
assert z.is_algebraic is False
|
| 304 |
+
assert z.is_transcendental is True
|
| 305 |
+
assert z.is_real is True
|
| 306 |
+
assert z.is_complex is True
|
| 307 |
+
assert z.is_noninteger is True
|
| 308 |
+
assert z.is_irrational is True
|
| 309 |
+
assert z.is_imaginary is False
|
| 310 |
+
assert z.is_positive is True
|
| 311 |
+
assert z.is_negative is False
|
| 312 |
+
assert z.is_nonpositive is False
|
| 313 |
+
assert z.is_nonnegative is True
|
| 314 |
+
assert z.is_even is False
|
| 315 |
+
assert z.is_odd is False
|
| 316 |
+
assert z.is_finite is True
|
| 317 |
+
assert z.is_infinite is False
|
| 318 |
+
assert z.is_comparable is True
|
| 319 |
+
assert z.is_prime is False
|
| 320 |
+
assert z.is_composite is False
|
| 321 |
+
|
| 322 |
+
|
| 323 |
+
def test_I():
|
| 324 |
+
z = S.ImaginaryUnit
|
| 325 |
+
assert z.is_commutative is True
|
| 326 |
+
assert z.is_integer is False
|
| 327 |
+
assert z.is_rational is False
|
| 328 |
+
assert z.is_algebraic is True
|
| 329 |
+
assert z.is_transcendental is False
|
| 330 |
+
assert z.is_real is False
|
| 331 |
+
assert z.is_complex is True
|
| 332 |
+
assert z.is_noninteger is False
|
| 333 |
+
assert z.is_irrational is False
|
| 334 |
+
assert z.is_imaginary is True
|
| 335 |
+
assert z.is_positive is False
|
| 336 |
+
assert z.is_negative is False
|
| 337 |
+
assert z.is_nonpositive is False
|
| 338 |
+
assert z.is_nonnegative is False
|
| 339 |
+
assert z.is_even is False
|
| 340 |
+
assert z.is_odd is False
|
| 341 |
+
assert z.is_finite is True
|
| 342 |
+
assert z.is_infinite is False
|
| 343 |
+
assert z.is_comparable is False
|
| 344 |
+
assert z.is_prime is False
|
| 345 |
+
assert z.is_composite is False
|
| 346 |
+
|
| 347 |
+
|
| 348 |
+
def test_symbol_real_false():
|
| 349 |
+
# issue 3848
|
| 350 |
+
a = Symbol('a', real=False)
|
| 351 |
+
|
| 352 |
+
assert a.is_real is False
|
| 353 |
+
assert a.is_integer is False
|
| 354 |
+
assert a.is_zero is False
|
| 355 |
+
|
| 356 |
+
assert a.is_negative is False
|
| 357 |
+
assert a.is_positive is False
|
| 358 |
+
assert a.is_nonnegative is False
|
| 359 |
+
assert a.is_nonpositive is False
|
| 360 |
+
assert a.is_nonzero is False
|
| 361 |
+
|
| 362 |
+
assert a.is_extended_negative is None
|
| 363 |
+
assert a.is_extended_positive is None
|
| 364 |
+
assert a.is_extended_nonnegative is None
|
| 365 |
+
assert a.is_extended_nonpositive is None
|
| 366 |
+
assert a.is_extended_nonzero is None
|
| 367 |
+
|
| 368 |
+
|
| 369 |
+
def test_symbol_extended_real_false():
|
| 370 |
+
# issue 3848
|
| 371 |
+
a = Symbol('a', extended_real=False)
|
| 372 |
+
|
| 373 |
+
assert a.is_real is False
|
| 374 |
+
assert a.is_integer is False
|
| 375 |
+
assert a.is_zero is False
|
| 376 |
+
|
| 377 |
+
assert a.is_negative is False
|
| 378 |
+
assert a.is_positive is False
|
| 379 |
+
assert a.is_nonnegative is False
|
| 380 |
+
assert a.is_nonpositive is False
|
| 381 |
+
assert a.is_nonzero is False
|
| 382 |
+
|
| 383 |
+
assert a.is_extended_negative is False
|
| 384 |
+
assert a.is_extended_positive is False
|
| 385 |
+
assert a.is_extended_nonnegative is False
|
| 386 |
+
assert a.is_extended_nonpositive is False
|
| 387 |
+
assert a.is_extended_nonzero is False
|
| 388 |
+
|
| 389 |
+
|
| 390 |
+
def test_symbol_imaginary():
|
| 391 |
+
a = Symbol('a', imaginary=True)
|
| 392 |
+
|
| 393 |
+
assert a.is_real is False
|
| 394 |
+
assert a.is_integer is False
|
| 395 |
+
assert a.is_negative is False
|
| 396 |
+
assert a.is_positive is False
|
| 397 |
+
assert a.is_nonnegative is False
|
| 398 |
+
assert a.is_nonpositive is False
|
| 399 |
+
assert a.is_zero is False
|
| 400 |
+
assert a.is_nonzero is False # since nonzero -> real
|
| 401 |
+
|
| 402 |
+
|
| 403 |
+
def test_symbol_zero():
|
| 404 |
+
x = Symbol('x', zero=True)
|
| 405 |
+
assert x.is_positive is False
|
| 406 |
+
assert x.is_nonpositive
|
| 407 |
+
assert x.is_negative is False
|
| 408 |
+
assert x.is_nonnegative
|
| 409 |
+
assert x.is_zero is True
|
| 410 |
+
# TODO Change to x.is_nonzero is None
|
| 411 |
+
# See https://github.com/sympy/sympy/pull/9583
|
| 412 |
+
assert x.is_nonzero is False
|
| 413 |
+
assert x.is_finite is True
|
| 414 |
+
|
| 415 |
+
|
| 416 |
+
def test_symbol_positive():
|
| 417 |
+
x = Symbol('x', positive=True)
|
| 418 |
+
assert x.is_positive is True
|
| 419 |
+
assert x.is_nonpositive is False
|
| 420 |
+
assert x.is_negative is False
|
| 421 |
+
assert x.is_nonnegative is True
|
| 422 |
+
assert x.is_zero is False
|
| 423 |
+
assert x.is_nonzero is True
|
| 424 |
+
|
| 425 |
+
|
| 426 |
+
def test_neg_symbol_positive():
|
| 427 |
+
x = -Symbol('x', positive=True)
|
| 428 |
+
assert x.is_positive is False
|
| 429 |
+
assert x.is_nonpositive is True
|
| 430 |
+
assert x.is_negative is True
|
| 431 |
+
assert x.is_nonnegative is False
|
| 432 |
+
assert x.is_zero is False
|
| 433 |
+
assert x.is_nonzero is True
|
| 434 |
+
|
| 435 |
+
|
| 436 |
+
def test_symbol_nonpositive():
|
| 437 |
+
x = Symbol('x', nonpositive=True)
|
| 438 |
+
assert x.is_positive is False
|
| 439 |
+
assert x.is_nonpositive is True
|
| 440 |
+
assert x.is_negative is None
|
| 441 |
+
assert x.is_nonnegative is None
|
| 442 |
+
assert x.is_zero is None
|
| 443 |
+
assert x.is_nonzero is None
|
| 444 |
+
|
| 445 |
+
|
| 446 |
+
def test_neg_symbol_nonpositive():
|
| 447 |
+
x = -Symbol('x', nonpositive=True)
|
| 448 |
+
assert x.is_positive is None
|
| 449 |
+
assert x.is_nonpositive is None
|
| 450 |
+
assert x.is_negative is False
|
| 451 |
+
assert x.is_nonnegative is True
|
| 452 |
+
assert x.is_zero is None
|
| 453 |
+
assert x.is_nonzero is None
|
| 454 |
+
|
| 455 |
+
|
| 456 |
+
def test_symbol_falsepositive():
|
| 457 |
+
x = Symbol('x', positive=False)
|
| 458 |
+
assert x.is_positive is False
|
| 459 |
+
assert x.is_nonpositive is None
|
| 460 |
+
assert x.is_negative is None
|
| 461 |
+
assert x.is_nonnegative is None
|
| 462 |
+
assert x.is_zero is None
|
| 463 |
+
assert x.is_nonzero is None
|
| 464 |
+
|
| 465 |
+
|
| 466 |
+
def test_symbol_falsepositive_mul():
|
| 467 |
+
# To test pull request 9379
|
| 468 |
+
# Explicit handling of arg.is_positive=False was added to Mul._eval_is_positive
|
| 469 |
+
x = 2*Symbol('x', positive=False)
|
| 470 |
+
assert x.is_positive is False # This was None before
|
| 471 |
+
assert x.is_nonpositive is None
|
| 472 |
+
assert x.is_negative is None
|
| 473 |
+
assert x.is_nonnegative is None
|
| 474 |
+
assert x.is_zero is None
|
| 475 |
+
assert x.is_nonzero is None
|
| 476 |
+
|
| 477 |
+
|
| 478 |
+
@XFAIL
|
| 479 |
+
def test_symbol_infinitereal_mul():
|
| 480 |
+
ix = Symbol('ix', infinite=True, extended_real=True)
|
| 481 |
+
assert (-ix).is_extended_positive is None
|
| 482 |
+
|
| 483 |
+
|
| 484 |
+
def test_neg_symbol_falsepositive():
|
| 485 |
+
x = -Symbol('x', positive=False)
|
| 486 |
+
assert x.is_positive is None
|
| 487 |
+
assert x.is_nonpositive is None
|
| 488 |
+
assert x.is_negative is False
|
| 489 |
+
assert x.is_nonnegative is None
|
| 490 |
+
assert x.is_zero is None
|
| 491 |
+
assert x.is_nonzero is None
|
| 492 |
+
|
| 493 |
+
|
| 494 |
+
def test_neg_symbol_falsenegative():
|
| 495 |
+
# To test pull request 9379
|
| 496 |
+
# Explicit handling of arg.is_negative=False was added to Mul._eval_is_positive
|
| 497 |
+
x = -Symbol('x', negative=False)
|
| 498 |
+
assert x.is_positive is False # This was None before
|
| 499 |
+
assert x.is_nonpositive is None
|
| 500 |
+
assert x.is_negative is None
|
| 501 |
+
assert x.is_nonnegative is None
|
| 502 |
+
assert x.is_zero is None
|
| 503 |
+
assert x.is_nonzero is None
|
| 504 |
+
|
| 505 |
+
|
| 506 |
+
def test_symbol_falsepositive_real():
|
| 507 |
+
x = Symbol('x', positive=False, real=True)
|
| 508 |
+
assert x.is_positive is False
|
| 509 |
+
assert x.is_nonpositive is True
|
| 510 |
+
assert x.is_negative is None
|
| 511 |
+
assert x.is_nonnegative is None
|
| 512 |
+
assert x.is_zero is None
|
| 513 |
+
assert x.is_nonzero is None
|
| 514 |
+
|
| 515 |
+
|
| 516 |
+
def test_neg_symbol_falsepositive_real():
|
| 517 |
+
x = -Symbol('x', positive=False, real=True)
|
| 518 |
+
assert x.is_positive is None
|
| 519 |
+
assert x.is_nonpositive is None
|
| 520 |
+
assert x.is_negative is False
|
| 521 |
+
assert x.is_nonnegative is True
|
| 522 |
+
assert x.is_zero is None
|
| 523 |
+
assert x.is_nonzero is None
|
| 524 |
+
|
| 525 |
+
|
| 526 |
+
def test_symbol_falsenonnegative():
|
| 527 |
+
x = Symbol('x', nonnegative=False)
|
| 528 |
+
assert x.is_positive is False
|
| 529 |
+
assert x.is_nonpositive is None
|
| 530 |
+
assert x.is_negative is None
|
| 531 |
+
assert x.is_nonnegative is False
|
| 532 |
+
assert x.is_zero is False
|
| 533 |
+
assert x.is_nonzero is None
|
| 534 |
+
|
| 535 |
+
|
| 536 |
+
@XFAIL
|
| 537 |
+
def test_neg_symbol_falsenonnegative():
|
| 538 |
+
x = -Symbol('x', nonnegative=False)
|
| 539 |
+
assert x.is_positive is None
|
| 540 |
+
assert x.is_nonpositive is False # this currently returns None
|
| 541 |
+
assert x.is_negative is False # this currently returns None
|
| 542 |
+
assert x.is_nonnegative is None
|
| 543 |
+
assert x.is_zero is False # this currently returns None
|
| 544 |
+
assert x.is_nonzero is True # this currently returns None
|
| 545 |
+
|
| 546 |
+
|
| 547 |
+
def test_symbol_falsenonnegative_real():
|
| 548 |
+
x = Symbol('x', nonnegative=False, real=True)
|
| 549 |
+
assert x.is_positive is False
|
| 550 |
+
assert x.is_nonpositive is True
|
| 551 |
+
assert x.is_negative is True
|
| 552 |
+
assert x.is_nonnegative is False
|
| 553 |
+
assert x.is_zero is False
|
| 554 |
+
assert x.is_nonzero is True
|
| 555 |
+
|
| 556 |
+
|
| 557 |
+
def test_neg_symbol_falsenonnegative_real():
|
| 558 |
+
x = -Symbol('x', nonnegative=False, real=True)
|
| 559 |
+
assert x.is_positive is True
|
| 560 |
+
assert x.is_nonpositive is False
|
| 561 |
+
assert x.is_negative is False
|
| 562 |
+
assert x.is_nonnegative is True
|
| 563 |
+
assert x.is_zero is False
|
| 564 |
+
assert x.is_nonzero is True
|
| 565 |
+
|
| 566 |
+
|
| 567 |
+
def test_prime():
|
| 568 |
+
assert S.NegativeOne.is_prime is False
|
| 569 |
+
assert S(-2).is_prime is False
|
| 570 |
+
assert S(-4).is_prime is False
|
| 571 |
+
assert S.Zero.is_prime is False
|
| 572 |
+
assert S.One.is_prime is False
|
| 573 |
+
assert S(2).is_prime is True
|
| 574 |
+
assert S(17).is_prime is True
|
| 575 |
+
assert S(4).is_prime is False
|
| 576 |
+
|
| 577 |
+
|
| 578 |
+
def test_composite():
|
| 579 |
+
assert S.NegativeOne.is_composite is False
|
| 580 |
+
assert S(-2).is_composite is False
|
| 581 |
+
assert S(-4).is_composite is False
|
| 582 |
+
assert S.Zero.is_composite is False
|
| 583 |
+
assert S(2).is_composite is False
|
| 584 |
+
assert S(17).is_composite is False
|
| 585 |
+
assert S(4).is_composite is True
|
| 586 |
+
x = Dummy(integer=True, positive=True, prime=False)
|
| 587 |
+
assert x.is_composite is None # x could be 1
|
| 588 |
+
assert (x + 1).is_composite is None
|
| 589 |
+
x = Dummy(positive=True, even=True, prime=False)
|
| 590 |
+
assert x.is_integer is True
|
| 591 |
+
assert x.is_composite is True
|
| 592 |
+
|
| 593 |
+
|
| 594 |
+
def test_prime_symbol():
|
| 595 |
+
x = Symbol('x', prime=True)
|
| 596 |
+
assert x.is_prime is True
|
| 597 |
+
assert x.is_integer is True
|
| 598 |
+
assert x.is_positive is True
|
| 599 |
+
assert x.is_negative is False
|
| 600 |
+
assert x.is_nonpositive is False
|
| 601 |
+
assert x.is_nonnegative is True
|
| 602 |
+
|
| 603 |
+
x = Symbol('x', prime=False)
|
| 604 |
+
assert x.is_prime is False
|
| 605 |
+
assert x.is_integer is None
|
| 606 |
+
assert x.is_positive is None
|
| 607 |
+
assert x.is_negative is None
|
| 608 |
+
assert x.is_nonpositive is None
|
| 609 |
+
assert x.is_nonnegative is None
|
| 610 |
+
|
| 611 |
+
|
| 612 |
+
def test_symbol_noncommutative():
|
| 613 |
+
x = Symbol('x', commutative=True)
|
| 614 |
+
assert x.is_complex is None
|
| 615 |
+
|
| 616 |
+
x = Symbol('x', commutative=False)
|
| 617 |
+
assert x.is_integer is False
|
| 618 |
+
assert x.is_rational is False
|
| 619 |
+
assert x.is_algebraic is False
|
| 620 |
+
assert x.is_irrational is False
|
| 621 |
+
assert x.is_real is False
|
| 622 |
+
assert x.is_complex is False
|
| 623 |
+
|
| 624 |
+
|
| 625 |
+
def test_other_symbol():
|
| 626 |
+
x = Symbol('x', integer=True)
|
| 627 |
+
assert x.is_integer is True
|
| 628 |
+
assert x.is_real is True
|
| 629 |
+
assert x.is_finite is True
|
| 630 |
+
|
| 631 |
+
x = Symbol('x', integer=True, nonnegative=True)
|
| 632 |
+
assert x.is_integer is True
|
| 633 |
+
assert x.is_nonnegative is True
|
| 634 |
+
assert x.is_negative is False
|
| 635 |
+
assert x.is_positive is None
|
| 636 |
+
assert x.is_finite is True
|
| 637 |
+
|
| 638 |
+
x = Symbol('x', integer=True, nonpositive=True)
|
| 639 |
+
assert x.is_integer is True
|
| 640 |
+
assert x.is_nonpositive is True
|
| 641 |
+
assert x.is_positive is False
|
| 642 |
+
assert x.is_negative is None
|
| 643 |
+
assert x.is_finite is True
|
| 644 |
+
|
| 645 |
+
x = Symbol('x', odd=True)
|
| 646 |
+
assert x.is_odd is True
|
| 647 |
+
assert x.is_even is False
|
| 648 |
+
assert x.is_integer is True
|
| 649 |
+
assert x.is_finite is True
|
| 650 |
+
|
| 651 |
+
x = Symbol('x', odd=False)
|
| 652 |
+
assert x.is_odd is False
|
| 653 |
+
assert x.is_even is None
|
| 654 |
+
assert x.is_integer is None
|
| 655 |
+
assert x.is_finite is None
|
| 656 |
+
|
| 657 |
+
x = Symbol('x', even=True)
|
| 658 |
+
assert x.is_even is True
|
| 659 |
+
assert x.is_odd is False
|
| 660 |
+
assert x.is_integer is True
|
| 661 |
+
assert x.is_finite is True
|
| 662 |
+
|
| 663 |
+
x = Symbol('x', even=False)
|
| 664 |
+
assert x.is_even is False
|
| 665 |
+
assert x.is_odd is None
|
| 666 |
+
assert x.is_integer is None
|
| 667 |
+
assert x.is_finite is None
|
| 668 |
+
|
| 669 |
+
x = Symbol('x', integer=True, nonnegative=True)
|
| 670 |
+
assert x.is_integer is True
|
| 671 |
+
assert x.is_nonnegative is True
|
| 672 |
+
assert x.is_finite is True
|
| 673 |
+
|
| 674 |
+
x = Symbol('x', integer=True, nonpositive=True)
|
| 675 |
+
assert x.is_integer is True
|
| 676 |
+
assert x.is_nonpositive is True
|
| 677 |
+
assert x.is_finite is True
|
| 678 |
+
|
| 679 |
+
x = Symbol('x', rational=True)
|
| 680 |
+
assert x.is_real is True
|
| 681 |
+
assert x.is_finite is True
|
| 682 |
+
|
| 683 |
+
x = Symbol('x', rational=False)
|
| 684 |
+
assert x.is_real is None
|
| 685 |
+
assert x.is_finite is None
|
| 686 |
+
|
| 687 |
+
x = Symbol('x', irrational=True)
|
| 688 |
+
assert x.is_real is True
|
| 689 |
+
assert x.is_finite is True
|
| 690 |
+
|
| 691 |
+
x = Symbol('x', irrational=False)
|
| 692 |
+
assert x.is_real is None
|
| 693 |
+
assert x.is_finite is None
|
| 694 |
+
|
| 695 |
+
with raises(AttributeError):
|
| 696 |
+
x.is_real = False
|
| 697 |
+
|
| 698 |
+
x = Symbol('x', algebraic=True)
|
| 699 |
+
assert x.is_transcendental is False
|
| 700 |
+
x = Symbol('x', transcendental=True)
|
| 701 |
+
assert x.is_algebraic is False
|
| 702 |
+
assert x.is_rational is False
|
| 703 |
+
assert x.is_integer is False
|
| 704 |
+
|
| 705 |
+
|
| 706 |
+
def test_evaluate_false():
|
| 707 |
+
# Previously this failed because the assumptions query would make new
|
| 708 |
+
# expressions and some of the evaluation logic would fail under
|
| 709 |
+
# evaluate(False).
|
| 710 |
+
from sympy.core.parameters import evaluate
|
| 711 |
+
from sympy.abc import x, h
|
| 712 |
+
f = 2**x**7
|
| 713 |
+
with evaluate(False):
|
| 714 |
+
fh = f.xreplace({x: x+h})
|
| 715 |
+
assert fh.exp.is_rational is None
|
| 716 |
+
|
| 717 |
+
|
| 718 |
+
def test_issue_3825():
|
| 719 |
+
"""catch: hash instability"""
|
| 720 |
+
x = Symbol("x")
|
| 721 |
+
y = Symbol("y")
|
| 722 |
+
a1 = x + y
|
| 723 |
+
a2 = y + x
|
| 724 |
+
a2.is_comparable
|
| 725 |
+
|
| 726 |
+
h1 = hash(a1)
|
| 727 |
+
h2 = hash(a2)
|
| 728 |
+
assert h1 == h2
|
| 729 |
+
|
| 730 |
+
|
| 731 |
+
def test_issue_4822():
|
| 732 |
+
z = (-1)**Rational(1, 3)*(1 - I*sqrt(3))
|
| 733 |
+
assert z.is_real in [True, None]
|
| 734 |
+
|
| 735 |
+
|
| 736 |
+
def test_hash_vs_typeinfo():
|
| 737 |
+
"""seemingly different typeinfo, but in fact equal"""
|
| 738 |
+
|
| 739 |
+
# the following two are semantically equal
|
| 740 |
+
x1 = Symbol('x', even=True)
|
| 741 |
+
x2 = Symbol('x', integer=True, odd=False)
|
| 742 |
+
|
| 743 |
+
assert hash(x1) == hash(x2)
|
| 744 |
+
assert x1 == x2
|
| 745 |
+
|
| 746 |
+
|
| 747 |
+
def test_hash_vs_typeinfo_2():
|
| 748 |
+
"""different typeinfo should mean !eq"""
|
| 749 |
+
# the following two are semantically different
|
| 750 |
+
x = Symbol('x')
|
| 751 |
+
x1 = Symbol('x', even=True)
|
| 752 |
+
|
| 753 |
+
assert x != x1
|
| 754 |
+
assert hash(x) != hash(x1) # This might fail with very low probability
|
| 755 |
+
|
| 756 |
+
|
| 757 |
+
def test_hash_vs_eq():
|
| 758 |
+
"""catch: different hash for equal objects"""
|
| 759 |
+
a = 1 + S.Pi # important: do not fold it into a Number instance
|
| 760 |
+
ha = hash(a) # it should be Add/Mul/... to trigger the bug
|
| 761 |
+
|
| 762 |
+
a.is_positive # this uses .evalf() and deduces it is positive
|
| 763 |
+
assert a.is_positive is True
|
| 764 |
+
|
| 765 |
+
# be sure that hash stayed the same
|
| 766 |
+
assert ha == hash(a)
|
| 767 |
+
|
| 768 |
+
# now b should be the same expression
|
| 769 |
+
b = a.expand(trig=True)
|
| 770 |
+
hb = hash(b)
|
| 771 |
+
|
| 772 |
+
assert a == b
|
| 773 |
+
assert ha == hb
|
| 774 |
+
|
| 775 |
+
|
| 776 |
+
def test_Add_is_pos_neg():
|
| 777 |
+
# these cover lines not covered by the rest of tests in core
|
| 778 |
+
n = Symbol('n', extended_negative=True, infinite=True)
|
| 779 |
+
nn = Symbol('n', extended_nonnegative=True, infinite=True)
|
| 780 |
+
np = Symbol('n', extended_nonpositive=True, infinite=True)
|
| 781 |
+
p = Symbol('p', extended_positive=True, infinite=True)
|
| 782 |
+
r = Dummy(extended_real=True, finite=False)
|
| 783 |
+
x = Symbol('x')
|
| 784 |
+
xf = Symbol('xf', finite=True)
|
| 785 |
+
assert (n + p).is_extended_positive is None
|
| 786 |
+
assert (n + x).is_extended_positive is None
|
| 787 |
+
assert (p + x).is_extended_positive is None
|
| 788 |
+
assert (n + p).is_extended_negative is None
|
| 789 |
+
assert (n + x).is_extended_negative is None
|
| 790 |
+
assert (p + x).is_extended_negative is None
|
| 791 |
+
|
| 792 |
+
assert (n + xf).is_extended_positive is False
|
| 793 |
+
assert (p + xf).is_extended_positive is True
|
| 794 |
+
assert (n + xf).is_extended_negative is True
|
| 795 |
+
assert (p + xf).is_extended_negative is False
|
| 796 |
+
|
| 797 |
+
assert (x - S.Infinity).is_extended_negative is None # issue 7798
|
| 798 |
+
# issue 8046, 16.2
|
| 799 |
+
assert (p + nn).is_extended_positive
|
| 800 |
+
assert (n + np).is_extended_negative
|
| 801 |
+
assert (p + r).is_extended_positive is None
|
| 802 |
+
|
| 803 |
+
|
| 804 |
+
def test_Add_is_imaginary():
|
| 805 |
+
nn = Dummy(nonnegative=True)
|
| 806 |
+
assert (I*nn + I).is_imaginary # issue 8046, 17
|
| 807 |
+
|
| 808 |
+
|
| 809 |
+
def test_Add_is_algebraic():
|
| 810 |
+
a = Symbol('a', algebraic=True)
|
| 811 |
+
b = Symbol('a', algebraic=True)
|
| 812 |
+
na = Symbol('na', algebraic=False)
|
| 813 |
+
nb = Symbol('nb', algebraic=False)
|
| 814 |
+
x = Symbol('x')
|
| 815 |
+
assert (a + b).is_algebraic
|
| 816 |
+
assert (na + nb).is_algebraic is None
|
| 817 |
+
assert (a + na).is_algebraic is False
|
| 818 |
+
assert (a + x).is_algebraic is None
|
| 819 |
+
assert (na + x).is_algebraic is None
|
| 820 |
+
|
| 821 |
+
|
| 822 |
+
def test_Mul_is_algebraic():
|
| 823 |
+
a = Symbol('a', algebraic=True)
|
| 824 |
+
b = Symbol('b', algebraic=True)
|
| 825 |
+
na = Symbol('na', algebraic=False)
|
| 826 |
+
an = Symbol('an', algebraic=True, nonzero=True)
|
| 827 |
+
nb = Symbol('nb', algebraic=False)
|
| 828 |
+
x = Symbol('x')
|
| 829 |
+
assert (a*b).is_algebraic is True
|
| 830 |
+
assert (na*nb).is_algebraic is None
|
| 831 |
+
assert (a*na).is_algebraic is None
|
| 832 |
+
assert (an*na).is_algebraic is False
|
| 833 |
+
assert (a*x).is_algebraic is None
|
| 834 |
+
assert (na*x).is_algebraic is None
|
| 835 |
+
|
| 836 |
+
|
| 837 |
+
def test_Pow_is_algebraic():
|
| 838 |
+
e = Symbol('e', algebraic=True)
|
| 839 |
+
|
| 840 |
+
assert Pow(1, e, evaluate=False).is_algebraic
|
| 841 |
+
assert Pow(0, e, evaluate=False).is_algebraic
|
| 842 |
+
|
| 843 |
+
a = Symbol('a', algebraic=True)
|
| 844 |
+
azf = Symbol('azf', algebraic=True, zero=False)
|
| 845 |
+
na = Symbol('na', algebraic=False)
|
| 846 |
+
ia = Symbol('ia', algebraic=True, irrational=True)
|
| 847 |
+
ib = Symbol('ib', algebraic=True, irrational=True)
|
| 848 |
+
r = Symbol('r', rational=True)
|
| 849 |
+
x = Symbol('x')
|
| 850 |
+
assert (a**2).is_algebraic is True
|
| 851 |
+
assert (a**r).is_algebraic is None
|
| 852 |
+
assert (azf**r).is_algebraic is True
|
| 853 |
+
assert (a**x).is_algebraic is None
|
| 854 |
+
assert (na**r).is_algebraic is None
|
| 855 |
+
assert (ia**r).is_algebraic is True
|
| 856 |
+
assert (ia**ib).is_algebraic is False
|
| 857 |
+
|
| 858 |
+
assert (a**e).is_algebraic is None
|
| 859 |
+
|
| 860 |
+
# Gelfond-Schneider constant:
|
| 861 |
+
assert Pow(2, sqrt(2), evaluate=False).is_algebraic is False
|
| 862 |
+
|
| 863 |
+
assert Pow(S.GoldenRatio, sqrt(3), evaluate=False).is_algebraic is False
|
| 864 |
+
|
| 865 |
+
# issue 8649
|
| 866 |
+
t = Symbol('t', real=True, transcendental=True)
|
| 867 |
+
n = Symbol('n', integer=True)
|
| 868 |
+
assert (t**n).is_algebraic is None
|
| 869 |
+
assert (t**n).is_integer is None
|
| 870 |
+
|
| 871 |
+
assert (pi**3).is_algebraic is False
|
| 872 |
+
r = Symbol('r', zero=True)
|
| 873 |
+
assert (pi**r).is_algebraic is True
|
| 874 |
+
|
| 875 |
+
|
| 876 |
+
def test_Mul_is_prime_composite():
|
| 877 |
+
x = Symbol('x', positive=True, integer=True)
|
| 878 |
+
y = Symbol('y', positive=True, integer=True)
|
| 879 |
+
assert (x*y).is_prime is None
|
| 880 |
+
assert ( (x+1)*(y+1) ).is_prime is False
|
| 881 |
+
assert ( (x+1)*(y+1) ).is_composite is True
|
| 882 |
+
|
| 883 |
+
x = Symbol('x', positive=True)
|
| 884 |
+
assert ( (x+1)*(y+1) ).is_prime is None
|
| 885 |
+
assert ( (x+1)*(y+1) ).is_composite is None
|
| 886 |
+
|
| 887 |
+
|
| 888 |
+
def test_Pow_is_pos_neg():
|
| 889 |
+
z = Symbol('z', real=True)
|
| 890 |
+
w = Symbol('w', nonpositive=True)
|
| 891 |
+
|
| 892 |
+
assert (S.NegativeOne**S(2)).is_positive is True
|
| 893 |
+
assert (S.One**z).is_positive is True
|
| 894 |
+
assert (S.NegativeOne**S(3)).is_positive is False
|
| 895 |
+
assert (S.Zero**S.Zero).is_positive is True # 0**0 is 1
|
| 896 |
+
assert (w**S(3)).is_positive is False
|
| 897 |
+
assert (w**S(2)).is_positive is None
|
| 898 |
+
assert (I**2).is_positive is False
|
| 899 |
+
assert (I**4).is_positive is True
|
| 900 |
+
|
| 901 |
+
# tests emerging from #16332 issue
|
| 902 |
+
p = Symbol('p', zero=True)
|
| 903 |
+
q = Symbol('q', zero=False, real=True)
|
| 904 |
+
j = Symbol('j', zero=False, even=True)
|
| 905 |
+
x = Symbol('x', zero=True)
|
| 906 |
+
y = Symbol('y', zero=True)
|
| 907 |
+
assert (p**q).is_positive is False
|
| 908 |
+
assert (p**q).is_negative is False
|
| 909 |
+
assert (p**j).is_positive is False
|
| 910 |
+
assert (x**y).is_positive is True # 0**0
|
| 911 |
+
assert (x**y).is_negative is False
|
| 912 |
+
|
| 913 |
+
|
| 914 |
+
def test_Pow_is_prime_composite():
|
| 915 |
+
x = Symbol('x', positive=True, integer=True)
|
| 916 |
+
y = Symbol('y', positive=True, integer=True)
|
| 917 |
+
assert (x**y).is_prime is None
|
| 918 |
+
assert ( x**(y+1) ).is_prime is False
|
| 919 |
+
assert ( x**(y+1) ).is_composite is None
|
| 920 |
+
assert ( (x+1)**(y+1) ).is_composite is True
|
| 921 |
+
assert ( (-x-1)**(2*y) ).is_composite is True
|
| 922 |
+
|
| 923 |
+
x = Symbol('x', positive=True)
|
| 924 |
+
assert (x**y).is_prime is None
|
| 925 |
+
|
| 926 |
+
|
| 927 |
+
def test_Mul_is_infinite():
|
| 928 |
+
x = Symbol('x')
|
| 929 |
+
f = Symbol('f', finite=True)
|
| 930 |
+
i = Symbol('i', infinite=True)
|
| 931 |
+
z = Dummy(zero=True)
|
| 932 |
+
nzf = Dummy(finite=True, zero=False)
|
| 933 |
+
from sympy.core.mul import Mul
|
| 934 |
+
assert (x*f).is_finite is None
|
| 935 |
+
assert (x*i).is_finite is None
|
| 936 |
+
assert (f*i).is_finite is None
|
| 937 |
+
assert (x*f*i).is_finite is None
|
| 938 |
+
assert (z*i).is_finite is None
|
| 939 |
+
assert (nzf*i).is_finite is False
|
| 940 |
+
assert (z*f).is_finite is True
|
| 941 |
+
assert Mul(0, f, evaluate=False).is_finite is True
|
| 942 |
+
assert Mul(0, i, evaluate=False).is_finite is None
|
| 943 |
+
|
| 944 |
+
assert (x*f).is_infinite is None
|
| 945 |
+
assert (x*i).is_infinite is None
|
| 946 |
+
assert (f*i).is_infinite is None
|
| 947 |
+
assert (x*f*i).is_infinite is None
|
| 948 |
+
assert (z*i).is_infinite is S.NaN.is_infinite
|
| 949 |
+
assert (nzf*i).is_infinite is True
|
| 950 |
+
assert (z*f).is_infinite is False
|
| 951 |
+
assert Mul(0, f, evaluate=False).is_infinite is False
|
| 952 |
+
assert Mul(0, i, evaluate=False).is_infinite is S.NaN.is_infinite
|
| 953 |
+
|
| 954 |
+
|
| 955 |
+
def test_Add_is_infinite():
|
| 956 |
+
x = Symbol('x')
|
| 957 |
+
f = Symbol('f', finite=True)
|
| 958 |
+
i = Symbol('i', infinite=True)
|
| 959 |
+
i2 = Symbol('i2', infinite=True)
|
| 960 |
+
z = Dummy(zero=True)
|
| 961 |
+
nzf = Dummy(finite=True, zero=False)
|
| 962 |
+
from sympy.core.add import Add
|
| 963 |
+
assert (x+f).is_finite is None
|
| 964 |
+
assert (x+i).is_finite is None
|
| 965 |
+
assert (f+i).is_finite is False
|
| 966 |
+
assert (x+f+i).is_finite is None
|
| 967 |
+
assert (z+i).is_finite is False
|
| 968 |
+
assert (nzf+i).is_finite is False
|
| 969 |
+
assert (z+f).is_finite is True
|
| 970 |
+
assert (i+i2).is_finite is None
|
| 971 |
+
assert Add(0, f, evaluate=False).is_finite is True
|
| 972 |
+
assert Add(0, i, evaluate=False).is_finite is False
|
| 973 |
+
|
| 974 |
+
assert (x+f).is_infinite is None
|
| 975 |
+
assert (x+i).is_infinite is None
|
| 976 |
+
assert (f+i).is_infinite is True
|
| 977 |
+
assert (x+f+i).is_infinite is None
|
| 978 |
+
assert (z+i).is_infinite is True
|
| 979 |
+
assert (nzf+i).is_infinite is True
|
| 980 |
+
assert (z+f).is_infinite is False
|
| 981 |
+
assert (i+i2).is_infinite is None
|
| 982 |
+
assert Add(0, f, evaluate=False).is_infinite is False
|
| 983 |
+
assert Add(0, i, evaluate=False).is_infinite is True
|
| 984 |
+
|
| 985 |
+
|
| 986 |
+
def test_special_is_rational():
|
| 987 |
+
i = Symbol('i', integer=True)
|
| 988 |
+
i2 = Symbol('i2', integer=True)
|
| 989 |
+
ni = Symbol('ni', integer=True, nonzero=True)
|
| 990 |
+
r = Symbol('r', rational=True)
|
| 991 |
+
rn = Symbol('r', rational=True, nonzero=True)
|
| 992 |
+
nr = Symbol('nr', irrational=True)
|
| 993 |
+
x = Symbol('x')
|
| 994 |
+
assert sqrt(3).is_rational is False
|
| 995 |
+
assert (3 + sqrt(3)).is_rational is False
|
| 996 |
+
assert (3*sqrt(3)).is_rational is False
|
| 997 |
+
assert exp(3).is_rational is False
|
| 998 |
+
assert exp(ni).is_rational is False
|
| 999 |
+
assert exp(rn).is_rational is False
|
| 1000 |
+
assert exp(x).is_rational is None
|
| 1001 |
+
assert exp(log(3), evaluate=False).is_rational is True
|
| 1002 |
+
assert log(exp(3), evaluate=False).is_rational is True
|
| 1003 |
+
assert log(3).is_rational is False
|
| 1004 |
+
assert log(ni + 1).is_rational is False
|
| 1005 |
+
assert log(rn + 1).is_rational is False
|
| 1006 |
+
assert log(x).is_rational is None
|
| 1007 |
+
assert (sqrt(3) + sqrt(5)).is_rational is None
|
| 1008 |
+
assert (sqrt(3) + S.Pi).is_rational is False
|
| 1009 |
+
assert (x**i).is_rational is None
|
| 1010 |
+
assert (i**i).is_rational is True
|
| 1011 |
+
assert (i**i2).is_rational is None
|
| 1012 |
+
assert (r**i).is_rational is None
|
| 1013 |
+
assert (r**r).is_rational is None
|
| 1014 |
+
assert (r**x).is_rational is None
|
| 1015 |
+
assert (nr**i).is_rational is None # issue 8598
|
| 1016 |
+
assert (nr**Symbol('z', zero=True)).is_rational
|
| 1017 |
+
assert sin(1).is_rational is False
|
| 1018 |
+
assert sin(ni).is_rational is False
|
| 1019 |
+
assert sin(rn).is_rational is False
|
| 1020 |
+
assert sin(x).is_rational is None
|
| 1021 |
+
assert asin(r).is_rational is False
|
| 1022 |
+
assert sin(asin(3), evaluate=False).is_rational is True
|
| 1023 |
+
|
| 1024 |
+
|
| 1025 |
+
@XFAIL
|
| 1026 |
+
def test_issue_6275():
|
| 1027 |
+
x = Symbol('x')
|
| 1028 |
+
# both zero or both Muls...but neither "change would be very appreciated.
|
| 1029 |
+
# This is similar to x/x => 1 even though if x = 0, it is really nan.
|
| 1030 |
+
assert isinstance(x*0, type(0*S.Infinity))
|
| 1031 |
+
if 0*S.Infinity is S.NaN:
|
| 1032 |
+
b = Symbol('b', finite=None)
|
| 1033 |
+
assert (b*0).is_zero is None
|
| 1034 |
+
|
| 1035 |
+
|
| 1036 |
+
def test_sanitize_assumptions():
|
| 1037 |
+
# issue 6666
|
| 1038 |
+
for cls in (Symbol, Dummy, Wild):
|
| 1039 |
+
x = cls('x', real=1, positive=0)
|
| 1040 |
+
assert x.is_real is True
|
| 1041 |
+
assert x.is_positive is False
|
| 1042 |
+
assert cls('', real=True, positive=None).is_positive is None
|
| 1043 |
+
raises(ValueError, lambda: cls('', commutative=None))
|
| 1044 |
+
raises(ValueError, lambda: Symbol._sanitize({"commutative": None}))
|
| 1045 |
+
|
| 1046 |
+
|
| 1047 |
+
def test_special_assumptions():
|
| 1048 |
+
e = -3 - sqrt(5) + (-sqrt(10)/2 - sqrt(2)/2)**2
|
| 1049 |
+
assert simplify(e < 0) is S.false
|
| 1050 |
+
assert simplify(e > 0) is S.false
|
| 1051 |
+
assert (e == 0) is False # it's not a literal 0
|
| 1052 |
+
assert e.equals(0) is True
|
| 1053 |
+
|
| 1054 |
+
|
| 1055 |
+
def test_inconsistent():
|
| 1056 |
+
# cf. issues 5795 and 5545
|
| 1057 |
+
raises(InconsistentAssumptions, lambda: Symbol('x', real=True,
|
| 1058 |
+
commutative=False))
|
| 1059 |
+
|
| 1060 |
+
|
| 1061 |
+
def test_issue_6631():
|
| 1062 |
+
assert ((-1)**(I)).is_real is True
|
| 1063 |
+
assert ((-1)**(I*2)).is_real is True
|
| 1064 |
+
assert ((-1)**(I/2)).is_real is True
|
| 1065 |
+
assert ((-1)**(I*S.Pi)).is_real is True
|
| 1066 |
+
assert (I**(I + 2)).is_real is True
|
| 1067 |
+
|
| 1068 |
+
|
| 1069 |
+
def test_issue_2730():
|
| 1070 |
+
assert (1/(1 + I)).is_real is False
|
| 1071 |
+
|
| 1072 |
+
|
| 1073 |
+
def test_issue_4149():
|
| 1074 |
+
assert (3 + I).is_complex
|
| 1075 |
+
assert (3 + I).is_imaginary is False
|
| 1076 |
+
assert (3*I + S.Pi*I).is_imaginary
|
| 1077 |
+
# as Zero.is_imaginary is False, see issue 7649
|
| 1078 |
+
y = Symbol('y', real=True)
|
| 1079 |
+
assert (3*I + S.Pi*I + y*I).is_imaginary is None
|
| 1080 |
+
p = Symbol('p', positive=True)
|
| 1081 |
+
assert (3*I + S.Pi*I + p*I).is_imaginary
|
| 1082 |
+
n = Symbol('n', negative=True)
|
| 1083 |
+
assert (-3*I - S.Pi*I + n*I).is_imaginary
|
| 1084 |
+
|
| 1085 |
+
i = Symbol('i', imaginary=True)
|
| 1086 |
+
assert ([(i**a).is_imaginary for a in range(4)] ==
|
| 1087 |
+
[False, True, False, True])
|
| 1088 |
+
|
| 1089 |
+
# tests from the PR #7887:
|
| 1090 |
+
e = S("-sqrt(3)*I/2 + 0.866025403784439*I")
|
| 1091 |
+
assert e.is_real is False
|
| 1092 |
+
assert e.is_imaginary
|
| 1093 |
+
|
| 1094 |
+
|
| 1095 |
+
def test_issue_2920():
|
| 1096 |
+
n = Symbol('n', negative=True)
|
| 1097 |
+
assert sqrt(n).is_imaginary
|
| 1098 |
+
|
| 1099 |
+
|
| 1100 |
+
def test_issue_7899():
|
| 1101 |
+
x = Symbol('x', real=True)
|
| 1102 |
+
assert (I*x).is_real is None
|
| 1103 |
+
assert ((x - I)*(x - 1)).is_zero is None
|
| 1104 |
+
assert ((x - I)*(x - 1)).is_real is None
|
| 1105 |
+
|
| 1106 |
+
|
| 1107 |
+
@XFAIL
|
| 1108 |
+
def test_issue_7993():
|
| 1109 |
+
x = Dummy(integer=True)
|
| 1110 |
+
y = Dummy(noninteger=True)
|
| 1111 |
+
assert (x - y).is_zero is False
|
| 1112 |
+
|
| 1113 |
+
|
| 1114 |
+
def test_issue_8075():
|
| 1115 |
+
raises(InconsistentAssumptions, lambda: Dummy(zero=True, finite=False))
|
| 1116 |
+
raises(InconsistentAssumptions, lambda: Dummy(zero=True, infinite=True))
|
| 1117 |
+
|
| 1118 |
+
|
| 1119 |
+
def test_issue_8642():
|
| 1120 |
+
x = Symbol('x', real=True, integer=False)
|
| 1121 |
+
assert (x*2).is_integer is None, (x*2).is_integer
|
| 1122 |
+
|
| 1123 |
+
|
| 1124 |
+
def test_issues_8632_8633_8638_8675_8992():
|
| 1125 |
+
p = Dummy(integer=True, positive=True)
|
| 1126 |
+
nn = Dummy(integer=True, nonnegative=True)
|
| 1127 |
+
assert (p - S.Half).is_positive
|
| 1128 |
+
assert (p - 1).is_nonnegative
|
| 1129 |
+
assert (nn + 1).is_positive
|
| 1130 |
+
assert (-p + 1).is_nonpositive
|
| 1131 |
+
assert (-nn - 1).is_negative
|
| 1132 |
+
prime = Dummy(prime=True)
|
| 1133 |
+
assert (prime - 2).is_nonnegative
|
| 1134 |
+
assert (prime - 3).is_nonnegative is None
|
| 1135 |
+
even = Dummy(positive=True, even=True)
|
| 1136 |
+
assert (even - 2).is_nonnegative
|
| 1137 |
+
|
| 1138 |
+
p = Dummy(positive=True)
|
| 1139 |
+
assert (p/(p + 1) - 1).is_negative
|
| 1140 |
+
assert ((p + 2)**3 - S.Half).is_positive
|
| 1141 |
+
n = Dummy(negative=True)
|
| 1142 |
+
assert (n - 3).is_nonpositive
|
| 1143 |
+
|
| 1144 |
+
|
| 1145 |
+
def test_issue_9115_9150():
|
| 1146 |
+
n = Dummy('n', integer=True, nonnegative=True)
|
| 1147 |
+
assert (factorial(n) >= 1) == True
|
| 1148 |
+
assert (factorial(n) < 1) == False
|
| 1149 |
+
|
| 1150 |
+
assert factorial(n + 1).is_even is None
|
| 1151 |
+
assert factorial(n + 2).is_even is True
|
| 1152 |
+
assert factorial(n + 2) >= 2
|
| 1153 |
+
|
| 1154 |
+
|
| 1155 |
+
def test_issue_9165():
|
| 1156 |
+
z = Symbol('z', zero=True)
|
| 1157 |
+
f = Symbol('f', finite=False)
|
| 1158 |
+
assert 0/z is S.NaN
|
| 1159 |
+
assert 0*(1/z) is S.NaN
|
| 1160 |
+
assert 0*f is S.NaN
|
| 1161 |
+
|
| 1162 |
+
|
| 1163 |
+
def test_issue_10024():
|
| 1164 |
+
x = Dummy('x')
|
| 1165 |
+
assert Mod(x, 2*pi).is_zero is None
|
| 1166 |
+
|
| 1167 |
+
|
| 1168 |
+
def test_issue_10302():
|
| 1169 |
+
x = Symbol('x')
|
| 1170 |
+
r = Symbol('r', real=True)
|
| 1171 |
+
u = -(3*2**pi)**(1/pi) + 2*3**(1/pi)
|
| 1172 |
+
i = u + u*I
|
| 1173 |
+
|
| 1174 |
+
assert i.is_real is None # w/o simplification this should fail
|
| 1175 |
+
assert (u + i).is_zero is None
|
| 1176 |
+
assert (1 + i).is_zero is False
|
| 1177 |
+
|
| 1178 |
+
a = Dummy('a', zero=True)
|
| 1179 |
+
assert (a + I).is_zero is False
|
| 1180 |
+
assert (a + r*I).is_zero is None
|
| 1181 |
+
assert (a + I).is_imaginary
|
| 1182 |
+
assert (a + x + I).is_imaginary is None
|
| 1183 |
+
assert (a + r*I + I).is_imaginary is None
|
| 1184 |
+
|
| 1185 |
+
|
| 1186 |
+
def test_complex_reciprocal_imaginary():
|
| 1187 |
+
assert (1 / (4 + 3*I)).is_imaginary is False
|
| 1188 |
+
|
| 1189 |
+
|
| 1190 |
+
def test_issue_16313():
|
| 1191 |
+
x = Symbol('x', extended_real=False)
|
| 1192 |
+
k = Symbol('k', real=True)
|
| 1193 |
+
l = Symbol('l', real=True, zero=False)
|
| 1194 |
+
assert (-x).is_real is False
|
| 1195 |
+
assert (k*x).is_real is None # k can be zero also
|
| 1196 |
+
assert (l*x).is_real is False
|
| 1197 |
+
assert (l*x*x).is_real is None # since x*x can be a real number
|
| 1198 |
+
assert (-x).is_positive is False
|
| 1199 |
+
|
| 1200 |
+
|
| 1201 |
+
def test_issue_16579():
|
| 1202 |
+
# extended_real -> finite | infinite
|
| 1203 |
+
x = Symbol('x', extended_real=True, infinite=False)
|
| 1204 |
+
y = Symbol('y', extended_real=True, finite=False)
|
| 1205 |
+
assert x.is_finite is True
|
| 1206 |
+
assert y.is_infinite is True
|
| 1207 |
+
|
| 1208 |
+
# With PR 16978, complex now implies finite
|
| 1209 |
+
c = Symbol('c', complex=True)
|
| 1210 |
+
assert c.is_finite is True
|
| 1211 |
+
raises(InconsistentAssumptions, lambda: Dummy(complex=True, finite=False))
|
| 1212 |
+
|
| 1213 |
+
# Now infinite == !finite
|
| 1214 |
+
nf = Symbol('nf', finite=False)
|
| 1215 |
+
assert nf.is_infinite is True
|
| 1216 |
+
|
| 1217 |
+
|
| 1218 |
+
def test_issue_17556():
|
| 1219 |
+
z = I*oo
|
| 1220 |
+
assert z.is_imaginary is False
|
| 1221 |
+
assert z.is_finite is False
|
| 1222 |
+
|
| 1223 |
+
|
| 1224 |
+
def test_issue_21651():
|
| 1225 |
+
k = Symbol('k', positive=True, integer=True)
|
| 1226 |
+
exp = 2*2**(-k)
|
| 1227 |
+
assert exp.is_integer is None
|
| 1228 |
+
|
| 1229 |
+
|
| 1230 |
+
def test_assumptions_copy():
|
| 1231 |
+
assert assumptions(Symbol('x'), {"commutative": True}
|
| 1232 |
+
) == {'commutative': True}
|
| 1233 |
+
assert assumptions(Symbol('x'), ['integer']) == {}
|
| 1234 |
+
assert assumptions(Symbol('x'), ['commutative']
|
| 1235 |
+
) == {'commutative': True}
|
| 1236 |
+
assert assumptions(Symbol('x')) == {'commutative': True}
|
| 1237 |
+
assert assumptions(1)['positive']
|
| 1238 |
+
assert assumptions(3 + I) == {
|
| 1239 |
+
'algebraic': True,
|
| 1240 |
+
'commutative': True,
|
| 1241 |
+
'complex': True,
|
| 1242 |
+
'composite': False,
|
| 1243 |
+
'even': False,
|
| 1244 |
+
'extended_negative': False,
|
| 1245 |
+
'extended_nonnegative': False,
|
| 1246 |
+
'extended_nonpositive': False,
|
| 1247 |
+
'extended_nonzero': False,
|
| 1248 |
+
'extended_positive': False,
|
| 1249 |
+
'extended_real': False,
|
| 1250 |
+
'finite': True,
|
| 1251 |
+
'imaginary': False,
|
| 1252 |
+
'infinite': False,
|
| 1253 |
+
'integer': False,
|
| 1254 |
+
'irrational': False,
|
| 1255 |
+
'negative': False,
|
| 1256 |
+
'noninteger': False,
|
| 1257 |
+
'nonnegative': False,
|
| 1258 |
+
'nonpositive': False,
|
| 1259 |
+
'nonzero': False,
|
| 1260 |
+
'odd': False,
|
| 1261 |
+
'positive': False,
|
| 1262 |
+
'prime': False,
|
| 1263 |
+
'rational': False,
|
| 1264 |
+
'real': False,
|
| 1265 |
+
'transcendental': False,
|
| 1266 |
+
'zero': False}
|
| 1267 |
+
|
| 1268 |
+
|
| 1269 |
+
def test_check_assumptions():
|
| 1270 |
+
assert check_assumptions(1, 0) is False
|
| 1271 |
+
x = Symbol('x', positive=True)
|
| 1272 |
+
assert check_assumptions(1, x) is True
|
| 1273 |
+
assert check_assumptions(1, 1) is True
|
| 1274 |
+
assert check_assumptions(-1, 1) is False
|
| 1275 |
+
i = Symbol('i', integer=True)
|
| 1276 |
+
# don't know if i is positive (or prime, etc...)
|
| 1277 |
+
assert check_assumptions(i, 1) is None
|
| 1278 |
+
assert check_assumptions(Dummy(integer=None), integer=True) is None
|
| 1279 |
+
assert check_assumptions(Dummy(integer=None), integer=False) is None
|
| 1280 |
+
assert check_assumptions(Dummy(integer=False), integer=True) is False
|
| 1281 |
+
assert check_assumptions(Dummy(integer=True), integer=False) is False
|
| 1282 |
+
# no T/F assumptions to check
|
| 1283 |
+
assert check_assumptions(Dummy(integer=False), integer=None) is True
|
| 1284 |
+
raises(ValueError, lambda: check_assumptions(2*x, x, positive=True))
|
| 1285 |
+
|
| 1286 |
+
|
| 1287 |
+
def test_failing_assumptions():
|
| 1288 |
+
x = Symbol('x', positive=True)
|
| 1289 |
+
y = Symbol('y')
|
| 1290 |
+
assert failing_assumptions(6*x + y, **x.assumptions0) == \
|
| 1291 |
+
{'real': None, 'imaginary': None, 'complex': None, 'hermitian': None,
|
| 1292 |
+
'positive': None, 'nonpositive': None, 'nonnegative': None, 'nonzero': None,
|
| 1293 |
+
'negative': None, 'zero': None, 'extended_real': None, 'finite': None,
|
| 1294 |
+
'infinite': None, 'extended_negative': None, 'extended_nonnegative': None,
|
| 1295 |
+
'extended_nonpositive': None, 'extended_nonzero': None,
|
| 1296 |
+
'extended_positive': None }
|
| 1297 |
+
|
| 1298 |
+
|
| 1299 |
+
def test_common_assumptions():
|
| 1300 |
+
assert common_assumptions([0, 1, 2]
|
| 1301 |
+
) == {'algebraic': True, 'irrational': False, 'hermitian':
|
| 1302 |
+
True, 'extended_real': True, 'real': True, 'extended_negative':
|
| 1303 |
+
False, 'extended_nonnegative': True, 'integer': True,
|
| 1304 |
+
'rational': True, 'imaginary': False, 'complex': True,
|
| 1305 |
+
'commutative': True,'noninteger': False, 'composite': False,
|
| 1306 |
+
'infinite': False, 'nonnegative': True, 'finite': True,
|
| 1307 |
+
'transcendental': False,'negative': False}
|
| 1308 |
+
assert common_assumptions([0, 1, 2], 'positive integer'.split()
|
| 1309 |
+
) == {'integer': True}
|
| 1310 |
+
assert common_assumptions([0, 1, 2], []) == {}
|
| 1311 |
+
assert common_assumptions([], ['integer']) == {}
|
| 1312 |
+
assert common_assumptions([0], ['integer']) == {'integer': True}
|
| 1313 |
+
|
| 1314 |
+
def test_pre_generated_assumption_rules_are_valid():
|
| 1315 |
+
# check the pre-generated assumptions match freshly generated assumptions
|
| 1316 |
+
# if this check fails, consider updating the assumptions
|
| 1317 |
+
# see sympy.core.assumptions._generate_assumption_rules
|
| 1318 |
+
pre_generated_assumptions =_load_pre_generated_assumption_rules()
|
| 1319 |
+
generated_assumptions =_generate_assumption_rules()
|
| 1320 |
+
assert pre_generated_assumptions._to_python() == generated_assumptions._to_python(), "pre-generated assumptions are invalid, see sympy.core.assumptions._generate_assumption_rules"
|
| 1321 |
+
|
| 1322 |
+
|
| 1323 |
+
def test_ask_shuffle():
|
| 1324 |
+
grp = PermutationGroup(Permutation(1, 0, 2), Permutation(2, 1, 3))
|
| 1325 |
+
|
| 1326 |
+
seed(123)
|
| 1327 |
+
first = grp.random()
|
| 1328 |
+
seed(123)
|
| 1329 |
+
simplify(I)
|
| 1330 |
+
second = grp.random()
|
| 1331 |
+
seed(123)
|
| 1332 |
+
simplify(-I)
|
| 1333 |
+
third = grp.random()
|
| 1334 |
+
|
| 1335 |
+
assert first == second == third
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_cache.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
from sympy.core.cache import cacheit, cached_property, lazy_function
|
| 3 |
+
from sympy.testing.pytest import raises
|
| 4 |
+
|
| 5 |
+
def test_cacheit_doc():
|
| 6 |
+
@cacheit
|
| 7 |
+
def testfn():
|
| 8 |
+
"test docstring"
|
| 9 |
+
pass
|
| 10 |
+
|
| 11 |
+
assert testfn.__doc__ == "test docstring"
|
| 12 |
+
assert testfn.__name__ == "testfn"
|
| 13 |
+
|
| 14 |
+
def test_cacheit_unhashable():
|
| 15 |
+
@cacheit
|
| 16 |
+
def testit(x):
|
| 17 |
+
return x
|
| 18 |
+
|
| 19 |
+
assert testit(1) == 1
|
| 20 |
+
assert testit(1) == 1
|
| 21 |
+
a = {}
|
| 22 |
+
assert testit(a) == {}
|
| 23 |
+
a[1] = 2
|
| 24 |
+
assert testit(a) == {1: 2}
|
| 25 |
+
|
| 26 |
+
def test_cachit_exception():
|
| 27 |
+
# Make sure the cache doesn't call functions multiple times when they
|
| 28 |
+
# raise TypeError
|
| 29 |
+
|
| 30 |
+
a = []
|
| 31 |
+
|
| 32 |
+
@cacheit
|
| 33 |
+
def testf(x):
|
| 34 |
+
a.append(0)
|
| 35 |
+
raise TypeError
|
| 36 |
+
|
| 37 |
+
raises(TypeError, lambda: testf(1))
|
| 38 |
+
assert len(a) == 1
|
| 39 |
+
|
| 40 |
+
a.clear()
|
| 41 |
+
# Unhashable type
|
| 42 |
+
raises(TypeError, lambda: testf([]))
|
| 43 |
+
assert len(a) == 1
|
| 44 |
+
|
| 45 |
+
@cacheit
|
| 46 |
+
def testf2(x):
|
| 47 |
+
a.append(0)
|
| 48 |
+
raise TypeError("Error")
|
| 49 |
+
|
| 50 |
+
a.clear()
|
| 51 |
+
raises(TypeError, lambda: testf2(1))
|
| 52 |
+
assert len(a) == 1
|
| 53 |
+
|
| 54 |
+
a.clear()
|
| 55 |
+
# Unhashable type
|
| 56 |
+
raises(TypeError, lambda: testf2([]))
|
| 57 |
+
assert len(a) == 1
|
| 58 |
+
|
| 59 |
+
def test_cached_property():
|
| 60 |
+
class A:
|
| 61 |
+
def __init__(self, value):
|
| 62 |
+
self.value = value
|
| 63 |
+
self.calls = 0
|
| 64 |
+
|
| 65 |
+
@cached_property
|
| 66 |
+
def prop(self):
|
| 67 |
+
self.calls = self.calls + 1
|
| 68 |
+
return self.value
|
| 69 |
+
|
| 70 |
+
a = A(2)
|
| 71 |
+
assert a.calls == 0
|
| 72 |
+
assert a.prop == 2
|
| 73 |
+
assert a.calls == 1
|
| 74 |
+
assert a.prop == 2
|
| 75 |
+
assert a.calls == 1
|
| 76 |
+
b = A(None)
|
| 77 |
+
assert b.prop == None
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def test_lazy_function():
|
| 81 |
+
module_name='xmlrpc.client'
|
| 82 |
+
function_name = 'gzip_decode'
|
| 83 |
+
lazy = lazy_function(module_name, function_name)
|
| 84 |
+
assert lazy(b'') == b''
|
| 85 |
+
assert module_name in sys.modules
|
| 86 |
+
assert function_name in str(lazy)
|
| 87 |
+
repr_lazy = repr(lazy)
|
| 88 |
+
assert 'LazyFunction' in repr_lazy
|
| 89 |
+
assert function_name in repr_lazy
|
| 90 |
+
|
| 91 |
+
lazy = lazy_function('sympy.core.cache', 'cheap')
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_compatibility.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.testing.pytest import warns_deprecated_sympy
|
| 2 |
+
|
| 3 |
+
def test_compatibility_submodule():
|
| 4 |
+
# Test the sympy.core.compatibility deprecation warning
|
| 5 |
+
with warns_deprecated_sympy():
|
| 6 |
+
import sympy.core.compatibility # noqa:F401
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_complex.py
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.function import expand_complex
|
| 2 |
+
from sympy.core.numbers import (I, Integer, Rational, pi)
|
| 3 |
+
from sympy.core.power import Pow
|
| 4 |
+
from sympy.core.singleton import S
|
| 5 |
+
from sympy.core.symbol import (Symbol, symbols)
|
| 6 |
+
from sympy.functions.elementary.complexes import (Abs, conjugate, im, re, sign)
|
| 7 |
+
from sympy.functions.elementary.exponential import exp
|
| 8 |
+
from sympy.functions.elementary.hyperbolic import (cosh, coth, sinh, tanh)
|
| 9 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 10 |
+
from sympy.functions.elementary.trigonometric import (cos, cot, sin, tan)
|
| 11 |
+
|
| 12 |
+
def test_complex():
|
| 13 |
+
a = Symbol("a", real=True)
|
| 14 |
+
b = Symbol("b", real=True)
|
| 15 |
+
e = (a + I*b)*(a - I*b)
|
| 16 |
+
assert e.expand() == a**2 + b**2
|
| 17 |
+
assert sqrt(I) == Pow(I, S.Half)
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def test_conjugate():
|
| 21 |
+
a = Symbol("a", real=True)
|
| 22 |
+
b = Symbol("b", real=True)
|
| 23 |
+
c = Symbol("c", imaginary=True)
|
| 24 |
+
d = Symbol("d", imaginary=True)
|
| 25 |
+
x = Symbol('x')
|
| 26 |
+
z = a + I*b + c + I*d
|
| 27 |
+
zc = a - I*b - c + I*d
|
| 28 |
+
assert conjugate(z) == zc
|
| 29 |
+
assert conjugate(exp(z)) == exp(zc)
|
| 30 |
+
assert conjugate(exp(I*x)) == exp(-I*conjugate(x))
|
| 31 |
+
assert conjugate(z**5) == zc**5
|
| 32 |
+
assert conjugate(abs(x)) == abs(x)
|
| 33 |
+
assert conjugate(sign(z)) == sign(zc)
|
| 34 |
+
assert conjugate(sin(z)) == sin(zc)
|
| 35 |
+
assert conjugate(cos(z)) == cos(zc)
|
| 36 |
+
assert conjugate(tan(z)) == tan(zc)
|
| 37 |
+
assert conjugate(cot(z)) == cot(zc)
|
| 38 |
+
assert conjugate(sinh(z)) == sinh(zc)
|
| 39 |
+
assert conjugate(cosh(z)) == cosh(zc)
|
| 40 |
+
assert conjugate(tanh(z)) == tanh(zc)
|
| 41 |
+
assert conjugate(coth(z)) == coth(zc)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def test_abs1():
|
| 45 |
+
a = Symbol("a", real=True)
|
| 46 |
+
b = Symbol("b", real=True)
|
| 47 |
+
assert abs(a) == Abs(a)
|
| 48 |
+
assert abs(-a) == abs(a)
|
| 49 |
+
assert abs(a + I*b) == sqrt(a**2 + b**2)
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def test_abs2():
|
| 53 |
+
a = Symbol("a", real=False)
|
| 54 |
+
b = Symbol("b", real=False)
|
| 55 |
+
assert abs(a) != a
|
| 56 |
+
assert abs(-a) != a
|
| 57 |
+
assert abs(a + I*b) != sqrt(a**2 + b**2)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def test_evalc():
|
| 61 |
+
x = Symbol("x", real=True)
|
| 62 |
+
y = Symbol("y", real=True)
|
| 63 |
+
z = Symbol("z")
|
| 64 |
+
assert ((x + I*y)**2).expand(complex=True) == x**2 + 2*I*x*y - y**2
|
| 65 |
+
assert expand_complex(z**(2*I)) == (re((re(z) + I*im(z))**(2*I)) +
|
| 66 |
+
I*im((re(z) + I*im(z))**(2*I)))
|
| 67 |
+
assert expand_complex(
|
| 68 |
+
z**(2*I), deep=False) == I*im(z**(2*I)) + re(z**(2*I))
|
| 69 |
+
|
| 70 |
+
assert exp(I*x) != cos(x) + I*sin(x)
|
| 71 |
+
assert exp(I*x).expand(complex=True) == cos(x) + I*sin(x)
|
| 72 |
+
assert exp(I*x + y).expand(complex=True) == exp(y)*cos(x) + I*sin(x)*exp(y)
|
| 73 |
+
|
| 74 |
+
assert sin(I*x).expand(complex=True) == I * sinh(x)
|
| 75 |
+
assert sin(x + I*y).expand(complex=True) == sin(x)*cosh(y) + \
|
| 76 |
+
I * sinh(y) * cos(x)
|
| 77 |
+
|
| 78 |
+
assert cos(I*x).expand(complex=True) == cosh(x)
|
| 79 |
+
assert cos(x + I*y).expand(complex=True) == cos(x)*cosh(y) - \
|
| 80 |
+
I * sinh(y) * sin(x)
|
| 81 |
+
|
| 82 |
+
assert tan(I*x).expand(complex=True) == tanh(x) * I
|
| 83 |
+
assert tan(x + I*y).expand(complex=True) == (
|
| 84 |
+
sin(2*x)/(cos(2*x) + cosh(2*y)) +
|
| 85 |
+
I*sinh(2*y)/(cos(2*x) + cosh(2*y)))
|
| 86 |
+
|
| 87 |
+
assert sinh(I*x).expand(complex=True) == I * sin(x)
|
| 88 |
+
assert sinh(x + I*y).expand(complex=True) == sinh(x)*cos(y) + \
|
| 89 |
+
I * sin(y) * cosh(x)
|
| 90 |
+
|
| 91 |
+
assert cosh(I*x).expand(complex=True) == cos(x)
|
| 92 |
+
assert cosh(x + I*y).expand(complex=True) == cosh(x)*cos(y) + \
|
| 93 |
+
I * sin(y) * sinh(x)
|
| 94 |
+
|
| 95 |
+
assert tanh(I*x).expand(complex=True) == tan(x) * I
|
| 96 |
+
assert tanh(x + I*y).expand(complex=True) == (
|
| 97 |
+
(sinh(x)*cosh(x) + I*cos(y)*sin(y)) /
|
| 98 |
+
(sinh(x)**2 + cos(y)**2)).expand()
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def test_pythoncomplex():
|
| 102 |
+
x = Symbol("x")
|
| 103 |
+
assert 4j*x != 4*x*I
|
| 104 |
+
assert 4j*x == 4.0*x*I
|
| 105 |
+
assert 4.1j*x != 4*x*I
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
def test_rootcomplex():
|
| 109 |
+
R = Rational
|
| 110 |
+
assert ((+1 + I)**R(1, 2)).expand(
|
| 111 |
+
complex=True) == 2**R(1, 4)*cos( pi/8) + 2**R(1, 4)*sin( pi/8)*I
|
| 112 |
+
assert ((-1 - I)**R(1, 2)).expand(
|
| 113 |
+
complex=True) == 2**R(1, 4)*cos(3*pi/8) - 2**R(1, 4)*sin(3*pi/8)*I
|
| 114 |
+
assert (sqrt(-10)*I).as_real_imag() == (-sqrt(10), 0)
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def test_expand_inverse():
|
| 118 |
+
assert (1/(1 + I)).expand(complex=True) == (1 - I)/2
|
| 119 |
+
assert ((1 + 2*I)**(-2)).expand(complex=True) == (-3 - 4*I)/25
|
| 120 |
+
assert ((1 + I)**(-8)).expand(complex=True) == Rational(1, 16)
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def test_expand_complex():
|
| 124 |
+
assert ((2 + 3*I)**10).expand(complex=True) == -341525 - 145668*I
|
| 125 |
+
# the following two tests are to ensure the SymPy uses an efficient
|
| 126 |
+
# algorithm for calculating powers of complex numbers. They should execute
|
| 127 |
+
# in something like 0.01s.
|
| 128 |
+
assert ((2 + 3*I)**1000).expand(complex=True) == \
|
| 129 |
+
-81079464736246615951519029367296227340216902563389546989376269312984127074385455204551402940331021387412262494620336565547972162814110386834027871072723273110439771695255662375718498785908345629702081336606863762777939617745464755635193139022811989314881997210583159045854968310911252660312523907616129080027594310008539817935736331124833163907518549408018652090650537035647520296539436440394920287688149200763245475036722326561143851304795139005599209239350981457301460233967137708519975586996623552182807311159141501424576682074392689622074945519232029999 + \
|
| 130 |
+
46938745946789557590804551905243206242164799136976022474337918748798900569942573265747576032611189047943842446167719177749107138603040963603119861476016947257034472364028585381714774667326478071264878108114128915685688115488744955550920239128462489496563930809677159214598114273887061533057125164518549173898349061972857446844052995037423459472376202251620778517659247970283904820245958198842631651569984310559418135975795868314764489884749573052997832686979294085577689571149679540256349988338406458116270429842222666345146926395233040564229555893248370000*I
|
| 131 |
+
assert ((2 + 3*I/4)**1000).expand(complex=True) == \
|
| 132 |
+
Integer(1)*37079892761199059751745775382463070250205990218394308874593455293485167797989691280095867197640410033222367257278387021789651672598831503296531725827158233077451476545928116965316544607115843772405184272449644892857783761260737279675075819921259597776770965829089907990486964515784097181964312256560561065607846661496055417619388874421218472707497847700629822858068783288579581649321248495739224020822198695759609598745114438265083593711851665996586461937988748911532242908776883696631067311443171682974330675406616373422505939887984366289623091300746049101284856530270685577940283077888955692921951247230006346681086274961362500646889925803654263491848309446197554307105991537357310209426736453173441104334496173618419659521888945605315751089087820455852582920963561495787655250624781448951403353654348109893478206364632640344111022531861683064175862889459084900614967785405977231549003280842218501570429860550379522498497412180001/114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681344168908984458505602379484807914058900934776500429002716706625830522008132236281291761267883317206598995396418127021779858404042159853183251540889433902091920554957783589672039160081957216630582755380425583726015528348786419432054508915275783882625175435528800822842770817965453762184851149029376 + \
|
| 133 |
+
I*421638390580169706973991429333213477486930178424989246669892530737775352519112934278994501272111385966211392610029433824534634841747911783746811994443436271013377059560245191441549885048056920190833693041257216263519792201852046825443439142932464031501882145407459174948712992271510309541474392303461939389368955986650538525895866713074543004916049550090364398070215427272240155060576252568700906004691224321432509053286859100920489253598392100207663785243368195857086816912514025693453058403158416856847185079684216151337200057494966741268925263085619240941610301610538225414050394612058339070756009433535451561664522479191267503989904464718368605684297071150902631208673621618217106272361061676184840810762902463998065947687814692402219182668782278472952758690939877465065070481351343206840649517150634973307937551168752642148704904383991876969408056379195860410677814566225456558230131911142229028179902418223009651437985670625/1793954211366022694113801876840128100034871409513586250746316776290259783425578615401030447369541046747571819748417910583511123376348523955353017744010395602173906080395504375010762174191250701116076984219741972574712741619474818186676828531882286780795390571221287481389759837587864244524002565968286448146002639202882164150037179450123657170327105882819203167448541028601906377066191895183769810676831353109303069033234715310287563158747705988305326397404720186258671215368588625611876280581509852855552819149745718992630449787803625851701801184123166018366180137512856918294030710215034138299203584
|
| 134 |
+
assert ((2 + 3*I)**-1000).expand(complex=True) == \
|
| 135 |
+
Integer(1)*-81079464736246615951519029367296227340216902563389546989376269312984127074385455204551402940331021387412262494620336565547972162814110386834027871072723273110439771695255662375718498785908345629702081336606863762777939617745464755635193139022811989314881997210583159045854968310911252660312523907616129080027594310008539817935736331124833163907518549408018652090650537035647520296539436440394920287688149200763245475036722326561143851304795139005599209239350981457301460233967137708519975586996623552182807311159141501424576682074392689622074945519232029999/8777125472973511649630750050295188683351430110097915876250894978429797369155961290321829625004920141758416719066805645579710744290541337680113772670040386863849283653078324415471816788604945889094925784900885812724984087843737442111926413818245854362613018058774368703971604921858023116665586358870612944209398056562604561248859926344335598822815885851096698226775053153403320782439987679978321289537645645163767251396759519805603090332694449553371530571613352311006350058217982509738362083094920649452123351717366337410243853659113315547584871655479914439219520157174729130746351059075207407866012574386726064196992865627149566238044625779078186624347183905913357718850537058578084932880569701242598663149911276357125355850792073635533676541250531086757377369962506979378337216411188347761901006460813413505861461267545723590468627854202034450569581626648934062198718362303420281555886394558137408159453103395918783625713213314350531051312551733021627153081075080140680608080529736975658786227362251632725009435866547613598753584705455955419696609282059191031962604169242974038517575645939316377801594539335940001 - Integer(1)*46938745946789557590804551905243206242164799136976022474337918748798900569942573265747576032611189047943842446167719177749107138603040963603119861476016947257034472364028585381714774667326478071264878108114128915685688115488744955550920239128462489496563930809677159214598114273887061533057125164518549173898349061972857446844052995037423459472376202251620778517659247970283904820245958198842631651569984310559418135975795868314764489884749573052997832686979294085577689571149679540256349988338406458116270429842222666345146926395233040564229555893248370000*I/8777125472973511649630750050295188683351430110097915876250894978429797369155961290321829625004920141758416719066805645579710744290541337680113772670040386863849283653078324415471816788604945889094925784900885812724984087843737442111926413818245854362613018058774368703971604921858023116665586358870612944209398056562604561248859926344335598822815885851096698226775053153403320782439987679978321289537645645163767251396759519805603090332694449553371530571613352311006350058217982509738362083094920649452123351717366337410243853659113315547584871655479914439219520157174729130746351059075207407866012574386726064196992865627149566238044625779078186624347183905913357718850537058578084932880569701242598663149911276357125355850792073635533676541250531086757377369962506979378337216411188347761901006460813413505861461267545723590468627854202034450569581626648934062198718362303420281555886394558137408159453103395918783625713213314350531051312551733021627153081075080140680608080529736975658786227362251632725009435866547613598753584705455955419696609282059191031962604169242974038517575645939316377801594539335940001
|
| 136 |
+
assert ((2 + 3*I/4)**-1000).expand(complex=True) == \
|
| 137 |
+
Integer(1)*4257256305661027385394552848555894604806501409793288342610746813288539790051927148781268212212078237301273165351052934681382567968787279534591114913777456610214738290619922068269909423637926549603264174216950025398244509039145410016404821694746262142525173737175066432954496592560621330313807235750500564940782099283410261748370262433487444897446779072067625787246390824312580440138770014838135245148574339248259670887549732495841810961088930810608893772914812838358159009303794863047635845688453859317690488124382253918725010358589723156019888846606295866740117645571396817375322724096486161308083462637370825829567578309445855481578518239186117686659177284332344643124760453112513611749309168470605289172320376911472635805822082051716625171429727162039621902266619821870482519063133136820085579315127038372190224739238686708451840610064871885616258831386810233957438253532027049148030157164346719204500373766157143311767338973363806106967439378604898250533766359989107510507493549529158818602327525235240510049484816090584478644771183158342479140194633579061295740839490629457435283873180259847394582069479062820225159699506175855369539201399183443253793905149785994830358114153241481884290274629611529758663543080724574566578220908907477622643689220814376054314972190402285121776593824615083669045183404206291739005554569305329760211752815718335731118664756831942466773261465213581616104242113894521054475516019456867271362053692785300826523328020796670205463390909136593859765912483565093461468865534470710132881677639651348709376/2103100954337624833663208713697737151593634525061637972297915388685604042449504336765884978184588688426595940401280828953096857809292320006227881797146858511436638446932833617514351442216409828605662238790280753075176269765767010004889778647709740770757817960711900340755635772183674511158570690702969774966791073165467918123298694584729211212414462628433370481195120564586361368504153395406845170075275051749019600057116719726628746724489572189061061036426955163696859127711110719502594479795200686212257570291758725259007379710596548777812659422174199194837355646482046783616494013289495563083118517507178847555801163089723056310287760875135196081975602765511153122381201303871673391366630940702817360340900568748719988954847590748960761446218262344767250783946365392689256634180417145926390656439421745644011831124277463643383712803287985472471755648426749842410972650924240795946699346613614779460399530274263580007672855851663196114585312432954432654691485867618908420370875753749297487803461900447407917655296784879220450937110470920633595689721819488638484547259978337741496090602390463594556401615298457456112485536498177883358587125449801777718900375736758266215245325999241624148841915093787519330809347240990363802360596034171167818310322276373120180985148650099673289383722502488957717848531612020897298448601714154586319660314294591620415272119454982220034319689607295960162971300417552364254983071768070124456169427638371140064235083443242844616326538396503937972586505546495649094344512270582463639152160238137952390380581401171977159154009407415523525096743009110916334144716516647041176989758534635251844947906038080852185583742296318878233394998111078843229681030277039104786225656992262073797524057992347971177720807155842376332851559276430280477639539393920006008737472164850104411971830120295750221200029811143140323763349636629725073624360001 - Integer(1)*3098214262599218784594285246258841485430681674561917573155883806818465520660668045042109232930382494608383663464454841313154390741655282039877410154577448327874989496074260116195788919037407420625081798124301494353693248757853222257918294662198297114746822817460991242508743651430439120439020484502408313310689912381846149597061657483084652685283853595100434135149479564507015504022249330340259111426799121454516345905101620532787348293877485702600390665276070250119465888154331218827342488849948540687659846652377277250614246402784754153678374932540789808703029043827352976139228402417432199779415751301480406673762521987999573209628597459357964214510139892316208670927074795773830798600837815329291912002136924506221066071242281626618211060464126372574400100990746934953437169840312584285942093951405864225230033279614235191326102697164613004299868695519642598882914862568516635347204441042798206770888274175592401790040170576311989738272102077819127459014286741435419468254146418098278519775722104890854275995510700298782146199325790002255362719776098816136732897323406228294203133323296591166026338391813696715894870956511298793595675308998014158717167429941371979636895553724830981754579086664608880698350866487717403917070872269853194118364230971216854931998642990452908852258008095741042117326241406479532880476938937997238098399302185675832474590293188864060116934035867037219176916416481757918864533515526389079998129329045569609325290897577497835388451456680707076072624629697883854217331728051953671643278797380171857920000*I/2103100954337624833663208713697737151593634525061637972297915388685604042449504336765884978184588688426595940401280828953096857809292320006227881797146858511436638446932833617514351442216409828605662238790280753075176269765767010004889778647709740770757817960711900340755635772183674511158570690702969774966791073165467918123298694584729211212414462628433370481195120564586361368504153395406845170075275051749019600057116719726628746724489572189061061036426955163696859127711110719502594479795200686212257570291758725259007379710596548777812659422174199194837355646482046783616494013289495563083118517507178847555801163089723056310287760875135196081975602765511153122381201303871673391366630940702817360340900568748719988954847590748960761446218262344767250783946365392689256634180417145926390656439421745644011831124277463643383712803287985472471755648426749842410972650924240795946699346613614779460399530274263580007672855851663196114585312432954432654691485867618908420370875753749297487803461900447407917655296784879220450937110470920633595689721819488638484547259978337741496090602390463594556401615298457456112485536498177883358587125449801777718900375736758266215245325999241624148841915093787519330809347240990363802360596034171167818310322276373120180985148650099673289383722502488957717848531612020897298448601714154586319660314294591620415272119454982220034319689607295960162971300417552364254983071768070124456169427638371140064235083443242844616326538396503937972586505546495649094344512270582463639152160238137952390380581401171977159154009407415523525096743009110916334144716516647041176989758534635251844947906038080852185583742296318878233394998111078843229681030277039104786225656992262073797524057992347971177720807155842376332851559276430280477639539393920006008737472164850104411971830120295750221200029811143140323763349636629725073624360001
|
| 138 |
+
|
| 139 |
+
a = Symbol('a', real=True)
|
| 140 |
+
b = Symbol('b', real=True)
|
| 141 |
+
assert exp(a*(2 + I*b)).expand(complex=True) == \
|
| 142 |
+
I*exp(2*a)*sin(a*b) + exp(2*a)*cos(a*b)
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
def test_expand():
|
| 146 |
+
f = (16 - 2*sqrt(29))**2
|
| 147 |
+
assert f.expand() == 372 - 64*sqrt(29)
|
| 148 |
+
f = (Integer(1)/2 + I/2)**10
|
| 149 |
+
assert f.expand() == I/32
|
| 150 |
+
f = (Integer(1)/2 + I)**10
|
| 151 |
+
assert f.expand() == Integer(237)/1024 - 779*I/256
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def test_re_im1652():
|
| 155 |
+
x = Symbol('x')
|
| 156 |
+
assert re(x) == re(conjugate(x))
|
| 157 |
+
assert im(x) == - im(conjugate(x))
|
| 158 |
+
assert im(x)*re(conjugate(x)) + im(conjugate(x)) * re(x) == 0
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
def test_issue_5084():
|
| 162 |
+
x = Symbol('x')
|
| 163 |
+
assert ((x + x*I)/(1 + I)).as_real_imag() == (re((x + I*x)/(1 + I)
|
| 164 |
+
), im((x + I*x)/(1 + I)))
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
def test_issue_5236():
|
| 168 |
+
assert (cos(1 + I)**3).as_real_imag() == (-3*sin(1)**2*sinh(1)**2*cos(1)*cosh(1) +
|
| 169 |
+
cos(1)**3*cosh(1)**3, -3*cos(1)**2*cosh(1)**2*sin(1)*sinh(1) + sin(1)**3*sinh(1)**3)
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def test_real_imag():
|
| 173 |
+
x, y, z = symbols('x, y, z')
|
| 174 |
+
X, Y, Z = symbols('X, Y, Z', commutative=False)
|
| 175 |
+
a = Symbol('a', real=True)
|
| 176 |
+
assert (2*a*x).as_real_imag() == (2*a*re(x), 2*a*im(x))
|
| 177 |
+
|
| 178 |
+
# issue 5395:
|
| 179 |
+
assert (x*x.conjugate()).as_real_imag() == (Abs(x)**2, 0)
|
| 180 |
+
assert im(x*x.conjugate()) == 0
|
| 181 |
+
assert im(x*y.conjugate()*z*y) == im(x*z)*Abs(y)**2
|
| 182 |
+
assert im(x*y.conjugate()*x*y) == im(x**2)*Abs(y)**2
|
| 183 |
+
assert im(Z*y.conjugate()*X*y) == im(Z*X)*Abs(y)**2
|
| 184 |
+
assert im(X*X.conjugate()) == im(X*X.conjugate(), evaluate=False)
|
| 185 |
+
assert (sin(x)*sin(x).conjugate()).as_real_imag() == \
|
| 186 |
+
(Abs(sin(x))**2, 0)
|
| 187 |
+
|
| 188 |
+
# issue 6573:
|
| 189 |
+
assert (x**2).as_real_imag() == (re(x)**2 - im(x)**2, 2*re(x)*im(x))
|
| 190 |
+
|
| 191 |
+
# issue 6428:
|
| 192 |
+
r = Symbol('r', real=True)
|
| 193 |
+
i = Symbol('i', imaginary=True)
|
| 194 |
+
assert (i*r*x).as_real_imag() == (I*i*r*im(x), -I*i*r*re(x))
|
| 195 |
+
assert (i*r*x*(y + 2)).as_real_imag() == (
|
| 196 |
+
I*i*r*(re(y) + 2)*im(x) + I*i*r*re(x)*im(y),
|
| 197 |
+
-I*i*r*(re(y) + 2)*re(x) + I*i*r*im(x)*im(y))
|
| 198 |
+
|
| 199 |
+
# issue 7106:
|
| 200 |
+
assert ((1 + I)/(1 - I)).as_real_imag() == (0, 1)
|
| 201 |
+
assert ((1 + 2*I)*(1 + 3*I)).as_real_imag() == (-5, 5)
|
| 202 |
+
|
| 203 |
+
|
| 204 |
+
def test_pow_issue_1724():
|
| 205 |
+
e = ((S.NegativeOne)**(S.One/3))
|
| 206 |
+
assert e.conjugate().n() == e.n().conjugate()
|
| 207 |
+
e = S('-2/3 - (-29/54 + sqrt(93)/18)**(1/3) - 1/(9*(-29/54 + sqrt(93)/18)**(1/3))')
|
| 208 |
+
assert e.conjugate().n() == e.n().conjugate()
|
| 209 |
+
e = 2**I
|
| 210 |
+
assert e.conjugate().n() == e.n().conjugate()
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
def test_issue_5429():
|
| 214 |
+
assert sqrt(I).conjugate() != sqrt(I)
|
| 215 |
+
|
| 216 |
+
def test_issue_4124():
|
| 217 |
+
from sympy.core.numbers import oo
|
| 218 |
+
assert expand_complex(I*oo) == oo*I
|
| 219 |
+
|
| 220 |
+
def test_issue_11518():
|
| 221 |
+
x = Symbol("x", real=True)
|
| 222 |
+
y = Symbol("y", real=True)
|
| 223 |
+
r = sqrt(x**2 + y**2)
|
| 224 |
+
assert conjugate(r) == r
|
| 225 |
+
s = abs(x + I * y)
|
| 226 |
+
assert conjugate(s) == r
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_constructor_postprocessor.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.basic import Basic
|
| 2 |
+
from sympy.core.mul import Mul
|
| 3 |
+
from sympy.core.symbol import (Symbol, symbols)
|
| 4 |
+
|
| 5 |
+
from sympy.testing.pytest import XFAIL
|
| 6 |
+
|
| 7 |
+
class SymbolInMulOnce(Symbol):
|
| 8 |
+
# Test class for a symbol that can only appear once in a `Mul` expression.
|
| 9 |
+
pass
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
Basic._constructor_postprocessor_mapping[SymbolInMulOnce] = {
|
| 13 |
+
"Mul": [lambda x: x],
|
| 14 |
+
"Pow": [lambda x: x.base if isinstance(x.base, SymbolInMulOnce) else x],
|
| 15 |
+
"Add": [lambda x: x],
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def _postprocess_SymbolRemovesOtherSymbols(expr):
|
| 20 |
+
args = tuple(i for i in expr.args if not isinstance(i, Symbol) or isinstance(i, SymbolRemovesOtherSymbols))
|
| 21 |
+
if args == expr.args:
|
| 22 |
+
return expr
|
| 23 |
+
return Mul.fromiter(args)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
class SymbolRemovesOtherSymbols(Symbol):
|
| 27 |
+
# Test class for a symbol that removes other symbols in `Mul`.
|
| 28 |
+
pass
|
| 29 |
+
|
| 30 |
+
Basic._constructor_postprocessor_mapping[SymbolRemovesOtherSymbols] = {
|
| 31 |
+
"Mul": [_postprocess_SymbolRemovesOtherSymbols],
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
class SubclassSymbolInMulOnce(SymbolInMulOnce):
|
| 35 |
+
pass
|
| 36 |
+
|
| 37 |
+
class SubclassSymbolRemovesOtherSymbols(SymbolRemovesOtherSymbols):
|
| 38 |
+
pass
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def test_constructor_postprocessors1():
|
| 42 |
+
x = SymbolInMulOnce("x")
|
| 43 |
+
y = SymbolInMulOnce("y")
|
| 44 |
+
assert isinstance(3*x, Mul)
|
| 45 |
+
assert (3*x).args == (3, x)
|
| 46 |
+
assert x*x == x
|
| 47 |
+
assert 3*x*x == 3*x
|
| 48 |
+
assert 2*x*x + x == 3*x
|
| 49 |
+
assert x**3*y*y == x*y
|
| 50 |
+
assert x**5 + y*x**3 == x + x*y
|
| 51 |
+
|
| 52 |
+
w = SymbolRemovesOtherSymbols("w")
|
| 53 |
+
assert x*w == w
|
| 54 |
+
assert (3*w).args == (3, w)
|
| 55 |
+
assert set((w + x).args) == {x, w}
|
| 56 |
+
|
| 57 |
+
def test_constructor_postprocessors2():
|
| 58 |
+
x = SubclassSymbolInMulOnce("x")
|
| 59 |
+
y = SubclassSymbolInMulOnce("y")
|
| 60 |
+
assert isinstance(3*x, Mul)
|
| 61 |
+
assert (3*x).args == (3, x)
|
| 62 |
+
assert x*x == x
|
| 63 |
+
assert 3*x*x == 3*x
|
| 64 |
+
assert 2*x*x + x == 3*x
|
| 65 |
+
assert x**3*y*y == x*y
|
| 66 |
+
assert x**5 + y*x**3 == x + x*y
|
| 67 |
+
|
| 68 |
+
w = SubclassSymbolRemovesOtherSymbols("w")
|
| 69 |
+
assert x*w == w
|
| 70 |
+
assert (3*w).args == (3, w)
|
| 71 |
+
assert set((w + x).args) == {x, w}
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
@XFAIL
|
| 75 |
+
def test_subexpression_postprocessors():
|
| 76 |
+
# The postprocessors used to work with subexpressions, but the
|
| 77 |
+
# functionality was removed. See #15948.
|
| 78 |
+
a = symbols("a")
|
| 79 |
+
x = SymbolInMulOnce("x")
|
| 80 |
+
w = SymbolRemovesOtherSymbols("w")
|
| 81 |
+
assert 3*a*w**2 == 3*w**2
|
| 82 |
+
assert 3*a*x**3*w**2 == 3*w**2
|
| 83 |
+
|
| 84 |
+
x = SubclassSymbolInMulOnce("x")
|
| 85 |
+
w = SubclassSymbolRemovesOtherSymbols("w")
|
| 86 |
+
assert 3*a*w**2 == 3*w**2
|
| 87 |
+
assert 3*a*x**3*w**2 == 3*w**2
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_containers.py
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from collections import defaultdict
|
| 2 |
+
|
| 3 |
+
from sympy.core.basic import Basic
|
| 4 |
+
from sympy.core.containers import (Dict, Tuple)
|
| 5 |
+
from sympy.core.numbers import Integer
|
| 6 |
+
from sympy.core.kind import NumberKind
|
| 7 |
+
from sympy.matrices.kind import MatrixKind
|
| 8 |
+
from sympy.core.singleton import S
|
| 9 |
+
from sympy.core.symbol import symbols
|
| 10 |
+
from sympy.core.sympify import sympify
|
| 11 |
+
from sympy.matrices.dense import Matrix
|
| 12 |
+
from sympy.sets.sets import FiniteSet
|
| 13 |
+
from sympy.core.containers import tuple_wrapper, TupleKind
|
| 14 |
+
from sympy.core.expr import unchanged
|
| 15 |
+
from sympy.core.function import Function, Lambda
|
| 16 |
+
from sympy.core.relational import Eq
|
| 17 |
+
from sympy.testing.pytest import raises
|
| 18 |
+
from sympy.utilities.iterables import is_sequence, iterable
|
| 19 |
+
|
| 20 |
+
from sympy.abc import x, y
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def test_Tuple():
|
| 24 |
+
t = (1, 2, 3, 4)
|
| 25 |
+
st = Tuple(*t)
|
| 26 |
+
assert set(sympify(t)) == set(st)
|
| 27 |
+
assert len(t) == len(st)
|
| 28 |
+
assert set(sympify(t[:2])) == set(st[:2])
|
| 29 |
+
assert isinstance(st[:], Tuple)
|
| 30 |
+
assert st == Tuple(1, 2, 3, 4)
|
| 31 |
+
assert st.func(*st.args) == st
|
| 32 |
+
p, q, r, s = symbols('p q r s')
|
| 33 |
+
t2 = (p, q, r, s)
|
| 34 |
+
st2 = Tuple(*t2)
|
| 35 |
+
assert st2.atoms() == set(t2)
|
| 36 |
+
assert st == st2.subs({p: 1, q: 2, r: 3, s: 4})
|
| 37 |
+
# issue 5505
|
| 38 |
+
assert all(isinstance(arg, Basic) for arg in st.args)
|
| 39 |
+
assert Tuple(p, 1).subs(p, 0) == Tuple(0, 1)
|
| 40 |
+
assert Tuple(p, Tuple(p, 1)).subs(p, 0) == Tuple(0, Tuple(0, 1))
|
| 41 |
+
|
| 42 |
+
assert Tuple(t2) == Tuple(Tuple(*t2))
|
| 43 |
+
assert Tuple.fromiter(t2) == Tuple(*t2)
|
| 44 |
+
assert Tuple.fromiter(x for x in range(4)) == Tuple(0, 1, 2, 3)
|
| 45 |
+
assert st2.fromiter(st2.args) == st2
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def test_Tuple_contains():
|
| 49 |
+
t1, t2 = Tuple(1), Tuple(2)
|
| 50 |
+
assert t1 in Tuple(1, 2, 3, t1, Tuple(t2))
|
| 51 |
+
assert t2 not in Tuple(1, 2, 3, t1, Tuple(t2))
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def test_Tuple_concatenation():
|
| 55 |
+
assert Tuple(1, 2) + Tuple(3, 4) == Tuple(1, 2, 3, 4)
|
| 56 |
+
assert (1, 2) + Tuple(3, 4) == Tuple(1, 2, 3, 4)
|
| 57 |
+
assert Tuple(1, 2) + (3, 4) == Tuple(1, 2, 3, 4)
|
| 58 |
+
raises(TypeError, lambda: Tuple(1, 2) + 3)
|
| 59 |
+
raises(TypeError, lambda: 1 + Tuple(2, 3))
|
| 60 |
+
|
| 61 |
+
#the Tuple case in __radd__ is only reached when a subclass is involved
|
| 62 |
+
class Tuple2(Tuple):
|
| 63 |
+
def __radd__(self, other):
|
| 64 |
+
return Tuple.__radd__(self, other + other)
|
| 65 |
+
assert Tuple(1, 2) + Tuple2(3, 4) == Tuple(1, 2, 1, 2, 3, 4)
|
| 66 |
+
assert Tuple2(1, 2) + Tuple(3, 4) == Tuple(1, 2, 3, 4)
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def test_Tuple_equality():
|
| 70 |
+
assert not isinstance(Tuple(1, 2), tuple)
|
| 71 |
+
assert (Tuple(1, 2) == (1, 2)) is True
|
| 72 |
+
assert (Tuple(1, 2) != (1, 2)) is False
|
| 73 |
+
assert (Tuple(1, 2) == (1, 3)) is False
|
| 74 |
+
assert (Tuple(1, 2) != (1, 3)) is True
|
| 75 |
+
assert (Tuple(1, 2) == Tuple(1, 2)) is True
|
| 76 |
+
assert (Tuple(1, 2) != Tuple(1, 2)) is False
|
| 77 |
+
assert (Tuple(1, 2) == Tuple(1, 3)) is False
|
| 78 |
+
assert (Tuple(1, 2) != Tuple(1, 3)) is True
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def test_Tuple_Eq():
|
| 82 |
+
assert Eq(Tuple(), Tuple()) is S.true
|
| 83 |
+
assert Eq(Tuple(1), 1) is S.false
|
| 84 |
+
assert Eq(Tuple(1, 2), Tuple(1)) is S.false
|
| 85 |
+
assert Eq(Tuple(1), Tuple(1)) is S.true
|
| 86 |
+
assert Eq(Tuple(1, 2), Tuple(1, 3)) is S.false
|
| 87 |
+
assert Eq(Tuple(1, 2), Tuple(1, 2)) is S.true
|
| 88 |
+
assert unchanged(Eq, Tuple(1, x), Tuple(1, 2))
|
| 89 |
+
assert Eq(Tuple(1, x), Tuple(1, 2)).subs(x, 2) is S.true
|
| 90 |
+
assert unchanged(Eq, Tuple(1, 2), x)
|
| 91 |
+
f = Function('f')
|
| 92 |
+
assert unchanged(Eq, Tuple(1), f(x))
|
| 93 |
+
assert Eq(Tuple(1), f(x)).subs(x, 1).subs(f, Lambda(y, (y,))) is S.true
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def test_Tuple_comparision():
|
| 97 |
+
assert (Tuple(1, 3) >= Tuple(-10, 30)) is S.true
|
| 98 |
+
assert (Tuple(1, 3) <= Tuple(-10, 30)) is S.false
|
| 99 |
+
assert (Tuple(1, 3) >= Tuple(1, 3)) is S.true
|
| 100 |
+
assert (Tuple(1, 3) <= Tuple(1, 3)) is S.true
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def test_Tuple_tuple_count():
|
| 104 |
+
assert Tuple(0, 1, 2, 3).tuple_count(4) == 0
|
| 105 |
+
assert Tuple(0, 4, 1, 2, 3).tuple_count(4) == 1
|
| 106 |
+
assert Tuple(0, 4, 1, 4, 2, 3).tuple_count(4) == 2
|
| 107 |
+
assert Tuple(0, 4, 1, 4, 2, 4, 3).tuple_count(4) == 3
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
def test_Tuple_index():
|
| 111 |
+
assert Tuple(4, 0, 1, 2, 3).index(4) == 0
|
| 112 |
+
assert Tuple(0, 4, 1, 2, 3).index(4) == 1
|
| 113 |
+
assert Tuple(0, 1, 4, 2, 3).index(4) == 2
|
| 114 |
+
assert Tuple(0, 1, 2, 4, 3).index(4) == 3
|
| 115 |
+
assert Tuple(0, 1, 2, 3, 4).index(4) == 4
|
| 116 |
+
|
| 117 |
+
raises(ValueError, lambda: Tuple(0, 1, 2, 3).index(4))
|
| 118 |
+
raises(ValueError, lambda: Tuple(4, 0, 1, 2, 3).index(4, 1))
|
| 119 |
+
raises(ValueError, lambda: Tuple(0, 1, 2, 3, 4).index(4, 1, 4))
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def test_Tuple_mul():
|
| 123 |
+
assert Tuple(1, 2, 3)*2 == Tuple(1, 2, 3, 1, 2, 3)
|
| 124 |
+
assert 2*Tuple(1, 2, 3) == Tuple(1, 2, 3, 1, 2, 3)
|
| 125 |
+
assert Tuple(1, 2, 3)*Integer(2) == Tuple(1, 2, 3, 1, 2, 3)
|
| 126 |
+
assert Integer(2)*Tuple(1, 2, 3) == Tuple(1, 2, 3, 1, 2, 3)
|
| 127 |
+
|
| 128 |
+
raises(TypeError, lambda: Tuple(1, 2, 3)*S.Half)
|
| 129 |
+
raises(TypeError, lambda: S.Half*Tuple(1, 2, 3))
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def test_tuple_wrapper():
|
| 133 |
+
|
| 134 |
+
@tuple_wrapper
|
| 135 |
+
def wrap_tuples_and_return(*t):
|
| 136 |
+
return t
|
| 137 |
+
|
| 138 |
+
p = symbols('p')
|
| 139 |
+
assert wrap_tuples_and_return(p, 1) == (p, 1)
|
| 140 |
+
assert wrap_tuples_and_return((p, 1)) == (Tuple(p, 1),)
|
| 141 |
+
assert wrap_tuples_and_return(1, (p, 2), 3) == (1, Tuple(p, 2), 3)
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
def test_iterable_is_sequence():
|
| 145 |
+
ordered = [[], (), Tuple(), Matrix([[]])]
|
| 146 |
+
unordered = [set()]
|
| 147 |
+
not_sympy_iterable = [{}, '', '']
|
| 148 |
+
assert all(is_sequence(i) for i in ordered)
|
| 149 |
+
assert all(not is_sequence(i) for i in unordered)
|
| 150 |
+
assert all(iterable(i) for i in ordered + unordered)
|
| 151 |
+
assert all(not iterable(i) for i in not_sympy_iterable)
|
| 152 |
+
assert all(iterable(i, exclude=None) for i in not_sympy_iterable)
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
def test_TupleKind():
|
| 156 |
+
kind = TupleKind(NumberKind, MatrixKind(NumberKind))
|
| 157 |
+
assert Tuple(1, Matrix([1, 2])).kind is kind
|
| 158 |
+
assert Tuple(1, 2).kind is TupleKind(NumberKind, NumberKind)
|
| 159 |
+
assert Tuple(1, 2).kind.element_kind == (NumberKind, NumberKind)
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
def test_Dict():
|
| 163 |
+
x, y, z = symbols('x y z')
|
| 164 |
+
d = Dict({x: 1, y: 2, z: 3})
|
| 165 |
+
assert d[x] == 1
|
| 166 |
+
assert d[y] == 2
|
| 167 |
+
raises(KeyError, lambda: d[2])
|
| 168 |
+
raises(KeyError, lambda: d['2'])
|
| 169 |
+
assert len(d) == 3
|
| 170 |
+
assert set(d.keys()) == {x, y, z}
|
| 171 |
+
assert set(d.values()) == {S.One, S(2), S(3)}
|
| 172 |
+
assert d.get(5, 'default') == 'default'
|
| 173 |
+
assert d.get('5', 'default') == 'default'
|
| 174 |
+
assert x in d and z in d and 5 not in d and '5' not in d
|
| 175 |
+
assert d.has(x) and d.has(1) # SymPy Basic .has method
|
| 176 |
+
|
| 177 |
+
# Test input types
|
| 178 |
+
# input - a Python dict
|
| 179 |
+
# input - items as args - SymPy style
|
| 180 |
+
assert (Dict({x: 1, y: 2, z: 3}) ==
|
| 181 |
+
Dict((x, 1), (y, 2), (z, 3)))
|
| 182 |
+
|
| 183 |
+
raises(TypeError, lambda: Dict(((x, 1), (y, 2), (z, 3))))
|
| 184 |
+
with raises(NotImplementedError):
|
| 185 |
+
d[5] = 6 # assert immutability
|
| 186 |
+
|
| 187 |
+
assert set(
|
| 188 |
+
d.items()) == {Tuple(x, S.One), Tuple(y, S(2)), Tuple(z, S(3))}
|
| 189 |
+
assert set(d) == {x, y, z}
|
| 190 |
+
assert str(d) == '{x: 1, y: 2, z: 3}'
|
| 191 |
+
assert d.__repr__() == '{x: 1, y: 2, z: 3}'
|
| 192 |
+
|
| 193 |
+
# Test creating a Dict from a Dict.
|
| 194 |
+
d = Dict({x: 1, y: 2, z: 3})
|
| 195 |
+
assert d == Dict(d)
|
| 196 |
+
|
| 197 |
+
# Test for supporting defaultdict
|
| 198 |
+
d = defaultdict(int)
|
| 199 |
+
assert d[x] == 0
|
| 200 |
+
assert d[y] == 0
|
| 201 |
+
assert d[z] == 0
|
| 202 |
+
assert Dict(d)
|
| 203 |
+
d = Dict(d)
|
| 204 |
+
assert len(d) == 3
|
| 205 |
+
assert set(d.keys()) == {x, y, z}
|
| 206 |
+
assert set(d.values()) == {S.Zero, S.Zero, S.Zero}
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
def test_issue_5788():
|
| 210 |
+
args = [(1, 2), (2, 1)]
|
| 211 |
+
for o in [Dict, Tuple, FiniteSet]:
|
| 212 |
+
# __eq__ and arg handling
|
| 213 |
+
if o != Tuple:
|
| 214 |
+
assert o(*args) == o(*reversed(args))
|
| 215 |
+
pair = [o(*args), o(*reversed(args))]
|
| 216 |
+
assert sorted(pair) == sorted(pair)
|
| 217 |
+
assert set(o(*args)) # doesn't fail
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_count_ops.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.concrete.summations import Sum
|
| 2 |
+
from sympy.core.basic import Basic
|
| 3 |
+
from sympy.core.function import (Derivative, Function, count_ops)
|
| 4 |
+
from sympy.core.numbers import (I, Rational, pi)
|
| 5 |
+
from sympy.core.relational import (Eq, Rel)
|
| 6 |
+
from sympy.core.singleton import S
|
| 7 |
+
from sympy.core.symbol import (Symbol, symbols)
|
| 8 |
+
from sympy.functions.elementary.exponential import exp
|
| 9 |
+
from sympy.functions.elementary.trigonometric import (cos, sin)
|
| 10 |
+
from sympy.integrals.integrals import Integral
|
| 11 |
+
from sympy.logic.boolalg import (And, Equivalent, ITE, Implies, Nand,
|
| 12 |
+
Nor, Not, Or, Xor)
|
| 13 |
+
from sympy.matrices.expressions.matexpr import MatrixSymbol
|
| 14 |
+
from sympy.core.containers import Tuple
|
| 15 |
+
|
| 16 |
+
x, y, z = symbols('x,y,z')
|
| 17 |
+
a, b, c = symbols('a,b,c')
|
| 18 |
+
|
| 19 |
+
def test_count_ops_non_visual():
|
| 20 |
+
def count(val):
|
| 21 |
+
return count_ops(val, visual=False)
|
| 22 |
+
assert count(x) == 0
|
| 23 |
+
assert count(x) is not S.Zero
|
| 24 |
+
assert count(x + y) == 1
|
| 25 |
+
assert count(x + y) is not S.One
|
| 26 |
+
assert count(x + y*x + 2*y) == 4
|
| 27 |
+
assert count({x + y: x}) == 1
|
| 28 |
+
assert count({x + y: S(2) + x}) is not S.One
|
| 29 |
+
assert count(x < y) == 1
|
| 30 |
+
assert count(Or(x,y)) == 1
|
| 31 |
+
assert count(And(x,y)) == 1
|
| 32 |
+
assert count(Not(x)) == 1
|
| 33 |
+
assert count(Nor(x,y)) == 2
|
| 34 |
+
assert count(Nand(x,y)) == 2
|
| 35 |
+
assert count(Xor(x,y)) == 1
|
| 36 |
+
assert count(Implies(x,y)) == 1
|
| 37 |
+
assert count(Equivalent(x,y)) == 1
|
| 38 |
+
assert count(ITE(x,y,z)) == 1
|
| 39 |
+
assert count(ITE(True,x,y)) == 0
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def test_count_ops_visual():
|
| 43 |
+
ADD, MUL, POW, SIN, COS, EXP, AND, D, G, M = symbols(
|
| 44 |
+
'Add Mul Pow sin cos exp And Derivative Integral Sum'.upper())
|
| 45 |
+
DIV, SUB, NEG = symbols('DIV SUB NEG')
|
| 46 |
+
LT, LE, GT, GE, EQ, NE = symbols('LT LE GT GE EQ NE')
|
| 47 |
+
NOT, OR, AND, XOR, IMPLIES, EQUIVALENT, _ITE, BASIC, TUPLE = symbols(
|
| 48 |
+
'Not Or And Xor Implies Equivalent ITE Basic Tuple'.upper())
|
| 49 |
+
|
| 50 |
+
def count(val):
|
| 51 |
+
return count_ops(val, visual=True)
|
| 52 |
+
|
| 53 |
+
assert count(7) is S.Zero
|
| 54 |
+
assert count(S(7)) is S.Zero
|
| 55 |
+
assert count(-1) == NEG
|
| 56 |
+
assert count(-2) == NEG
|
| 57 |
+
assert count(S(2)/3) == DIV
|
| 58 |
+
assert count(Rational(2, 3)) == DIV
|
| 59 |
+
assert count(pi/3) == DIV
|
| 60 |
+
assert count(-pi/3) == DIV + NEG
|
| 61 |
+
assert count(I - 1) == SUB
|
| 62 |
+
assert count(1 - I) == SUB
|
| 63 |
+
assert count(1 - 2*I) == SUB + MUL
|
| 64 |
+
|
| 65 |
+
assert count(x) is S.Zero
|
| 66 |
+
assert count(-x) == NEG
|
| 67 |
+
assert count(-2*x/3) == NEG + DIV + MUL
|
| 68 |
+
assert count(Rational(-2, 3)*x) == NEG + DIV + MUL
|
| 69 |
+
assert count(1/x) == DIV
|
| 70 |
+
assert count(1/(x*y)) == DIV + MUL
|
| 71 |
+
assert count(-1/x) == NEG + DIV
|
| 72 |
+
assert count(-2/x) == NEG + DIV
|
| 73 |
+
assert count(x/y) == DIV
|
| 74 |
+
assert count(-x/y) == NEG + DIV
|
| 75 |
+
|
| 76 |
+
assert count(x**2) == POW
|
| 77 |
+
assert count(-x**2) == POW + NEG
|
| 78 |
+
assert count(-2*x**2) == POW + MUL + NEG
|
| 79 |
+
|
| 80 |
+
assert count(x + pi/3) == ADD + DIV
|
| 81 |
+
assert count(x + S.One/3) == ADD + DIV
|
| 82 |
+
assert count(x + Rational(1, 3)) == ADD + DIV
|
| 83 |
+
assert count(x + y) == ADD
|
| 84 |
+
assert count(x - y) == SUB
|
| 85 |
+
assert count(y - x) == SUB
|
| 86 |
+
assert count(-1/(x - y)) == DIV + NEG + SUB
|
| 87 |
+
assert count(-1/(y - x)) == DIV + NEG + SUB
|
| 88 |
+
assert count(1 + x**y) == ADD + POW
|
| 89 |
+
assert count(1 + x + y) == 2*ADD
|
| 90 |
+
assert count(1 + x + y + z) == 3*ADD
|
| 91 |
+
assert count(1 + x**y + 2*x*y + y**2) == 3*ADD + 2*POW + 2*MUL
|
| 92 |
+
assert count(2*z + y + x + 1) == 3*ADD + MUL
|
| 93 |
+
assert count(2*z + y**17 + x + 1) == 3*ADD + MUL + POW
|
| 94 |
+
assert count(2*z + y**17 + x + sin(x)) == 3*ADD + POW + MUL + SIN
|
| 95 |
+
assert count(2*z + y**17 + x + sin(x**2)) == 3*ADD + MUL + 2*POW + SIN
|
| 96 |
+
assert count(2*z + y**17 + x + sin(
|
| 97 |
+
x**2) + exp(cos(x))) == 4*ADD + MUL + 2*POW + EXP + COS + SIN
|
| 98 |
+
|
| 99 |
+
assert count(Derivative(x, x)) == D
|
| 100 |
+
assert count(Integral(x, x) + 2*x/(1 + x)) == G + DIV + MUL + 2*ADD
|
| 101 |
+
assert count(Sum(x, (x, 1, x + 1)) + 2*x/(1 + x)) == M + DIV + MUL + 3*ADD
|
| 102 |
+
assert count(Basic()) is S.Zero
|
| 103 |
+
|
| 104 |
+
assert count({x + 1: sin(x)}) == ADD + SIN
|
| 105 |
+
assert count([x + 1, sin(x) + y, None]) == ADD + SIN + ADD
|
| 106 |
+
assert count({x + 1: sin(x), y: cos(x) + 1}) == SIN + COS + 2*ADD
|
| 107 |
+
assert count({}) is S.Zero
|
| 108 |
+
assert count([x + 1, sin(x)*y, None]) == SIN + ADD + MUL
|
| 109 |
+
assert count([]) is S.Zero
|
| 110 |
+
|
| 111 |
+
assert count(Basic()) == 0
|
| 112 |
+
assert count(Basic(Basic(),Basic(x,x+y))) == ADD + 2*BASIC
|
| 113 |
+
assert count(Basic(x, x + y)) == ADD + BASIC
|
| 114 |
+
assert [count(Rel(x, y, op)) for op in '< <= > >= == <> !='.split()
|
| 115 |
+
] == [LT, LE, GT, GE, EQ, NE, NE]
|
| 116 |
+
assert count(Or(x, y)) == OR
|
| 117 |
+
assert count(And(x, y)) == AND
|
| 118 |
+
assert count(Or(x, Or(y, And(z, a)))) == AND + OR
|
| 119 |
+
assert count(Nor(x, y)) == NOT + OR
|
| 120 |
+
assert count(Nand(x, y)) == NOT + AND
|
| 121 |
+
assert count(Xor(x, y)) == XOR
|
| 122 |
+
assert count(Implies(x, y)) == IMPLIES
|
| 123 |
+
assert count(Equivalent(x, y)) == EQUIVALENT
|
| 124 |
+
assert count(ITE(x, y, z)) == _ITE
|
| 125 |
+
assert count([Or(x, y), And(x, y), Basic(x + y)]
|
| 126 |
+
) == ADD + AND + BASIC + OR
|
| 127 |
+
|
| 128 |
+
assert count(Basic(Tuple(x))) == BASIC + TUPLE
|
| 129 |
+
#It checks that TUPLE is counted as an operation.
|
| 130 |
+
|
| 131 |
+
assert count(Eq(x + y, S(2))) == ADD + EQ
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def test_issue_9324():
|
| 135 |
+
def count(val):
|
| 136 |
+
return count_ops(val, visual=False)
|
| 137 |
+
|
| 138 |
+
M = MatrixSymbol('M', 10, 10)
|
| 139 |
+
assert count(M[0, 0]) == 0
|
| 140 |
+
assert count(2 * M[0, 0] + M[5, 7]) == 2
|
| 141 |
+
P = MatrixSymbol('P', 3, 3)
|
| 142 |
+
Q = MatrixSymbol('Q', 3, 3)
|
| 143 |
+
assert count(P + Q) == 1
|
| 144 |
+
m = Symbol('m', integer=True)
|
| 145 |
+
n = Symbol('n', integer=True)
|
| 146 |
+
M = MatrixSymbol('M', m + n, m * m)
|
| 147 |
+
assert count(M[0, 1]) == 2
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
def test_issue_21532():
|
| 151 |
+
f = Function('f')
|
| 152 |
+
g = Function('g')
|
| 153 |
+
FUNC_F, FUNC_G = symbols('FUNC_F, FUNC_G')
|
| 154 |
+
assert f(x).count_ops(visual=True) == FUNC_F
|
| 155 |
+
assert g(x).count_ops(visual=True) == FUNC_G
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_diff.py
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.concrete.summations import Sum
|
| 2 |
+
from sympy.core.expr import Expr
|
| 3 |
+
from sympy.core.function import (Derivative, Function, diff, Subs)
|
| 4 |
+
from sympy.core.numbers import (I, Rational, pi)
|
| 5 |
+
from sympy.core.relational import Eq
|
| 6 |
+
from sympy.core.singleton import S
|
| 7 |
+
from sympy.core.symbol import Symbol
|
| 8 |
+
from sympy.functions.combinatorial.factorials import factorial
|
| 9 |
+
from sympy.functions.elementary.complexes import (im, re)
|
| 10 |
+
from sympy.functions.elementary.exponential import (exp, log)
|
| 11 |
+
from sympy.functions.elementary.miscellaneous import Max
|
| 12 |
+
from sympy.functions.elementary.piecewise import Piecewise
|
| 13 |
+
from sympy.functions.elementary.trigonometric import (cos, cot, sin, tan)
|
| 14 |
+
from sympy.tensor.array.ndim_array import NDimArray
|
| 15 |
+
from sympy.testing.pytest import raises
|
| 16 |
+
from sympy.abc import a, b, c, x, y, z
|
| 17 |
+
|
| 18 |
+
def test_diff():
|
| 19 |
+
assert Rational(1, 3).diff(x) is S.Zero
|
| 20 |
+
assert I.diff(x) is S.Zero
|
| 21 |
+
assert pi.diff(x) is S.Zero
|
| 22 |
+
assert x.diff(x, 0) == x
|
| 23 |
+
assert (x**2).diff(x, 2, x) == 0
|
| 24 |
+
assert (x**2).diff((x, 2), x) == 0
|
| 25 |
+
assert (x**2).diff((x, 1), x) == 2
|
| 26 |
+
assert (x**2).diff((x, 1), (x, 1)) == 2
|
| 27 |
+
assert (x**2).diff((x, 2)) == 2
|
| 28 |
+
assert (x**2).diff(x, y, 0) == 2*x
|
| 29 |
+
assert (x**2).diff(x, (y, 0)) == 2*x
|
| 30 |
+
assert (x**2).diff(x, y) == 0
|
| 31 |
+
raises(ValueError, lambda: x.diff(1, x))
|
| 32 |
+
|
| 33 |
+
p = Rational(5)
|
| 34 |
+
e = a*b + b**p
|
| 35 |
+
assert e.diff(a) == b
|
| 36 |
+
assert e.diff(b) == a + 5*b**4
|
| 37 |
+
assert e.diff(b).diff(a) == Rational(1)
|
| 38 |
+
e = a*(b + c)
|
| 39 |
+
assert e.diff(a) == b + c
|
| 40 |
+
assert e.diff(b) == a
|
| 41 |
+
assert e.diff(b).diff(a) == Rational(1)
|
| 42 |
+
e = c**p
|
| 43 |
+
assert e.diff(c, 6) == Rational(0)
|
| 44 |
+
assert e.diff(c, 5) == Rational(120)
|
| 45 |
+
e = c**Rational(2)
|
| 46 |
+
assert e.diff(c) == 2*c
|
| 47 |
+
e = a*b*c
|
| 48 |
+
assert e.diff(c) == a*b
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def test_diff2():
|
| 52 |
+
n3 = Rational(3)
|
| 53 |
+
n2 = Rational(2)
|
| 54 |
+
n6 = Rational(6)
|
| 55 |
+
|
| 56 |
+
e = n3*(-n2 + x**n2)*cos(x) + x*(-n6 + x**n2)*sin(x)
|
| 57 |
+
assert e == 3*(-2 + x**2)*cos(x) + x*(-6 + x**2)*sin(x)
|
| 58 |
+
assert e.diff(x).expand() == x**3*cos(x)
|
| 59 |
+
|
| 60 |
+
e = (x + 1)**3
|
| 61 |
+
assert e.diff(x) == 3*(x + 1)**2
|
| 62 |
+
e = x*(x + 1)**3
|
| 63 |
+
assert e.diff(x) == (x + 1)**3 + 3*x*(x + 1)**2
|
| 64 |
+
e = 2*exp(x*x)*x
|
| 65 |
+
assert e.diff(x) == 2*exp(x**2) + 4*x**2*exp(x**2)
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def test_diff3():
|
| 69 |
+
p = Rational(5)
|
| 70 |
+
e = a*b + sin(b**p)
|
| 71 |
+
assert e == a*b + sin(b**5)
|
| 72 |
+
assert e.diff(a) == b
|
| 73 |
+
assert e.diff(b) == a + 5*b**4*cos(b**5)
|
| 74 |
+
e = tan(c)
|
| 75 |
+
assert e == tan(c)
|
| 76 |
+
assert e.diff(c) in [cos(c)**(-2), 1 + sin(c)**2/cos(c)**2, 1 + tan(c)**2]
|
| 77 |
+
e = c*log(c) - c
|
| 78 |
+
assert e == -c + c*log(c)
|
| 79 |
+
assert e.diff(c) == log(c)
|
| 80 |
+
e = log(sin(c))
|
| 81 |
+
assert e == log(sin(c))
|
| 82 |
+
assert e.diff(c) in [sin(c)**(-1)*cos(c), cot(c)]
|
| 83 |
+
e = (Rational(2)**a/log(Rational(2)))
|
| 84 |
+
assert e == 2**a*log(Rational(2))**(-1)
|
| 85 |
+
assert e.diff(a) == 2**a
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def test_diff_no_eval_derivative():
|
| 89 |
+
class My(Expr):
|
| 90 |
+
def __new__(cls, x):
|
| 91 |
+
return Expr.__new__(cls, x)
|
| 92 |
+
|
| 93 |
+
# My doesn't have its own _eval_derivative method
|
| 94 |
+
assert My(x).diff(x).func is Derivative
|
| 95 |
+
assert My(x).diff(x, 3).func is Derivative
|
| 96 |
+
assert re(x).diff(x, 2) == Derivative(re(x), (x, 2)) # issue 15518
|
| 97 |
+
assert diff(NDimArray([re(x), im(x)]), (x, 2)) == NDimArray(
|
| 98 |
+
[Derivative(re(x), (x, 2)), Derivative(im(x), (x, 2))])
|
| 99 |
+
# it doesn't have y so it shouldn't need a method for this case
|
| 100 |
+
assert My(x).diff(y) == 0
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def test_speed():
|
| 104 |
+
# this should return in 0.0s. If it takes forever, it's wrong.
|
| 105 |
+
assert x.diff(x, 10**8) == 0
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
def test_deriv_noncommutative():
|
| 109 |
+
A = Symbol("A", commutative=False)
|
| 110 |
+
f = Function("f")
|
| 111 |
+
assert A*f(x)*A == f(x)*A**2
|
| 112 |
+
assert A*f(x).diff(x)*A == f(x).diff(x) * A**2
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def test_diff_nth_derivative():
|
| 116 |
+
f = Function("f")
|
| 117 |
+
n = Symbol("n", integer=True)
|
| 118 |
+
|
| 119 |
+
expr = diff(sin(x), (x, n))
|
| 120 |
+
expr2 = diff(f(x), (x, 2))
|
| 121 |
+
expr3 = diff(f(x), (x, n))
|
| 122 |
+
|
| 123 |
+
assert expr.subs(sin(x), cos(-x)) == Derivative(cos(-x), (x, n))
|
| 124 |
+
assert expr.subs(n, 1).doit() == cos(x)
|
| 125 |
+
assert expr.subs(n, 2).doit() == -sin(x)
|
| 126 |
+
|
| 127 |
+
assert expr2.subs(Derivative(f(x), x), y) == Derivative(y, x)
|
| 128 |
+
# Currently not supported (cannot determine if `n > 1`):
|
| 129 |
+
#assert expr3.subs(Derivative(f(x), x), y) == Derivative(y, (x, n-1))
|
| 130 |
+
assert expr3 == Derivative(f(x), (x, n))
|
| 131 |
+
|
| 132 |
+
assert diff(x, (x, n)) == Piecewise((x, Eq(n, 0)), (1, Eq(n, 1)), (0, True))
|
| 133 |
+
assert diff(2*x, (x, n)).dummy_eq(
|
| 134 |
+
Sum(Piecewise((2*x*factorial(n)/(factorial(y)*factorial(-y + n)),
|
| 135 |
+
Eq(y, 0) & Eq(Max(0, -y + n), 0)),
|
| 136 |
+
(2*factorial(n)/(factorial(y)*factorial(-y + n)), Eq(y, 0) & Eq(Max(0,
|
| 137 |
+
-y + n), 1)), (0, True)), (y, 0, n)))
|
| 138 |
+
# TODO: assert diff(x**2, (x, n)) == x**(2-n)*ff(2, n)
|
| 139 |
+
exprm = x*sin(x)
|
| 140 |
+
mul_diff = diff(exprm, (x, n))
|
| 141 |
+
assert isinstance(mul_diff, Sum)
|
| 142 |
+
for i in range(5):
|
| 143 |
+
assert mul_diff.subs(n, i).doit() == exprm.diff((x, i)).expand()
|
| 144 |
+
|
| 145 |
+
exprm2 = 2*y*x*sin(x)*cos(x)*log(x)*exp(x)
|
| 146 |
+
dex = exprm2.diff((x, n))
|
| 147 |
+
assert isinstance(dex, Sum)
|
| 148 |
+
for i in range(7):
|
| 149 |
+
assert dex.subs(n, i).doit().expand() == \
|
| 150 |
+
exprm2.diff((x, i)).expand()
|
| 151 |
+
|
| 152 |
+
assert (cos(x)*sin(y)).diff([[x, y, z]]) == NDimArray([
|
| 153 |
+
-sin(x)*sin(y), cos(x)*cos(y), 0])
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
def test_issue_16160():
|
| 157 |
+
assert Derivative(x**3, (x, x)).subs(x, 2) == Subs(
|
| 158 |
+
Derivative(x**3, (x, 2)), x, 2)
|
| 159 |
+
assert Derivative(1 + x**3, (x, x)).subs(x, 0
|
| 160 |
+
) == Derivative(1 + y**3, (y, 0)).subs(y, 0)
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_equal.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.numbers import Rational
|
| 2 |
+
from sympy.core.symbol import (Dummy, Symbol)
|
| 3 |
+
from sympy.functions.elementary.exponential import exp
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def test_equal():
|
| 7 |
+
b = Symbol("b")
|
| 8 |
+
a = Symbol("a")
|
| 9 |
+
e1 = a + b
|
| 10 |
+
e2 = 2*a*b
|
| 11 |
+
e3 = a**3*b**2
|
| 12 |
+
e4 = a*b + b*a
|
| 13 |
+
assert not e1 == e2
|
| 14 |
+
assert not e1 == e2
|
| 15 |
+
assert e1 != e2
|
| 16 |
+
assert e2 == e4
|
| 17 |
+
assert e2 != e3
|
| 18 |
+
assert not e2 == e3
|
| 19 |
+
|
| 20 |
+
x = Symbol("x")
|
| 21 |
+
e1 = exp(x + 1/x)
|
| 22 |
+
y = Symbol("x")
|
| 23 |
+
e2 = exp(y + 1/y)
|
| 24 |
+
assert e1 == e2
|
| 25 |
+
assert not e1 != e2
|
| 26 |
+
y = Symbol("y")
|
| 27 |
+
e2 = exp(y + 1/y)
|
| 28 |
+
assert not e1 == e2
|
| 29 |
+
assert e1 != e2
|
| 30 |
+
|
| 31 |
+
e5 = Rational(3) + 2*x - x - x
|
| 32 |
+
assert e5 == 3
|
| 33 |
+
assert 3 == e5
|
| 34 |
+
assert e5 != 4
|
| 35 |
+
assert 4 != e5
|
| 36 |
+
assert e5 != 3 + x
|
| 37 |
+
assert 3 + x != e5
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def test_expevalbug():
|
| 41 |
+
x = Symbol("x")
|
| 42 |
+
e1 = exp(1*x)
|
| 43 |
+
e3 = exp(x)
|
| 44 |
+
assert e1 == e3
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def test_cmp_bug1():
|
| 48 |
+
class T:
|
| 49 |
+
pass
|
| 50 |
+
|
| 51 |
+
t = T()
|
| 52 |
+
x = Symbol("x")
|
| 53 |
+
|
| 54 |
+
assert not (x == t)
|
| 55 |
+
assert (x != t)
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def test_cmp_bug2():
|
| 59 |
+
class T:
|
| 60 |
+
pass
|
| 61 |
+
|
| 62 |
+
t = T()
|
| 63 |
+
|
| 64 |
+
assert not (Symbol == t)
|
| 65 |
+
assert (Symbol != t)
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def test_cmp_issue_4357():
|
| 69 |
+
""" Check that Basic subclasses can be compared with sympifiable objects.
|
| 70 |
+
|
| 71 |
+
https://github.com/sympy/sympy/issues/4357
|
| 72 |
+
"""
|
| 73 |
+
assert not (Symbol == 1)
|
| 74 |
+
assert (Symbol != 1)
|
| 75 |
+
assert not (Symbol == 'x')
|
| 76 |
+
assert (Symbol != 'x')
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def test_dummy_eq():
|
| 80 |
+
x = Symbol('x')
|
| 81 |
+
y = Symbol('y')
|
| 82 |
+
|
| 83 |
+
u = Dummy('u')
|
| 84 |
+
|
| 85 |
+
assert (u**2 + 1).dummy_eq(x**2 + 1) is True
|
| 86 |
+
assert ((u**2 + 1) == (x**2 + 1)) is False
|
| 87 |
+
|
| 88 |
+
assert (u**2 + y).dummy_eq(x**2 + y, x) is True
|
| 89 |
+
assert (u**2 + y).dummy_eq(x**2 + y, y) is False
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_eval.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.function import Function
|
| 2 |
+
from sympy.core.numbers import (I, Rational)
|
| 3 |
+
from sympy.core.singleton import S
|
| 4 |
+
from sympy.core.symbol import Symbol
|
| 5 |
+
from sympy.functions.elementary.exponential import exp
|
| 6 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 7 |
+
from sympy.functions.elementary.trigonometric import (cos, tan)
|
| 8 |
+
from sympy.testing.pytest import XFAIL
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def test_add_eval():
|
| 12 |
+
a = Symbol("a")
|
| 13 |
+
b = Symbol("b")
|
| 14 |
+
c = Rational(1)
|
| 15 |
+
p = Rational(5)
|
| 16 |
+
assert a*b + c + p == a*b + 6
|
| 17 |
+
assert c + a + p == a + 6
|
| 18 |
+
assert c + a - p == a + (-4)
|
| 19 |
+
assert a + a == 2*a
|
| 20 |
+
assert a + p + a == 2*a + 5
|
| 21 |
+
assert c + p == Rational(6)
|
| 22 |
+
assert b + a - b == a
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def test_addmul_eval():
|
| 26 |
+
a = Symbol("a")
|
| 27 |
+
b = Symbol("b")
|
| 28 |
+
c = Rational(1)
|
| 29 |
+
p = Rational(5)
|
| 30 |
+
assert c + a + b*c + a - p == 2*a + b + (-4)
|
| 31 |
+
assert a*2 + p + a == a*2 + 5 + a
|
| 32 |
+
assert a*2 + p + a == 3*a + 5
|
| 33 |
+
assert a*2 + a == 3*a
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def test_pow_eval():
|
| 37 |
+
# XXX Pow does not fully support conversion of negative numbers
|
| 38 |
+
# to their complex equivalent
|
| 39 |
+
|
| 40 |
+
assert sqrt(-1) == I
|
| 41 |
+
|
| 42 |
+
assert sqrt(-4) == 2*I
|
| 43 |
+
assert sqrt( 4) == 2
|
| 44 |
+
assert (8)**Rational(1, 3) == 2
|
| 45 |
+
assert (-8)**Rational(1, 3) == 2*((-1)**Rational(1, 3))
|
| 46 |
+
|
| 47 |
+
assert sqrt(-2) == I*sqrt(2)
|
| 48 |
+
assert (-1)**Rational(1, 3) != I
|
| 49 |
+
assert (-10)**Rational(1, 3) != I*((10)**Rational(1, 3))
|
| 50 |
+
assert (-2)**Rational(1, 4) != (2)**Rational(1, 4)
|
| 51 |
+
|
| 52 |
+
assert 64**Rational(1, 3) == 4
|
| 53 |
+
assert 64**Rational(2, 3) == 16
|
| 54 |
+
assert 24/sqrt(64) == 3
|
| 55 |
+
assert (-27)**Rational(1, 3) == 3*(-1)**Rational(1, 3)
|
| 56 |
+
|
| 57 |
+
assert (cos(2) / tan(2))**2 == (cos(2) / tan(2))**2
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
@XFAIL
|
| 61 |
+
def test_pow_eval_X1():
|
| 62 |
+
assert (-1)**Rational(1, 3) == S.Half + S.Half*I*sqrt(3)
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def test_mulpow_eval():
|
| 66 |
+
x = Symbol('x')
|
| 67 |
+
assert sqrt(50)/(sqrt(2)*x) == 5/x
|
| 68 |
+
assert sqrt(27)/sqrt(3) == 3
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def test_evalpow_bug():
|
| 72 |
+
x = Symbol("x")
|
| 73 |
+
assert 1/(1/x) == x
|
| 74 |
+
assert 1/(-1/x) == -x
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def test_symbol_expand():
|
| 78 |
+
x = Symbol('x')
|
| 79 |
+
y = Symbol('y')
|
| 80 |
+
|
| 81 |
+
f = x**4*y**4
|
| 82 |
+
assert f == x**4*y**4
|
| 83 |
+
assert f == f.expand()
|
| 84 |
+
|
| 85 |
+
g = (x*y)**4
|
| 86 |
+
assert g == f
|
| 87 |
+
assert g.expand() == f
|
| 88 |
+
assert g.expand() == g.expand().expand()
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def test_function():
|
| 92 |
+
f, l = map(Function, 'fl')
|
| 93 |
+
x = Symbol('x')
|
| 94 |
+
assert exp(l(x))*l(x)/exp(l(x)) == l(x)
|
| 95 |
+
assert exp(f(x))*f(x)/exp(f(x)) == f(x)
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_evalf.py
ADDED
|
@@ -0,0 +1,738 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import math
|
| 2 |
+
|
| 3 |
+
from sympy.concrete.products import (Product, product)
|
| 4 |
+
from sympy.concrete.summations import Sum
|
| 5 |
+
from sympy.core.add import Add
|
| 6 |
+
from sympy.core.evalf import N
|
| 7 |
+
from sympy.core.function import (Function, nfloat)
|
| 8 |
+
from sympy.core.mul import Mul
|
| 9 |
+
from sympy.core import (GoldenRatio)
|
| 10 |
+
from sympy.core.numbers import (AlgebraicNumber, E, Float, I, Rational,
|
| 11 |
+
oo, zoo, nan, pi)
|
| 12 |
+
from sympy.core.power import Pow
|
| 13 |
+
from sympy.core.relational import Eq
|
| 14 |
+
from sympy.core.singleton import S
|
| 15 |
+
from sympy.core.symbol import Symbol
|
| 16 |
+
from sympy.core.sympify import sympify
|
| 17 |
+
from sympy.functions.combinatorial.factorials import factorial
|
| 18 |
+
from sympy.functions.combinatorial.numbers import fibonacci
|
| 19 |
+
from sympy.functions.elementary.complexes import (Abs, re, im)
|
| 20 |
+
from sympy.functions.elementary.exponential import (exp, log)
|
| 21 |
+
from sympy.functions.elementary.hyperbolic import (acosh, cosh)
|
| 22 |
+
from sympy.functions.elementary.integers import (ceiling, floor)
|
| 23 |
+
from sympy.functions.elementary.miscellaneous import (Max, sqrt)
|
| 24 |
+
from sympy.functions.elementary.trigonometric import (acos, atan, cos, sin, tan)
|
| 25 |
+
from sympy.integrals.integrals import (Integral, integrate)
|
| 26 |
+
from sympy.polys.polytools import factor
|
| 27 |
+
from sympy.polys.rootoftools import CRootOf
|
| 28 |
+
from sympy.polys.specialpolys import cyclotomic_poly
|
| 29 |
+
from sympy.printing import srepr
|
| 30 |
+
from sympy.printing.str import sstr
|
| 31 |
+
from sympy.simplify.simplify import simplify
|
| 32 |
+
from sympy.core.numbers import comp
|
| 33 |
+
from sympy.core.evalf import (complex_accuracy, PrecisionExhausted,
|
| 34 |
+
scaled_zero, get_integer_part, as_mpmath, evalf, _evalf_with_bounded_error)
|
| 35 |
+
from mpmath import inf, ninf, make_mpc
|
| 36 |
+
from mpmath.libmp.libmpf import from_float, fzero
|
| 37 |
+
from sympy.core.expr import unchanged
|
| 38 |
+
from sympy.testing.pytest import raises, XFAIL
|
| 39 |
+
from sympy.abc import n, x, y
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def NS(e, n=15, **options):
|
| 43 |
+
return sstr(sympify(e).evalf(n, **options), full_prec=True)
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def test_evalf_helpers():
|
| 47 |
+
from mpmath.libmp import finf
|
| 48 |
+
assert complex_accuracy((from_float(2.0), None, 35, None)) == 35
|
| 49 |
+
assert complex_accuracy((from_float(2.0), from_float(10.0), 35, 100)) == 37
|
| 50 |
+
assert complex_accuracy(
|
| 51 |
+
(from_float(2.0), from_float(1000.0), 35, 100)) == 43
|
| 52 |
+
assert complex_accuracy((from_float(2.0), from_float(10.0), 100, 35)) == 35
|
| 53 |
+
assert complex_accuracy(
|
| 54 |
+
(from_float(2.0), from_float(1000.0), 100, 35)) == 35
|
| 55 |
+
assert complex_accuracy(finf) == math.inf
|
| 56 |
+
assert complex_accuracy(zoo) == math.inf
|
| 57 |
+
raises(ValueError, lambda: get_integer_part(zoo, 1, {}))
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def test_evalf_basic():
|
| 61 |
+
assert NS('pi', 15) == '3.14159265358979'
|
| 62 |
+
assert NS('2/3', 10) == '0.6666666667'
|
| 63 |
+
assert NS('355/113-pi', 6) == '2.66764e-7'
|
| 64 |
+
assert NS('16*atan(1/5)-4*atan(1/239)', 15) == '3.14159265358979'
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def test_cancellation():
|
| 68 |
+
assert NS(Add(pi, Rational(1, 10**1000), -pi, evaluate=False), 15,
|
| 69 |
+
maxn=1200) == '1.00000000000000e-1000'
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def test_evalf_powers():
|
| 73 |
+
assert NS('pi**(10**20)', 10) == '1.339148777e+49714987269413385435'
|
| 74 |
+
assert NS(pi**(10**100), 10) == ('4.946362032e+4971498726941338543512682882'
|
| 75 |
+
'9089887365167832438044244613405349992494711208'
|
| 76 |
+
'95526746555473864642912223')
|
| 77 |
+
assert NS('2**(1/10**50)', 15) == '1.00000000000000'
|
| 78 |
+
assert NS('2**(1/10**50)-1', 15) == '6.93147180559945e-51'
|
| 79 |
+
|
| 80 |
+
# Evaluation of Rump's ill-conditioned polynomial
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def test_evalf_rump():
|
| 84 |
+
a = 1335*y**6/4 + x**2*(11*x**2*y**2 - y**6 - 121*y**4 - 2) + 11*y**8/2 + x/(2*y)
|
| 85 |
+
assert NS(a, 15, subs={x: 77617, y: 33096}) == '-0.827396059946821'
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def test_evalf_complex():
|
| 89 |
+
assert NS('2*sqrt(pi)*I', 10) == '3.544907702*I'
|
| 90 |
+
assert NS('3+3*I', 15) == '3.00000000000000 + 3.00000000000000*I'
|
| 91 |
+
assert NS('E+pi*I', 15) == '2.71828182845905 + 3.14159265358979*I'
|
| 92 |
+
assert NS('pi * (3+4*I)', 15) == '9.42477796076938 + 12.5663706143592*I'
|
| 93 |
+
assert NS('I*(2+I)', 15) == '-1.00000000000000 + 2.00000000000000*I'
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
@XFAIL
|
| 97 |
+
def test_evalf_complex_bug():
|
| 98 |
+
assert NS('(pi+E*I)*(E+pi*I)', 15) in ('0.e-15 + 17.25866050002*I',
|
| 99 |
+
'0.e-17 + 17.25866050002*I', '-0.e-17 + 17.25866050002*I')
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def test_evalf_complex_powers():
|
| 103 |
+
assert NS('(E+pi*I)**100000000000000000') == \
|
| 104 |
+
'-3.58896782867793e+61850354284995199 + 4.58581754997159e+61850354284995199*I'
|
| 105 |
+
# XXX: rewrite if a+a*I simplification introduced in SymPy
|
| 106 |
+
#assert NS('(pi + pi*I)**2') in ('0.e-15 + 19.7392088021787*I', '0.e-16 + 19.7392088021787*I')
|
| 107 |
+
assert NS('(pi + pi*I)**2', chop=True) == '19.7392088021787*I'
|
| 108 |
+
assert NS(
|
| 109 |
+
'(pi + 1/10**8 + pi*I)**2') == '6.2831853e-8 + 19.7392088650106*I'
|
| 110 |
+
assert NS('(pi + 1/10**12 + pi*I)**2') == '6.283e-12 + 19.7392088021850*I'
|
| 111 |
+
assert NS('(pi + pi*I)**4', chop=True) == '-389.636364136010'
|
| 112 |
+
assert NS(
|
| 113 |
+
'(pi + 1/10**8 + pi*I)**4') == '-389.636366616512 + 2.4805021e-6*I'
|
| 114 |
+
assert NS('(pi + 1/10**12 + pi*I)**4') == '-389.636364136258 + 2.481e-10*I'
|
| 115 |
+
assert NS(
|
| 116 |
+
'(10000*pi + 10000*pi*I)**4', chop=True) == '-3.89636364136010e+18'
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
@XFAIL
|
| 120 |
+
def test_evalf_complex_powers_bug():
|
| 121 |
+
assert NS('(pi + pi*I)**4') == '-389.63636413601 + 0.e-14*I'
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def test_evalf_exponentiation():
|
| 125 |
+
assert NS(sqrt(-pi)) == '1.77245385090552*I'
|
| 126 |
+
assert NS(Pow(pi*I, Rational(
|
| 127 |
+
1, 2), evaluate=False)) == '1.25331413731550 + 1.25331413731550*I'
|
| 128 |
+
assert NS(pi**I) == '0.413292116101594 + 0.910598499212615*I'
|
| 129 |
+
assert NS(pi**(E + I/3)) == '20.8438653991931 + 8.36343473930031*I'
|
| 130 |
+
assert NS((pi + I/3)**(E + I/3)) == '17.2442906093590 + 13.6839376767037*I'
|
| 131 |
+
assert NS(exp(pi)) == '23.1406926327793'
|
| 132 |
+
assert NS(exp(pi + E*I)) == '-21.0981542849657 + 9.50576358282422*I'
|
| 133 |
+
assert NS(pi**pi) == '36.4621596072079'
|
| 134 |
+
assert NS((-pi)**pi) == '-32.9138577418939 - 15.6897116534332*I'
|
| 135 |
+
assert NS((-pi)**(-pi)) == '-0.0247567717232697 + 0.0118013091280262*I'
|
| 136 |
+
|
| 137 |
+
# An example from Smith, "Multiple Precision Complex Arithmetic and Functions"
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
def test_evalf_complex_cancellation():
|
| 141 |
+
A = Rational('63287/100000')
|
| 142 |
+
B = Rational('52498/100000')
|
| 143 |
+
C = Rational('69301/100000')
|
| 144 |
+
D = Rational('83542/100000')
|
| 145 |
+
F = Rational('2231321613/2500000000')
|
| 146 |
+
# XXX: the number of returned mantissa digits in the real part could
|
| 147 |
+
# change with the implementation. What matters is that the returned digits are
|
| 148 |
+
# correct; those that are showing now are correct.
|
| 149 |
+
# >>> ((A+B*I)*(C+D*I)).expand()
|
| 150 |
+
# 64471/10000000000 + 2231321613*I/2500000000
|
| 151 |
+
# >>> 2231321613*4
|
| 152 |
+
# 8925286452L
|
| 153 |
+
assert NS((A + B*I)*(C + D*I), 6) == '6.44710e-6 + 0.892529*I'
|
| 154 |
+
assert NS((A + B*I)*(C + D*I), 10) == '6.447100000e-6 + 0.8925286452*I'
|
| 155 |
+
assert NS((A + B*I)*(
|
| 156 |
+
C + D*I) - F*I, 5) in ('6.4471e-6 + 0.e-14*I', '6.4471e-6 - 0.e-14*I')
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def test_evalf_logs():
|
| 160 |
+
assert NS("log(3+pi*I)", 15) == '1.46877619736226 + 0.808448792630022*I'
|
| 161 |
+
assert NS("log(pi*I)", 15) == '1.14472988584940 + 1.57079632679490*I'
|
| 162 |
+
assert NS('log(-1 + 0.00001)', 2) == '-1.0e-5 + 3.1*I'
|
| 163 |
+
assert NS('log(100, 10, evaluate=False)', 15) == '2.00000000000000'
|
| 164 |
+
assert NS('-2*I*log(-(-1)**(S(1)/9))', 15) == '-5.58505360638185'
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
def test_evalf_trig():
|
| 168 |
+
assert NS('sin(1)', 15) == '0.841470984807897'
|
| 169 |
+
assert NS('cos(1)', 15) == '0.540302305868140'
|
| 170 |
+
assert NS('tan(1)', 15) == '1.55740772465490'
|
| 171 |
+
assert NS('sin(10**-6)', 15) == '9.99999999999833e-7'
|
| 172 |
+
assert NS('cos(10**-6)', 15) == '0.999999999999500'
|
| 173 |
+
assert NS('tan(10**-6)', 15) == '1.00000000000033e-6'
|
| 174 |
+
assert NS('sin(E*10**100)', 15) == '0.409160531722613'
|
| 175 |
+
assert NS('tan(I)',15) =='0.761594155955765*I'
|
| 176 |
+
assert NS('tan(1000*I)',15)== '1.00000000000000*I'
|
| 177 |
+
# Some input near roots
|
| 178 |
+
assert NS(sin(exp(pi*sqrt(163))*pi), 15) == '-2.35596641936785e-12'
|
| 179 |
+
assert NS(sin(pi*10**100 + Rational(7, 10**5), evaluate=False), 15, maxn=120) == \
|
| 180 |
+
'6.99999999428333e-5'
|
| 181 |
+
assert NS(sin(Rational(7, 10**5), evaluate=False), 15) == \
|
| 182 |
+
'6.99999999428333e-5'
|
| 183 |
+
|
| 184 |
+
# Check detection of various false identities
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
def test_evalf_near_integers():
|
| 188 |
+
# Binet's formula
|
| 189 |
+
f = lambda n: ((1 + sqrt(5))**n)/(2**n * sqrt(5))
|
| 190 |
+
assert NS(f(5000) - fibonacci(5000), 10, maxn=1500) == '5.156009964e-1046'
|
| 191 |
+
# Some near-integer identities from
|
| 192 |
+
# http://mathworld.wolfram.com/AlmostInteger.html
|
| 193 |
+
assert NS('sin(2017*2**(1/5))', 15) == '-1.00000000000000'
|
| 194 |
+
assert NS('sin(2017*2**(1/5))', 20) == '-0.99999999999999997857'
|
| 195 |
+
assert NS('1+sin(2017*2**(1/5))', 15) == '2.14322287389390e-17'
|
| 196 |
+
assert NS('45 - 613*E/37 + 35/991', 15) == '6.03764498766326e-11'
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
def test_evalf_ramanujan():
|
| 200 |
+
assert NS(exp(pi*sqrt(163)) - 640320**3 - 744, 10) == '-7.499274028e-13'
|
| 201 |
+
# A related identity
|
| 202 |
+
A = 262537412640768744*exp(-pi*sqrt(163))
|
| 203 |
+
B = 196884*exp(-2*pi*sqrt(163))
|
| 204 |
+
C = 103378831900730205293632*exp(-3*pi*sqrt(163))
|
| 205 |
+
assert NS(1 - A - B + C, 10) == '1.613679005e-59'
|
| 206 |
+
|
| 207 |
+
# Input that for various reasons have failed at some point
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
def test_evalf_bugs():
|
| 211 |
+
assert NS(sin(1) + exp(-10**10), 10) == NS(sin(1), 10)
|
| 212 |
+
assert NS(exp(10**10) + sin(1), 10) == NS(exp(10**10), 10)
|
| 213 |
+
assert NS('expand_log(log(1+1/10**50))', 20) == '1.0000000000000000000e-50'
|
| 214 |
+
assert NS('log(10**100,10)', 10) == '100.0000000'
|
| 215 |
+
assert NS('log(2)', 10) == '0.6931471806'
|
| 216 |
+
assert NS(
|
| 217 |
+
'(sin(x)-x)/x**3', 15, subs={x: '1/10**50'}) == '-0.166666666666667'
|
| 218 |
+
assert NS(sin(1) + Rational(
|
| 219 |
+
1, 10**100)*I, 15) == '0.841470984807897 + 1.00000000000000e-100*I'
|
| 220 |
+
assert x.evalf() == x
|
| 221 |
+
assert NS((1 + I)**2*I, 6) == '-2.00000'
|
| 222 |
+
d = {n: (
|
| 223 |
+
-1)**Rational(6, 7), y: (-1)**Rational(4, 7), x: (-1)**Rational(2, 7)}
|
| 224 |
+
assert NS((x*(1 + y*(1 + n))).subs(d).evalf(), 6) == '0.346011 + 0.433884*I'
|
| 225 |
+
assert NS(((-I - sqrt(2)*I)**2).evalf()) == '-5.82842712474619'
|
| 226 |
+
assert NS((1 + I)**2*I, 15) == '-2.00000000000000'
|
| 227 |
+
# issue 4758 (1/2):
|
| 228 |
+
assert NS(pi.evalf(69) - pi) == '-4.43863937855894e-71'
|
| 229 |
+
# issue 4758 (2/2): With the bug present, this still only fails if the
|
| 230 |
+
# terms are in the order given here. This is not generally the case,
|
| 231 |
+
# because the order depends on the hashes of the terms.
|
| 232 |
+
assert NS(20 - 5008329267844*n**25 - 477638700*n**37 - 19*n,
|
| 233 |
+
subs={n: .01}) == '19.8100000000000'
|
| 234 |
+
assert NS(((x - 1)*(1 - x)**1000).n()
|
| 235 |
+
) == '(1.00000000000000 - x)**1000*(x - 1.00000000000000)'
|
| 236 |
+
assert NS((-x).n()) == '-x'
|
| 237 |
+
assert NS((-2*x).n()) == '-2.00000000000000*x'
|
| 238 |
+
assert NS((-2*x*y).n()) == '-2.00000000000000*x*y'
|
| 239 |
+
assert cos(x).n(subs={x: 1+I}) == cos(x).subs(x, 1+I).n()
|
| 240 |
+
# issue 6660. Also NaN != mpmath.nan
|
| 241 |
+
# In this order:
|
| 242 |
+
# 0*nan, 0/nan, 0*inf, 0/inf
|
| 243 |
+
# 0+nan, 0-nan, 0+inf, 0-inf
|
| 244 |
+
# >>> n = Some Number
|
| 245 |
+
# n*nan, n/nan, n*inf, n/inf
|
| 246 |
+
# n+nan, n-nan, n+inf, n-inf
|
| 247 |
+
assert (0*E**(oo)).n() is S.NaN
|
| 248 |
+
assert (0/E**(oo)).n() is S.Zero
|
| 249 |
+
|
| 250 |
+
assert (0+E**(oo)).n() is S.Infinity
|
| 251 |
+
assert (0-E**(oo)).n() is S.NegativeInfinity
|
| 252 |
+
|
| 253 |
+
assert (5*E**(oo)).n() is S.Infinity
|
| 254 |
+
assert (5/E**(oo)).n() is S.Zero
|
| 255 |
+
|
| 256 |
+
assert (5+E**(oo)).n() is S.Infinity
|
| 257 |
+
assert (5-E**(oo)).n() is S.NegativeInfinity
|
| 258 |
+
|
| 259 |
+
#issue 7416
|
| 260 |
+
assert as_mpmath(0.0, 10, {'chop': True}) == 0
|
| 261 |
+
|
| 262 |
+
#issue 5412
|
| 263 |
+
assert ((oo*I).n() == S.Infinity*I)
|
| 264 |
+
assert ((oo+oo*I).n() == S.Infinity + S.Infinity*I)
|
| 265 |
+
|
| 266 |
+
#issue 11518
|
| 267 |
+
assert NS(2*x**2.5, 5) == '2.0000*x**2.5000'
|
| 268 |
+
|
| 269 |
+
#issue 13076
|
| 270 |
+
assert NS(Mul(Max(0, y), x, evaluate=False).evalf()) == 'x*Max(0, y)'
|
| 271 |
+
|
| 272 |
+
#issue 18516
|
| 273 |
+
assert NS(log(S(3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589376)/36360291795869936842385267079543319118023385026001623040346035832580600191583895484198508262979388783308179702534403855752855931517013066142992430916562025780021771247847643450125342836565813209972590371590152578728008385990139795377610001).evalf(15, chop=True)) == '-oo'
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
def test_evalf_integer_parts():
|
| 277 |
+
a = floor(log(8)/log(2) - exp(-1000), evaluate=False)
|
| 278 |
+
b = floor(log(8)/log(2), evaluate=False)
|
| 279 |
+
assert a.evalf() == 3.0
|
| 280 |
+
assert b.evalf() == 3.0
|
| 281 |
+
# equals, as a fallback, can still fail but it might succeed as here
|
| 282 |
+
assert ceiling(10*(sin(1)**2 + cos(1)**2)) == 10
|
| 283 |
+
|
| 284 |
+
assert int(floor(factorial(50)/E, evaluate=False).evalf(70)) == \
|
| 285 |
+
int(11188719610782480504630258070757734324011354208865721592720336800)
|
| 286 |
+
assert int(ceiling(factorial(50)/E, evaluate=False).evalf(70)) == \
|
| 287 |
+
int(11188719610782480504630258070757734324011354208865721592720336801)
|
| 288 |
+
assert int(floor(GoldenRatio**999 / sqrt(5) + S.Half)
|
| 289 |
+
.evalf(1000)) == fibonacci(999)
|
| 290 |
+
assert int(floor(GoldenRatio**1000 / sqrt(5) + S.Half)
|
| 291 |
+
.evalf(1000)) == fibonacci(1000)
|
| 292 |
+
|
| 293 |
+
assert ceiling(x).evalf(subs={x: 3}) == 3.0
|
| 294 |
+
assert ceiling(x).evalf(subs={x: 3*I}) == 3.0*I
|
| 295 |
+
assert ceiling(x).evalf(subs={x: 2 + 3*I}) == 2.0 + 3.0*I
|
| 296 |
+
assert ceiling(x).evalf(subs={x: 3.}) == 3.0
|
| 297 |
+
assert ceiling(x).evalf(subs={x: 3.*I}) == 3.0*I
|
| 298 |
+
assert ceiling(x).evalf(subs={x: 2. + 3*I}) == 2.0 + 3.0*I
|
| 299 |
+
|
| 300 |
+
assert float((floor(1.5, evaluate=False)+1/9).evalf()) == 1 + 1/9
|
| 301 |
+
assert float((floor(0.5, evaluate=False)+20).evalf()) == 20
|
| 302 |
+
|
| 303 |
+
# issue 19991
|
| 304 |
+
n = 1169809367327212570704813632106852886389036911
|
| 305 |
+
r = 744723773141314414542111064094745678855643068
|
| 306 |
+
|
| 307 |
+
assert floor(n / (pi / 2)) == r
|
| 308 |
+
assert floor(80782 * sqrt(2)) == 114242
|
| 309 |
+
|
| 310 |
+
# issue 20076
|
| 311 |
+
assert 260515 - floor(260515/pi + 1/2) * pi == atan(tan(260515))
|
| 312 |
+
|
| 313 |
+
assert floor(x).evalf(subs={x: sqrt(2)}) == 1.0
|
| 314 |
+
|
| 315 |
+
|
| 316 |
+
def test_evalf_trig_zero_detection():
|
| 317 |
+
a = sin(160*pi, evaluate=False)
|
| 318 |
+
t = a.evalf(maxn=100)
|
| 319 |
+
assert abs(t) < 1e-100
|
| 320 |
+
assert t._prec < 2
|
| 321 |
+
assert a.evalf(chop=True) == 0
|
| 322 |
+
raises(PrecisionExhausted, lambda: a.evalf(strict=True))
|
| 323 |
+
|
| 324 |
+
|
| 325 |
+
def test_evalf_sum():
|
| 326 |
+
assert Sum(n,(n,1,2)).evalf() == 3.
|
| 327 |
+
assert Sum(n,(n,1,2)).doit().evalf() == 3.
|
| 328 |
+
# the next test should return instantly
|
| 329 |
+
assert Sum(1/n,(n,1,2)).evalf() == 1.5
|
| 330 |
+
|
| 331 |
+
# issue 8219
|
| 332 |
+
assert Sum(E/factorial(n), (n, 0, oo)).evalf() == (E*E).evalf()
|
| 333 |
+
# issue 8254
|
| 334 |
+
assert Sum(2**n*n/factorial(n), (n, 0, oo)).evalf() == (2*E*E).evalf()
|
| 335 |
+
# issue 8411
|
| 336 |
+
s = Sum(1/x**2, (x, 100, oo))
|
| 337 |
+
assert s.n() == s.doit().n()
|
| 338 |
+
|
| 339 |
+
|
| 340 |
+
def test_evalf_divergent_series():
|
| 341 |
+
raises(ValueError, lambda: Sum(1/n, (n, 1, oo)).evalf())
|
| 342 |
+
raises(ValueError, lambda: Sum(n/(n**2 + 1), (n, 1, oo)).evalf())
|
| 343 |
+
raises(ValueError, lambda: Sum((-1)**n, (n, 1, oo)).evalf())
|
| 344 |
+
raises(ValueError, lambda: Sum((-1)**n, (n, 1, oo)).evalf())
|
| 345 |
+
raises(ValueError, lambda: Sum(n**2, (n, 1, oo)).evalf())
|
| 346 |
+
raises(ValueError, lambda: Sum(2**n, (n, 1, oo)).evalf())
|
| 347 |
+
raises(ValueError, lambda: Sum((-2)**n, (n, 1, oo)).evalf())
|
| 348 |
+
raises(ValueError, lambda: Sum((2*n + 3)/(3*n**2 + 4), (n, 0, oo)).evalf())
|
| 349 |
+
raises(ValueError, lambda: Sum((0.5*n**3)/(n**4 + 1), (n, 0, oo)).evalf())
|
| 350 |
+
|
| 351 |
+
|
| 352 |
+
def test_evalf_product():
|
| 353 |
+
assert Product(n, (n, 1, 10)).evalf() == 3628800.
|
| 354 |
+
assert comp(Product(1 - S.Half**2/n**2, (n, 1, oo)).n(5), 0.63662)
|
| 355 |
+
assert Product(n, (n, -1, 3)).evalf() == 0
|
| 356 |
+
|
| 357 |
+
|
| 358 |
+
def test_evalf_py_methods():
|
| 359 |
+
assert abs(float(pi + 1) - 4.1415926535897932) < 1e-10
|
| 360 |
+
assert abs(complex(pi + 1) - 4.1415926535897932) < 1e-10
|
| 361 |
+
assert abs(
|
| 362 |
+
complex(pi + E*I) - (3.1415926535897931 + 2.7182818284590451j)) < 1e-10
|
| 363 |
+
raises(TypeError, lambda: float(pi + x))
|
| 364 |
+
|
| 365 |
+
|
| 366 |
+
def test_evalf_power_subs_bugs():
|
| 367 |
+
assert (x**2).evalf(subs={x: 0}) == 0
|
| 368 |
+
assert sqrt(x).evalf(subs={x: 0}) == 0
|
| 369 |
+
assert (x**Rational(2, 3)).evalf(subs={x: 0}) == 0
|
| 370 |
+
assert (x**x).evalf(subs={x: 0}) == 1.0
|
| 371 |
+
assert (3**x).evalf(subs={x: 0}) == 1.0
|
| 372 |
+
assert exp(x).evalf(subs={x: 0}) == 1.0
|
| 373 |
+
assert ((2 + I)**x).evalf(subs={x: 0}) == 1.0
|
| 374 |
+
assert (0**x).evalf(subs={x: 0}) == 1.0
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
def test_evalf_arguments():
|
| 378 |
+
raises(TypeError, lambda: pi.evalf(method="garbage"))
|
| 379 |
+
|
| 380 |
+
|
| 381 |
+
def test_implemented_function_evalf():
|
| 382 |
+
from sympy.utilities.lambdify import implemented_function
|
| 383 |
+
f = Function('f')
|
| 384 |
+
f = implemented_function(f, lambda x: x + 1)
|
| 385 |
+
assert str(f(x)) == "f(x)"
|
| 386 |
+
assert str(f(2)) == "f(2)"
|
| 387 |
+
assert f(2).evalf() == 3.0
|
| 388 |
+
assert f(x).evalf() == f(x)
|
| 389 |
+
f = implemented_function(Function('sin'), lambda x: x + 1)
|
| 390 |
+
assert f(2).evalf() != sin(2)
|
| 391 |
+
del f._imp_ # XXX: due to caching _imp_ would influence all other tests
|
| 392 |
+
|
| 393 |
+
|
| 394 |
+
def test_evaluate_false():
|
| 395 |
+
for no in [0, False]:
|
| 396 |
+
assert Add(3, 2, evaluate=no).is_Add
|
| 397 |
+
assert Mul(3, 2, evaluate=no).is_Mul
|
| 398 |
+
assert Pow(3, 2, evaluate=no).is_Pow
|
| 399 |
+
assert Pow(y, 2, evaluate=True) - Pow(y, 2, evaluate=True) == 0
|
| 400 |
+
|
| 401 |
+
|
| 402 |
+
def test_evalf_relational():
|
| 403 |
+
assert Eq(x/5, y/10).evalf() == Eq(0.2*x, 0.1*y)
|
| 404 |
+
# if this first assertion fails it should be replaced with
|
| 405 |
+
# one that doesn't
|
| 406 |
+
assert unchanged(Eq, (3 - I)**2/2 + I, 0)
|
| 407 |
+
assert Eq((3 - I)**2/2 + I, 0).n() is S.false
|
| 408 |
+
assert nfloat(Eq((3 - I)**2 + I, 0)) == S.false
|
| 409 |
+
|
| 410 |
+
|
| 411 |
+
def test_issue_5486():
|
| 412 |
+
assert not cos(sqrt(0.5 + I)).n().is_Function
|
| 413 |
+
|
| 414 |
+
|
| 415 |
+
def test_issue_5486_bug():
|
| 416 |
+
from sympy.core.expr import Expr
|
| 417 |
+
from sympy.core.numbers import I
|
| 418 |
+
assert abs(Expr._from_mpmath(I._to_mpmath(15), 15) - I) < 1.0e-15
|
| 419 |
+
|
| 420 |
+
|
| 421 |
+
def test_bugs():
|
| 422 |
+
from sympy.functions.elementary.complexes import (polar_lift, re)
|
| 423 |
+
|
| 424 |
+
assert abs(re((1 + I)**2)) < 1e-15
|
| 425 |
+
|
| 426 |
+
# anything that evalf's to 0 will do in place of polar_lift
|
| 427 |
+
assert abs(polar_lift(0)).n() == 0
|
| 428 |
+
|
| 429 |
+
|
| 430 |
+
def test_subs():
|
| 431 |
+
assert NS('besseli(-x, y) - besseli(x, y)', subs={x: 3.5, y: 20.0}) == \
|
| 432 |
+
'-4.92535585957223e-10'
|
| 433 |
+
assert NS('Piecewise((x, x>0)) + Piecewise((1-x, x>0))', subs={x: 0.1}) == \
|
| 434 |
+
'1.00000000000000'
|
| 435 |
+
raises(TypeError, lambda: x.evalf(subs=(x, 1)))
|
| 436 |
+
|
| 437 |
+
|
| 438 |
+
def test_issue_4956_5204():
|
| 439 |
+
# issue 4956
|
| 440 |
+
v = S('''(-27*12**(1/3)*sqrt(31)*I +
|
| 441 |
+
27*2**(2/3)*3**(1/3)*sqrt(31)*I)/(-2511*2**(2/3)*3**(1/3) +
|
| 442 |
+
(29*18**(1/3) + 9*2**(1/3)*3**(2/3)*sqrt(31)*I +
|
| 443 |
+
87*2**(1/3)*3**(1/6)*I)**2)''')
|
| 444 |
+
assert NS(v, 1) == '0.e-118 - 0.e-118*I'
|
| 445 |
+
|
| 446 |
+
# issue 5204
|
| 447 |
+
v = S('''-(357587765856 + 18873261792*249**(1/2) + 56619785376*I*83**(1/2) +
|
| 448 |
+
108755765856*I*3**(1/2) + 41281887168*6**(1/3)*(1422 +
|
| 449 |
+
54*249**(1/2))**(1/3) - 1239810624*6**(1/3)*249**(1/2)*(1422 +
|
| 450 |
+
54*249**(1/2))**(1/3) - 3110400000*I*6**(1/3)*83**(1/2)*(1422 +
|
| 451 |
+
54*249**(1/2))**(1/3) + 13478400000*I*3**(1/2)*6**(1/3)*(1422 +
|
| 452 |
+
54*249**(1/2))**(1/3) + 1274950152*6**(2/3)*(1422 +
|
| 453 |
+
54*249**(1/2))**(2/3) + 32347944*6**(2/3)*249**(1/2)*(1422 +
|
| 454 |
+
54*249**(1/2))**(2/3) - 1758790152*I*3**(1/2)*6**(2/3)*(1422 +
|
| 455 |
+
54*249**(1/2))**(2/3) - 304403832*I*6**(2/3)*83**(1/2)*(1422 +
|
| 456 |
+
4*249**(1/2))**(2/3))/(175732658352 + (1106028 + 25596*249**(1/2) +
|
| 457 |
+
76788*I*83**(1/2))**2)''')
|
| 458 |
+
assert NS(v, 5) == '0.077284 + 1.1104*I'
|
| 459 |
+
assert NS(v, 1) == '0.08 + 1.*I'
|
| 460 |
+
|
| 461 |
+
|
| 462 |
+
def test_old_docstring():
|
| 463 |
+
a = (E + pi*I)*(E - pi*I)
|
| 464 |
+
assert NS(a) == '17.2586605000200'
|
| 465 |
+
assert a.n() == 17.25866050002001
|
| 466 |
+
|
| 467 |
+
|
| 468 |
+
def test_issue_4806():
|
| 469 |
+
assert integrate(atan(x)**2, (x, -1, 1)).evalf().round(1) == Float(0.5, 1)
|
| 470 |
+
assert atan(0, evaluate=False).n() == 0
|
| 471 |
+
|
| 472 |
+
|
| 473 |
+
def test_evalf_mul():
|
| 474 |
+
# SymPy should not try to expand this; it should be handled term-wise
|
| 475 |
+
# in evalf through mpmath
|
| 476 |
+
assert NS(product(1 + sqrt(n)*I, (n, 1, 500)), 1) == '5.e+567 + 2.e+568*I'
|
| 477 |
+
|
| 478 |
+
|
| 479 |
+
def test_scaled_zero():
|
| 480 |
+
a, b = (([0], 1, 100, 1), -1)
|
| 481 |
+
assert scaled_zero(100) == (a, b)
|
| 482 |
+
assert scaled_zero(a) == (0, 1, 100, 1)
|
| 483 |
+
a, b = (([1], 1, 100, 1), -1)
|
| 484 |
+
assert scaled_zero(100, -1) == (a, b)
|
| 485 |
+
assert scaled_zero(a) == (1, 1, 100, 1)
|
| 486 |
+
raises(ValueError, lambda: scaled_zero(scaled_zero(100)))
|
| 487 |
+
raises(ValueError, lambda: scaled_zero(100, 2))
|
| 488 |
+
raises(ValueError, lambda: scaled_zero(100, 0))
|
| 489 |
+
raises(ValueError, lambda: scaled_zero((1, 5, 1, 3)))
|
| 490 |
+
|
| 491 |
+
|
| 492 |
+
def test_chop_value():
|
| 493 |
+
for i in range(-27, 28):
|
| 494 |
+
assert (Pow(10, i)*2).n(chop=10**i) and not (Pow(10, i)).n(chop=10**i)
|
| 495 |
+
|
| 496 |
+
|
| 497 |
+
def test_infinities():
|
| 498 |
+
assert oo.evalf(chop=True) == inf
|
| 499 |
+
assert (-oo).evalf(chop=True) == ninf
|
| 500 |
+
|
| 501 |
+
|
| 502 |
+
def test_to_mpmath():
|
| 503 |
+
assert sqrt(3)._to_mpmath(20)._mpf_ == (0, int(908093), -19, 20)
|
| 504 |
+
assert S(3.2)._to_mpmath(20)._mpf_ == (0, int(838861), -18, 20)
|
| 505 |
+
|
| 506 |
+
|
| 507 |
+
def test_issue_6632_evalf():
|
| 508 |
+
add = (-100000*sqrt(2500000001) + 5000000001)
|
| 509 |
+
assert add.n() == 9.999999998e-11
|
| 510 |
+
assert (add*add).n() == 9.999999996e-21
|
| 511 |
+
|
| 512 |
+
|
| 513 |
+
def test_issue_4945():
|
| 514 |
+
from sympy.abc import H
|
| 515 |
+
assert (H/0).evalf(subs={H:1}) == zoo
|
| 516 |
+
|
| 517 |
+
|
| 518 |
+
def test_evalf_integral():
|
| 519 |
+
# test that workprec has to increase in order to get a result other than 0
|
| 520 |
+
eps = Rational(1, 1000000)
|
| 521 |
+
assert Integral(sin(x), (x, -pi, pi + eps)).n(2)._prec == 10
|
| 522 |
+
|
| 523 |
+
|
| 524 |
+
def test_issue_8821_highprec_from_str():
|
| 525 |
+
s = str(pi.evalf(128))
|
| 526 |
+
p = N(s)
|
| 527 |
+
assert Abs(sin(p)) < 1e-15
|
| 528 |
+
p = N(s, 64)
|
| 529 |
+
assert Abs(sin(p)) < 1e-64
|
| 530 |
+
|
| 531 |
+
|
| 532 |
+
def test_issue_8853():
|
| 533 |
+
p = Symbol('x', even=True, positive=True)
|
| 534 |
+
assert floor(-p - S.Half).is_even == False
|
| 535 |
+
assert floor(-p + S.Half).is_even == True
|
| 536 |
+
assert ceiling(p - S.Half).is_even == True
|
| 537 |
+
assert ceiling(p + S.Half).is_even == False
|
| 538 |
+
|
| 539 |
+
assert get_integer_part(S.Half, -1, {}, True) == (0, 0)
|
| 540 |
+
assert get_integer_part(S.Half, 1, {}, True) == (1, 0)
|
| 541 |
+
assert get_integer_part(Rational(-1, 2), -1, {}, True) == (-1, 0)
|
| 542 |
+
assert get_integer_part(Rational(-1, 2), 1, {}, True) == (0, 0)
|
| 543 |
+
|
| 544 |
+
|
| 545 |
+
def test_issue_17681():
|
| 546 |
+
class identity_func(Function):
|
| 547 |
+
|
| 548 |
+
def _eval_evalf(self, *args, **kwargs):
|
| 549 |
+
return self.args[0].evalf(*args, **kwargs)
|
| 550 |
+
|
| 551 |
+
assert floor(identity_func(S(0))) == 0
|
| 552 |
+
assert get_integer_part(S(0), 1, {}, True) == (0, 0)
|
| 553 |
+
|
| 554 |
+
|
| 555 |
+
def test_issue_9326():
|
| 556 |
+
from sympy.core.symbol import Dummy
|
| 557 |
+
d1 = Dummy('d')
|
| 558 |
+
d2 = Dummy('d')
|
| 559 |
+
e = d1 + d2
|
| 560 |
+
assert e.evalf(subs = {d1: 1, d2: 2}) == 3.0
|
| 561 |
+
|
| 562 |
+
|
| 563 |
+
def test_issue_10323():
|
| 564 |
+
assert ceiling(sqrt(2**30 + 1)) == 2**15 + 1
|
| 565 |
+
|
| 566 |
+
|
| 567 |
+
def test_AssocOp_Function():
|
| 568 |
+
# the first arg of Min is not comparable in the imaginary part
|
| 569 |
+
raises(ValueError, lambda: S('''
|
| 570 |
+
Min(-sqrt(3)*cos(pi/18)/6 + re(1/((-1/2 - sqrt(3)*I/2)*(1/6 +
|
| 571 |
+
sqrt(3)*I/18)**(1/3)))/3 + sin(pi/18)/2 + 2 + I*(-cos(pi/18)/2 -
|
| 572 |
+
sqrt(3)*sin(pi/18)/6 + im(1/((-1/2 - sqrt(3)*I/2)*(1/6 +
|
| 573 |
+
sqrt(3)*I/18)**(1/3)))/3), re(1/((-1/2 + sqrt(3)*I/2)*(1/6 +
|
| 574 |
+
sqrt(3)*I/18)**(1/3)))/3 - sqrt(3)*cos(pi/18)/6 - sin(pi/18)/2 + 2 +
|
| 575 |
+
I*(im(1/((-1/2 + sqrt(3)*I/2)*(1/6 + sqrt(3)*I/18)**(1/3)))/3 -
|
| 576 |
+
sqrt(3)*sin(pi/18)/6 + cos(pi/18)/2))'''))
|
| 577 |
+
# if that is changed so a non-comparable number remains as
|
| 578 |
+
# an arg, then the Min/Max instantiation needs to be changed
|
| 579 |
+
# to watch out for non-comparable args when making simplifications
|
| 580 |
+
# and the following test should be added instead (with e being
|
| 581 |
+
# the sympified expression above):
|
| 582 |
+
# raises(ValueError, lambda: e._eval_evalf(2))
|
| 583 |
+
|
| 584 |
+
|
| 585 |
+
def test_issue_10395():
|
| 586 |
+
eq = x*Max(0, y)
|
| 587 |
+
assert nfloat(eq) == eq
|
| 588 |
+
eq = x*Max(y, -1.1)
|
| 589 |
+
assert nfloat(eq) == eq
|
| 590 |
+
assert Max(y, 4).n() == Max(4.0, y)
|
| 591 |
+
|
| 592 |
+
|
| 593 |
+
def test_issue_13098():
|
| 594 |
+
assert floor(log(S('9.'+'9'*20), 10)) == 0
|
| 595 |
+
assert ceiling(log(S('9.'+'9'*20), 10)) == 1
|
| 596 |
+
assert floor(log(20 - S('9.'+'9'*20), 10)) == 1
|
| 597 |
+
assert ceiling(log(20 - S('9.'+'9'*20), 10)) == 2
|
| 598 |
+
|
| 599 |
+
|
| 600 |
+
def test_issue_14601():
|
| 601 |
+
e = 5*x*y/2 - y*(35*(x**3)/2 - 15*x/2)
|
| 602 |
+
subst = {x:0.0, y:0.0}
|
| 603 |
+
e2 = e.evalf(subs=subst)
|
| 604 |
+
assert float(e2) == 0.0
|
| 605 |
+
assert float((x + x*(x**2 + x)).evalf(subs={x: 0.0})) == 0.0
|
| 606 |
+
|
| 607 |
+
|
| 608 |
+
def test_issue_11151():
|
| 609 |
+
z = S.Zero
|
| 610 |
+
e = Sum(z, (x, 1, 2))
|
| 611 |
+
assert e != z # it shouldn't evaluate
|
| 612 |
+
# when it does evaluate, this is what it should give
|
| 613 |
+
assert evalf(e, 15, {}) == \
|
| 614 |
+
evalf(z, 15, {}) == (None, None, 15, None)
|
| 615 |
+
# so this shouldn't fail
|
| 616 |
+
assert (e/2).n() == 0
|
| 617 |
+
# this was where the issue appeared
|
| 618 |
+
expr0 = Sum(x**2 + x, (x, 1, 2))
|
| 619 |
+
expr1 = Sum(0, (x, 1, 2))
|
| 620 |
+
expr2 = expr1/expr0
|
| 621 |
+
assert simplify(factor(expr2) - expr2) == 0
|
| 622 |
+
|
| 623 |
+
|
| 624 |
+
def test_issue_13425():
|
| 625 |
+
assert N('2**.5', 30) == N('sqrt(2)', 30)
|
| 626 |
+
assert N('x - x', 30) == 0
|
| 627 |
+
assert abs((N('pi*.1', 22)*10 - pi).n()) < 1e-22
|
| 628 |
+
|
| 629 |
+
|
| 630 |
+
def test_issue_17421():
|
| 631 |
+
assert N(acos(-I + acosh(cosh(cosh(1) + I)))) == 1.0*I
|
| 632 |
+
|
| 633 |
+
|
| 634 |
+
def test_issue_20291():
|
| 635 |
+
from sympy.sets import EmptySet, Reals
|
| 636 |
+
from sympy.sets.sets import (Complement, FiniteSet, Intersection)
|
| 637 |
+
a = Symbol('a')
|
| 638 |
+
b = Symbol('b')
|
| 639 |
+
A = FiniteSet(a, b)
|
| 640 |
+
assert A.evalf(subs={a: 1, b: 2}) == FiniteSet(1.0, 2.0)
|
| 641 |
+
B = FiniteSet(a-b, 1)
|
| 642 |
+
assert B.evalf(subs={a: 1, b: 2}) == FiniteSet(-1.0, 1.0)
|
| 643 |
+
|
| 644 |
+
sol = Complement(Intersection(FiniteSet(-b/2 - sqrt(b**2-4*pi)/2), Reals), FiniteSet(0))
|
| 645 |
+
assert sol.evalf(subs={b: 1}) == EmptySet
|
| 646 |
+
|
| 647 |
+
|
| 648 |
+
def test_evalf_with_zoo():
|
| 649 |
+
assert (1/x).evalf(subs={x: 0}) == zoo # issue 8242
|
| 650 |
+
assert (-1/x).evalf(subs={x: 0}) == zoo # PR 16150
|
| 651 |
+
assert (0 ** x).evalf(subs={x: -1}) == zoo # PR 16150
|
| 652 |
+
assert (0 ** x).evalf(subs={x: -1 + I}) == nan
|
| 653 |
+
assert Mul(2, Pow(0, -1, evaluate=False), evaluate=False).evalf() == zoo # issue 21147
|
| 654 |
+
assert Mul(x, 1/x, evaluate=False).evalf(subs={x: 0}) == Mul(x, 1/x, evaluate=False).subs(x, 0) == nan
|
| 655 |
+
assert Mul(1/x, 1/x, evaluate=False).evalf(subs={x: 0}) == zoo
|
| 656 |
+
assert Mul(1/x, Abs(1/x), evaluate=False).evalf(subs={x: 0}) == zoo
|
| 657 |
+
assert Abs(zoo, evaluate=False).evalf() == oo
|
| 658 |
+
assert re(zoo, evaluate=False).evalf() == nan
|
| 659 |
+
assert im(zoo, evaluate=False).evalf() == nan
|
| 660 |
+
assert Add(zoo, zoo, evaluate=False).evalf() == nan
|
| 661 |
+
assert Add(oo, zoo, evaluate=False).evalf() == nan
|
| 662 |
+
assert Pow(zoo, -1, evaluate=False).evalf() == 0
|
| 663 |
+
assert Pow(zoo, Rational(-1, 3), evaluate=False).evalf() == 0
|
| 664 |
+
assert Pow(zoo, Rational(1, 3), evaluate=False).evalf() == zoo
|
| 665 |
+
assert Pow(zoo, S.Half, evaluate=False).evalf() == zoo
|
| 666 |
+
assert Pow(zoo, 2, evaluate=False).evalf() == zoo
|
| 667 |
+
assert Pow(0, zoo, evaluate=False).evalf() == nan
|
| 668 |
+
assert log(zoo, evaluate=False).evalf() == zoo
|
| 669 |
+
assert zoo.evalf(chop=True) == zoo
|
| 670 |
+
assert x.evalf(subs={x: zoo}) == zoo
|
| 671 |
+
|
| 672 |
+
|
| 673 |
+
def test_evalf_with_bounded_error():
|
| 674 |
+
cases = [
|
| 675 |
+
# zero
|
| 676 |
+
(Rational(0), None, 1),
|
| 677 |
+
# zero im part
|
| 678 |
+
(pi, None, 10),
|
| 679 |
+
# zero real part
|
| 680 |
+
(pi*I, None, 10),
|
| 681 |
+
# re and im nonzero
|
| 682 |
+
(2-3*I, None, 5),
|
| 683 |
+
# similar tests again, but using eps instead of m
|
| 684 |
+
(Rational(0), Rational(1, 2), None),
|
| 685 |
+
(pi, Rational(1, 1000), None),
|
| 686 |
+
(pi * I, Rational(1, 1000), None),
|
| 687 |
+
(2 - 3 * I, Rational(1, 1000), None),
|
| 688 |
+
# very large eps
|
| 689 |
+
(2 - 3 * I, Rational(1000), None),
|
| 690 |
+
# case where x already small, hence some cancellation in p = m + n - 1
|
| 691 |
+
(Rational(1234, 10**8), Rational(1, 10**12), None),
|
| 692 |
+
]
|
| 693 |
+
for x0, eps, m in cases:
|
| 694 |
+
a, b, _, _ = evalf(x0, 53, {})
|
| 695 |
+
c, d, _, _ = _evalf_with_bounded_error(x0, eps, m)
|
| 696 |
+
if eps is None:
|
| 697 |
+
eps = 2**(-m)
|
| 698 |
+
z = make_mpc((a or fzero, b or fzero))
|
| 699 |
+
w = make_mpc((c or fzero, d or fzero))
|
| 700 |
+
assert abs(w - z) < eps
|
| 701 |
+
|
| 702 |
+
# eps must be positive
|
| 703 |
+
raises(ValueError, lambda: _evalf_with_bounded_error(pi, Rational(0)))
|
| 704 |
+
raises(ValueError, lambda: _evalf_with_bounded_error(pi, -pi))
|
| 705 |
+
raises(ValueError, lambda: _evalf_with_bounded_error(pi, I))
|
| 706 |
+
|
| 707 |
+
|
| 708 |
+
def test_issue_22849():
|
| 709 |
+
a = -8 + 3 * sqrt(3)
|
| 710 |
+
x = AlgebraicNumber(a)
|
| 711 |
+
assert evalf(a, 1, {}) == evalf(x, 1, {})
|
| 712 |
+
|
| 713 |
+
|
| 714 |
+
def test_evalf_real_alg_num():
|
| 715 |
+
# This test demonstrates why the entry for `AlgebraicNumber` in
|
| 716 |
+
# `sympy.core.evalf._create_evalf_table()` has to use `x.to_root()`,
|
| 717 |
+
# instead of `x.as_expr()`. If the latter is used, then `z` will be
|
| 718 |
+
# a complex number with `0.e-20` for imaginary part, even though `a5`
|
| 719 |
+
# is a real number.
|
| 720 |
+
zeta = Symbol('zeta')
|
| 721 |
+
a5 = AlgebraicNumber(CRootOf(cyclotomic_poly(5), -1), [-1, -1, 0, 0], alias=zeta)
|
| 722 |
+
z = a5.evalf()
|
| 723 |
+
assert isinstance(z, Float)
|
| 724 |
+
assert not hasattr(z, '_mpc_')
|
| 725 |
+
assert hasattr(z, '_mpf_')
|
| 726 |
+
|
| 727 |
+
|
| 728 |
+
def test_issue_20733():
|
| 729 |
+
expr = 1/((x - 9)*(x - 8)*(x - 7)*(x - 4)**2*(x - 3)**3*(x - 2))
|
| 730 |
+
assert str(expr.evalf(1, subs={x:1})) == '-4.e-5'
|
| 731 |
+
assert str(expr.evalf(2, subs={x:1})) == '-4.1e-5'
|
| 732 |
+
assert str(expr.evalf(11, subs={x:1})) == '-4.1335978836e-5'
|
| 733 |
+
assert str(expr.evalf(20, subs={x:1})) == '-0.000041335978835978835979'
|
| 734 |
+
|
| 735 |
+
expr = Mul(*((x - i) for i in range(2, 1000)))
|
| 736 |
+
assert srepr(expr.evalf(2, subs={x: 1})) == "Float('4.0271e+2561', precision=10)"
|
| 737 |
+
assert srepr(expr.evalf(10, subs={x: 1})) == "Float('4.02790050126e+2561', precision=37)"
|
| 738 |
+
assert srepr(expr.evalf(53, subs={x: 1})) == "Float('4.0279005012722099453824067459760158730668154575647110393e+2561', precision=179)"
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_expand.py
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.expr import unchanged
|
| 2 |
+
from sympy.core.mul import Mul
|
| 3 |
+
from sympy.core.numbers import (I, Rational as R, pi)
|
| 4 |
+
from sympy.core.power import Pow
|
| 5 |
+
from sympy.core.singleton import S
|
| 6 |
+
from sympy.core.symbol import Symbol
|
| 7 |
+
from sympy.functions.combinatorial.factorials import factorial
|
| 8 |
+
from sympy.functions.elementary.exponential import (exp, log)
|
| 9 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 10 |
+
from sympy.functions.elementary.trigonometric import (cos, sin)
|
| 11 |
+
from sympy.series.order import O
|
| 12 |
+
from sympy.simplify.radsimp import expand_numer
|
| 13 |
+
from sympy.core.function import (expand, expand_multinomial,
|
| 14 |
+
expand_power_base, expand_log)
|
| 15 |
+
|
| 16 |
+
from sympy.testing.pytest import raises
|
| 17 |
+
from sympy.core.random import verify_numerically
|
| 18 |
+
|
| 19 |
+
from sympy.abc import x, y, z
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def test_expand_no_log():
|
| 23 |
+
assert (
|
| 24 |
+
(1 + log(x**4))**2).expand(log=False) == 1 + 2*log(x**4) + log(x**4)**2
|
| 25 |
+
assert ((1 + log(x**4))*(1 + log(x**3))).expand(
|
| 26 |
+
log=False) == 1 + log(x**4) + log(x**3) + log(x**4)*log(x**3)
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def test_expand_no_multinomial():
|
| 30 |
+
assert ((1 + x)*(1 + (1 + x)**4)).expand(multinomial=False) == \
|
| 31 |
+
1 + x + (1 + x)**4 + x*(1 + x)**4
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def test_expand_negative_integer_powers():
|
| 35 |
+
expr = (x + y)**(-2)
|
| 36 |
+
assert expr.expand() == 1 / (2*x*y + x**2 + y**2)
|
| 37 |
+
assert expr.expand(multinomial=False) == (x + y)**(-2)
|
| 38 |
+
expr = (x + y)**(-3)
|
| 39 |
+
assert expr.expand() == 1 / (3*x*x*y + 3*x*y*y + x**3 + y**3)
|
| 40 |
+
assert expr.expand(multinomial=False) == (x + y)**(-3)
|
| 41 |
+
expr = (x + y)**(2) * (x + y)**(-4)
|
| 42 |
+
assert expr.expand() == 1 / (2*x*y + x**2 + y**2)
|
| 43 |
+
assert expr.expand(multinomial=False) == (x + y)**(-2)
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def test_expand_non_commutative():
|
| 47 |
+
A = Symbol('A', commutative=False)
|
| 48 |
+
B = Symbol('B', commutative=False)
|
| 49 |
+
C = Symbol('C', commutative=False)
|
| 50 |
+
a = Symbol('a')
|
| 51 |
+
b = Symbol('b')
|
| 52 |
+
i = Symbol('i', integer=True)
|
| 53 |
+
n = Symbol('n', negative=True)
|
| 54 |
+
m = Symbol('m', negative=True)
|
| 55 |
+
p = Symbol('p', polar=True)
|
| 56 |
+
np = Symbol('p', polar=False)
|
| 57 |
+
|
| 58 |
+
assert (C*(A + B)).expand() == C*A + C*B
|
| 59 |
+
assert (C*(A + B)).expand() != A*C + B*C
|
| 60 |
+
assert ((A + B)**2).expand() == A**2 + A*B + B*A + B**2
|
| 61 |
+
assert ((A + B)**3).expand() == (A**2*B + B**2*A + A*B**2 + B*A**2 +
|
| 62 |
+
A**3 + B**3 + A*B*A + B*A*B)
|
| 63 |
+
# issue 6219
|
| 64 |
+
assert ((a*A*B*A**-1)**2).expand() == a**2*A*B**2/A
|
| 65 |
+
# Note that (a*A*B*A**-1)**2 is automatically converted to a**2*(A*B*A**-1)**2
|
| 66 |
+
assert ((a*A*B*A**-1)**2).expand(deep=False) == a**2*(A*B*A**-1)**2
|
| 67 |
+
assert ((a*A*B*A**-1)**2).expand() == a**2*(A*B**2*A**-1)
|
| 68 |
+
assert ((a*A*B*A**-1)**2).expand(force=True) == a**2*A*B**2*A**(-1)
|
| 69 |
+
assert ((a*A*B)**2).expand() == a**2*A*B*A*B
|
| 70 |
+
assert ((a*A)**2).expand() == a**2*A**2
|
| 71 |
+
assert ((a*A*B)**i).expand() == a**i*(A*B)**i
|
| 72 |
+
assert ((a*A*(B*(A*B/A)**2))**i).expand() == a**i*(A*B*A*B**2/A)**i
|
| 73 |
+
# issue 6558
|
| 74 |
+
assert (A*B*(A*B)**-1).expand() == 1
|
| 75 |
+
assert ((a*A)**i).expand() == a**i*A**i
|
| 76 |
+
assert ((a*A*B*A**-1)**3).expand() == a**3*A*B**3/A
|
| 77 |
+
assert ((a*A*B*A*B/A)**3).expand() == \
|
| 78 |
+
a**3*A*B*(A*B**2)*(A*B**2)*A*B*A**(-1)
|
| 79 |
+
assert ((a*A*B*A*B/A)**-2).expand() == \
|
| 80 |
+
A*B**-1*A**-1*B**-2*A**-1*B**-1*A**-1/a**2
|
| 81 |
+
assert ((a*b*A*B*A**-1)**i).expand() == a**i*b**i*(A*B/A)**i
|
| 82 |
+
assert ((a*(a*b)**i)**i).expand() == a**i*a**(i**2)*b**(i**2)
|
| 83 |
+
e = Pow(Mul(a, 1/a, A, B, evaluate=False), S(2), evaluate=False)
|
| 84 |
+
assert e.expand() == A*B*A*B
|
| 85 |
+
assert sqrt(a*(A*b)**i).expand() == sqrt(a*b**i*A**i)
|
| 86 |
+
assert (sqrt(-a)**a).expand() == sqrt(-a)**a
|
| 87 |
+
assert expand((-2*n)**(i/3)) == 2**(i/3)*(-n)**(i/3)
|
| 88 |
+
assert expand((-2*n*m)**(i/a)) == (-2)**(i/a)*(-n)**(i/a)*(-m)**(i/a)
|
| 89 |
+
assert expand((-2*a*p)**b) == 2**b*p**b*(-a)**b
|
| 90 |
+
assert expand((-2*a*np)**b) == 2**b*(-a*np)**b
|
| 91 |
+
assert expand(sqrt(A*B)) == sqrt(A*B)
|
| 92 |
+
assert expand(sqrt(-2*a*b)) == sqrt(2)*sqrt(-a*b)
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
def test_expand_radicals():
|
| 96 |
+
a = (x + y)**R(1, 2)
|
| 97 |
+
|
| 98 |
+
assert (a**1).expand() == a
|
| 99 |
+
assert (a**3).expand() == x*a + y*a
|
| 100 |
+
assert (a**5).expand() == x**2*a + 2*x*y*a + y**2*a
|
| 101 |
+
|
| 102 |
+
assert (1/a**1).expand() == 1/a
|
| 103 |
+
assert (1/a**3).expand() == 1/(x*a + y*a)
|
| 104 |
+
assert (1/a**5).expand() == 1/(x**2*a + 2*x*y*a + y**2*a)
|
| 105 |
+
|
| 106 |
+
a = (x + y)**R(1, 3)
|
| 107 |
+
|
| 108 |
+
assert (a**1).expand() == a
|
| 109 |
+
assert (a**2).expand() == a**2
|
| 110 |
+
assert (a**4).expand() == x*a + y*a
|
| 111 |
+
assert (a**5).expand() == x*a**2 + y*a**2
|
| 112 |
+
assert (a**7).expand() == x**2*a + 2*x*y*a + y**2*a
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def test_expand_modulus():
|
| 116 |
+
assert ((x + y)**11).expand(modulus=11) == x**11 + y**11
|
| 117 |
+
assert ((x + sqrt(2)*y)**11).expand(modulus=11) == x**11 + 10*sqrt(2)*y**11
|
| 118 |
+
assert (x + y/2).expand(modulus=1) == y/2
|
| 119 |
+
|
| 120 |
+
raises(ValueError, lambda: ((x + y)**11).expand(modulus=0))
|
| 121 |
+
raises(ValueError, lambda: ((x + y)**11).expand(modulus=x))
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def test_issue_5743():
|
| 125 |
+
assert (x*sqrt(
|
| 126 |
+
x + y)*(1 + sqrt(x + y))).expand() == x**2 + x*y + x*sqrt(x + y)
|
| 127 |
+
assert (x*sqrt(
|
| 128 |
+
x + y)*(1 + x*sqrt(x + y))).expand() == x**3 + x**2*y + x*sqrt(x + y)
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
def test_expand_frac():
|
| 132 |
+
assert expand((x + y)*y/x/(x + 1), frac=True) == \
|
| 133 |
+
(x*y + y**2)/(x**2 + x)
|
| 134 |
+
assert expand((x + y)*y/x/(x + 1), numer=True) == \
|
| 135 |
+
(x*y + y**2)/(x*(x + 1))
|
| 136 |
+
assert expand((x + y)*y/x/(x + 1), denom=True) == \
|
| 137 |
+
y*(x + y)/(x**2 + x)
|
| 138 |
+
eq = (x + 1)**2/y
|
| 139 |
+
assert expand_numer(eq, multinomial=False) == eq
|
| 140 |
+
# issue 26329
|
| 141 |
+
eq = (exp(x*z) - exp(y*z))/exp(z*(x + y))
|
| 142 |
+
ans = exp(-y*z) - exp(-x*z)
|
| 143 |
+
assert eq.expand(numer=True) != ans
|
| 144 |
+
assert eq.expand(numer=True, exact=True) == ans
|
| 145 |
+
assert expand_numer(eq) != ans
|
| 146 |
+
assert expand_numer(eq, exact=True) == ans
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
def test_issue_6121():
|
| 150 |
+
eq = -I*exp(-3*I*pi/4)/(4*pi**(S(3)/2)*sqrt(x))
|
| 151 |
+
assert eq.expand(complex=True) # does not give oo recursion
|
| 152 |
+
eq = -I*exp(-3*I*pi/4)/(4*pi**(R(3, 2))*sqrt(x))
|
| 153 |
+
assert eq.expand(complex=True) # does not give oo recursion
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
def test_expand_power_base():
|
| 157 |
+
assert expand_power_base((x*y*z)**4) == x**4*y**4*z**4
|
| 158 |
+
assert expand_power_base((x*y*z)**x).is_Pow
|
| 159 |
+
assert expand_power_base((x*y*z)**x, force=True) == x**x*y**x*z**x
|
| 160 |
+
assert expand_power_base((x*(y*z)**2)**3) == x**3*y**6*z**6
|
| 161 |
+
|
| 162 |
+
assert expand_power_base((sin((x*y)**2)*y)**z).is_Pow
|
| 163 |
+
assert expand_power_base(
|
| 164 |
+
(sin((x*y)**2)*y)**z, force=True) == sin((x*y)**2)**z*y**z
|
| 165 |
+
assert expand_power_base(
|
| 166 |
+
(sin((x*y)**2)*y)**z, deep=True) == (sin(x**2*y**2)*y)**z
|
| 167 |
+
|
| 168 |
+
assert expand_power_base(exp(x)**2) == exp(2*x)
|
| 169 |
+
assert expand_power_base((exp(x)*exp(y))**2) == exp(2*x)*exp(2*y)
|
| 170 |
+
|
| 171 |
+
assert expand_power_base(
|
| 172 |
+
(exp((x*y)**z)*exp(y))**2) == exp(2*(x*y)**z)*exp(2*y)
|
| 173 |
+
assert expand_power_base((exp((x*y)**z)*exp(
|
| 174 |
+
y))**2, deep=True, force=True) == exp(2*x**z*y**z)*exp(2*y)
|
| 175 |
+
|
| 176 |
+
assert expand_power_base((exp(x)*exp(y))**z).is_Pow
|
| 177 |
+
assert expand_power_base(
|
| 178 |
+
(exp(x)*exp(y))**z, force=True) == exp(x)**z*exp(y)**z
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
def test_expand_arit():
|
| 182 |
+
a = Symbol("a")
|
| 183 |
+
b = Symbol("b", positive=True)
|
| 184 |
+
c = Symbol("c")
|
| 185 |
+
|
| 186 |
+
p = R(5)
|
| 187 |
+
e = (a + b)*c
|
| 188 |
+
assert e == c*(a + b)
|
| 189 |
+
assert (e.expand() - a*c - b*c) == R(0)
|
| 190 |
+
e = (a + b)*(a + b)
|
| 191 |
+
assert e == (a + b)**2
|
| 192 |
+
assert e.expand() == 2*a*b + a**2 + b**2
|
| 193 |
+
e = (a + b)*(a + b)**R(2)
|
| 194 |
+
assert e == (a + b)**3
|
| 195 |
+
assert e.expand() == 3*b*a**2 + 3*a*b**2 + a**3 + b**3
|
| 196 |
+
assert e.expand() == 3*b*a**2 + 3*a*b**2 + a**3 + b**3
|
| 197 |
+
e = (a + b)*(a + c)*(b + c)
|
| 198 |
+
assert e == (a + c)*(a + b)*(b + c)
|
| 199 |
+
assert e.expand() == 2*a*b*c + b*a**2 + c*a**2 + b*c**2 + a*c**2 + c*b**2 + a*b**2
|
| 200 |
+
e = (a + R(1))**p
|
| 201 |
+
assert e == (1 + a)**5
|
| 202 |
+
assert e.expand() == 1 + 5*a + 10*a**2 + 10*a**3 + 5*a**4 + a**5
|
| 203 |
+
e = (a + b + c)*(a + c + p)
|
| 204 |
+
assert e == (5 + a + c)*(a + b + c)
|
| 205 |
+
assert e.expand() == 5*a + 5*b + 5*c + 2*a*c + b*c + a*b + a**2 + c**2
|
| 206 |
+
x = Symbol("x")
|
| 207 |
+
s = exp(x*x) - 1
|
| 208 |
+
e = s.nseries(x, 0, 6)/x**2
|
| 209 |
+
assert e.expand() == 1 + x**2/2 + O(x**4)
|
| 210 |
+
|
| 211 |
+
e = (x*(y + z))**(x*(y + z))*(x + y)
|
| 212 |
+
assert e.expand(power_exp=False, power_base=False) == x*(x*y + x*
|
| 213 |
+
z)**(x*y + x*z) + y*(x*y + x*z)**(x*y + x*z)
|
| 214 |
+
assert e.expand(power_exp=False, power_base=False, deep=False) == x* \
|
| 215 |
+
(x*(y + z))**(x*(y + z)) + y*(x*(y + z))**(x*(y + z))
|
| 216 |
+
e = x * (x + (y + 1)**2)
|
| 217 |
+
assert e.expand(deep=False) == x**2 + x*(y + 1)**2
|
| 218 |
+
e = (x*(y + z))**z
|
| 219 |
+
assert e.expand(power_base=True, mul=True, deep=True) in [x**z*(y +
|
| 220 |
+
z)**z, (x*y + x*z)**z]
|
| 221 |
+
assert ((2*y)**z).expand() == 2**z*y**z
|
| 222 |
+
p = Symbol('p', positive=True)
|
| 223 |
+
assert sqrt(-x).expand().is_Pow
|
| 224 |
+
assert sqrt(-x).expand(force=True) == I*sqrt(x)
|
| 225 |
+
assert ((2*y*p)**z).expand() == 2**z*p**z*y**z
|
| 226 |
+
assert ((2*y*p*x)**z).expand() == 2**z*p**z*(x*y)**z
|
| 227 |
+
assert ((2*y*p*x)**z).expand(force=True) == 2**z*p**z*x**z*y**z
|
| 228 |
+
assert ((2*y*p*-pi)**z).expand() == 2**z*pi**z*p**z*(-y)**z
|
| 229 |
+
assert ((2*y*p*-pi*x)**z).expand() == 2**z*pi**z*p**z*(-x*y)**z
|
| 230 |
+
n = Symbol('n', negative=True)
|
| 231 |
+
m = Symbol('m', negative=True)
|
| 232 |
+
assert ((-2*x*y*n)**z).expand() == 2**z*(-n)**z*(x*y)**z
|
| 233 |
+
assert ((-2*x*y*n*m)**z).expand() == 2**z*(-m)**z*(-n)**z*(-x*y)**z
|
| 234 |
+
# issue 5482
|
| 235 |
+
assert sqrt(-2*x*n) == sqrt(2)*sqrt(-n)*sqrt(x)
|
| 236 |
+
# issue 5605 (2)
|
| 237 |
+
assert (cos(x + y)**2).expand(trig=True) in [
|
| 238 |
+
(-sin(x)*sin(y) + cos(x)*cos(y))**2,
|
| 239 |
+
sin(x)**2*sin(y)**2 - 2*sin(x)*sin(y)*cos(x)*cos(y) + cos(x)**2*cos(y)**2
|
| 240 |
+
]
|
| 241 |
+
|
| 242 |
+
# Check that this isn't too slow
|
| 243 |
+
x = Symbol('x')
|
| 244 |
+
W = 1
|
| 245 |
+
for i in range(1, 21):
|
| 246 |
+
W = W * (x - i)
|
| 247 |
+
W = W.expand()
|
| 248 |
+
assert W.has(-1672280820*x**15)
|
| 249 |
+
|
| 250 |
+
def test_expand_mul():
|
| 251 |
+
# part of issue 20597
|
| 252 |
+
e = Mul(2, 3, evaluate=False)
|
| 253 |
+
assert e.expand() == 6
|
| 254 |
+
|
| 255 |
+
e = Mul(2, 3, 1/x, evaluate=False)
|
| 256 |
+
assert e.expand() == 6/x
|
| 257 |
+
e = Mul(2, R(1, 3), evaluate=False)
|
| 258 |
+
assert e.expand() == R(2, 3)
|
| 259 |
+
|
| 260 |
+
def test_power_expand():
|
| 261 |
+
"""Test for Pow.expand()"""
|
| 262 |
+
a = Symbol('a')
|
| 263 |
+
b = Symbol('b')
|
| 264 |
+
p = (a + b)**2
|
| 265 |
+
assert p.expand() == a**2 + b**2 + 2*a*b
|
| 266 |
+
|
| 267 |
+
p = (1 + 2*(1 + a))**2
|
| 268 |
+
assert p.expand() == 9 + 4*(a**2) + 12*a
|
| 269 |
+
|
| 270 |
+
p = 2**(a + b)
|
| 271 |
+
assert p.expand() == 2**a*2**b
|
| 272 |
+
|
| 273 |
+
A = Symbol('A', commutative=False)
|
| 274 |
+
B = Symbol('B', commutative=False)
|
| 275 |
+
assert (2**(A + B)).expand() == 2**(A + B)
|
| 276 |
+
assert (A**(a + b)).expand() != A**(a + b)
|
| 277 |
+
|
| 278 |
+
|
| 279 |
+
def test_issues_5919_6830():
|
| 280 |
+
# issue 5919
|
| 281 |
+
n = -1 + 1/x
|
| 282 |
+
z = n/x/(-n)**2 - 1/n/x
|
| 283 |
+
assert expand(z) == 1/(x**2 - 2*x + 1) - 1/(x - 2 + 1/x) - 1/(-x + 1)
|
| 284 |
+
|
| 285 |
+
# issue 6830
|
| 286 |
+
p = (1 + x)**2
|
| 287 |
+
assert expand_multinomial((1 + x*p)**2) == (
|
| 288 |
+
x**2*(x**4 + 4*x**3 + 6*x**2 + 4*x + 1) + 2*x*(x**2 + 2*x + 1) + 1)
|
| 289 |
+
assert expand_multinomial((1 + (y + x)*p)**2) == (
|
| 290 |
+
2*((x + y)*(x**2 + 2*x + 1)) + (x**2 + 2*x*y + y**2)*
|
| 291 |
+
(x**4 + 4*x**3 + 6*x**2 + 4*x + 1) + 1)
|
| 292 |
+
A = Symbol('A', commutative=False)
|
| 293 |
+
p = (1 + A)**2
|
| 294 |
+
assert expand_multinomial((1 + x*p)**2) == (
|
| 295 |
+
x**2*(1 + 4*A + 6*A**2 + 4*A**3 + A**4) + 2*x*(1 + 2*A + A**2) + 1)
|
| 296 |
+
assert expand_multinomial((1 + (y + x)*p)**2) == (
|
| 297 |
+
(x + y)*(1 + 2*A + A**2)*2 + (x**2 + 2*x*y + y**2)*
|
| 298 |
+
(1 + 4*A + 6*A**2 + 4*A**3 + A**4) + 1)
|
| 299 |
+
assert expand_multinomial((1 + (y + x)*p)**3) == (
|
| 300 |
+
(x + y)*(1 + 2*A + A**2)*3 + (x**2 + 2*x*y + y**2)*(1 + 4*A +
|
| 301 |
+
6*A**2 + 4*A**3 + A**4)*3 + (x**3 + 3*x**2*y + 3*x*y**2 + y**3)*(1 + 6*A
|
| 302 |
+
+ 15*A**2 + 20*A**3 + 15*A**4 + 6*A**5 + A**6) + 1)
|
| 303 |
+
# unevaluate powers
|
| 304 |
+
eq = (Pow((x + 1)*((A + 1)**2), 2, evaluate=False))
|
| 305 |
+
# - in this case the base is not an Add so no further
|
| 306 |
+
# expansion is done
|
| 307 |
+
assert expand_multinomial(eq) == \
|
| 308 |
+
(x**2 + 2*x + 1)*(1 + 4*A + 6*A**2 + 4*A**3 + A**4)
|
| 309 |
+
# - but here, the expanded base *is* an Add so it gets expanded
|
| 310 |
+
eq = (Pow(((A + 1)**2), 2, evaluate=False))
|
| 311 |
+
assert expand_multinomial(eq) == 1 + 4*A + 6*A**2 + 4*A**3 + A**4
|
| 312 |
+
|
| 313 |
+
# coverage
|
| 314 |
+
def ok(a, b, n):
|
| 315 |
+
e = (a + I*b)**n
|
| 316 |
+
return verify_numerically(e, expand_multinomial(e))
|
| 317 |
+
|
| 318 |
+
for a in [2, S.Half]:
|
| 319 |
+
for b in [3, R(1, 3)]:
|
| 320 |
+
for n in range(2, 6):
|
| 321 |
+
assert ok(a, b, n)
|
| 322 |
+
|
| 323 |
+
assert expand_multinomial((x + 1 + O(z))**2) == \
|
| 324 |
+
1 + 2*x + x**2 + O(z)
|
| 325 |
+
assert expand_multinomial((x + 1 + O(z))**3) == \
|
| 326 |
+
1 + 3*x + 3*x**2 + x**3 + O(z)
|
| 327 |
+
|
| 328 |
+
assert expand_multinomial(3**(x + y + 3)) == 27*3**(x + y)
|
| 329 |
+
|
| 330 |
+
def test_expand_log():
|
| 331 |
+
t = Symbol('t', positive=True)
|
| 332 |
+
# after first expansion, -2*log(2) + log(4); then 0 after second
|
| 333 |
+
assert expand(log(t**2) - log(t**2/4) - 2*log(2)) == 0
|
| 334 |
+
assert expand_log(log(7*6)/log(6)) == 1 + log(7)/log(6)
|
| 335 |
+
b = factorial(10)
|
| 336 |
+
assert expand_log(log(7*b**4)/log(b)
|
| 337 |
+
) == 4 + log(7)/log(b)
|
| 338 |
+
|
| 339 |
+
|
| 340 |
+
def test_issue_23952():
|
| 341 |
+
assert (x**(y + z)).expand(force=True) == x**y*x**z
|
| 342 |
+
one = Symbol('1', integer=True, prime=True, odd=True, positive=True)
|
| 343 |
+
two = Symbol('2', integer=True, prime=True, even=True)
|
| 344 |
+
e = two - one
|
| 345 |
+
for b in (0, x):
|
| 346 |
+
# 0**e = 0, 0**-e = zoo; but if expanded then nan
|
| 347 |
+
assert unchanged(Pow, b, e) # power_exp
|
| 348 |
+
assert unchanged(Pow, b, -e) # power_exp
|
| 349 |
+
assert unchanged(Pow, b, y - x) # power_exp
|
| 350 |
+
assert unchanged(Pow, b, 3 - x) # multinomial
|
| 351 |
+
assert (b**e).expand().is_Pow # power_exp
|
| 352 |
+
assert (b**-e).expand().is_Pow # power_exp
|
| 353 |
+
assert (b**(y - x)).expand().is_Pow # power_exp
|
| 354 |
+
assert (b**(3 - x)).expand().is_Pow # multinomial
|
| 355 |
+
nn1 = Symbol('nn1', nonnegative=True)
|
| 356 |
+
nn2 = Symbol('nn2', nonnegative=True)
|
| 357 |
+
nn3 = Symbol('nn3', nonnegative=True)
|
| 358 |
+
assert (x**(nn1 + nn2)).expand() == x**nn1*x**nn2
|
| 359 |
+
assert (x**(-nn1 - nn2)).expand() == x**-nn1*x**-nn2
|
| 360 |
+
assert unchanged(Pow, x, nn1 + nn2 - nn3)
|
| 361 |
+
assert unchanged(Pow, x, 1 + nn2 - nn3)
|
| 362 |
+
assert unchanged(Pow, x, nn1 - nn2)
|
| 363 |
+
assert unchanged(Pow, x, 1 - nn2)
|
| 364 |
+
assert unchanged(Pow, x, -1 + nn2)
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_expr.py
ADDED
|
@@ -0,0 +1,2313 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.assumptions.refine import refine
|
| 2 |
+
from sympy.concrete.summations import Sum
|
| 3 |
+
from sympy.core.add import Add
|
| 4 |
+
from sympy.core.basic import Basic
|
| 5 |
+
from sympy.core.containers import Tuple
|
| 6 |
+
from sympy.core.expr import (ExprBuilder, unchanged, Expr,
|
| 7 |
+
UnevaluatedExpr)
|
| 8 |
+
from sympy.core.function import (Function, expand, WildFunction,
|
| 9 |
+
AppliedUndef, Derivative, diff, Subs)
|
| 10 |
+
from sympy.core.mul import Mul, _unevaluated_Mul
|
| 11 |
+
from sympy.core.numbers import (NumberSymbol, E, zoo, oo, Float, I,
|
| 12 |
+
Rational, nan, Integer, Number, pi, _illegal)
|
| 13 |
+
from sympy.core.power import Pow
|
| 14 |
+
from sympy.core.relational import Ge, Lt, Gt, Le
|
| 15 |
+
from sympy.core.singleton import S
|
| 16 |
+
from sympy.core.sorting import default_sort_key
|
| 17 |
+
from sympy.core.symbol import Symbol, symbols, Dummy, Wild
|
| 18 |
+
from sympy.core.sympify import sympify
|
| 19 |
+
from sympy.functions.combinatorial.factorials import factorial
|
| 20 |
+
from sympy.functions.elementary.exponential import exp_polar, exp, log
|
| 21 |
+
from sympy.functions.elementary.hyperbolic import sinh, tanh
|
| 22 |
+
from sympy.functions.elementary.miscellaneous import sqrt, Max
|
| 23 |
+
from sympy.functions.elementary.piecewise import Piecewise
|
| 24 |
+
from sympy.functions.elementary.trigonometric import tan, sin, cos
|
| 25 |
+
from sympy.functions.special.delta_functions import (Heaviside,
|
| 26 |
+
DiracDelta)
|
| 27 |
+
from sympy.functions.special.error_functions import Si
|
| 28 |
+
from sympy.functions.special.gamma_functions import gamma
|
| 29 |
+
from sympy.integrals.integrals import integrate, Integral
|
| 30 |
+
from sympy.physics.secondquant import FockState
|
| 31 |
+
from sympy.polys.partfrac import apart
|
| 32 |
+
from sympy.polys.polytools import factor, cancel, Poly
|
| 33 |
+
from sympy.polys.rationaltools import together
|
| 34 |
+
from sympy.series.order import O
|
| 35 |
+
from sympy.sets.sets import FiniteSet
|
| 36 |
+
from sympy.simplify.combsimp import combsimp
|
| 37 |
+
from sympy.simplify.gammasimp import gammasimp
|
| 38 |
+
from sympy.simplify.powsimp import powsimp
|
| 39 |
+
from sympy.simplify.radsimp import collect, radsimp
|
| 40 |
+
from sympy.simplify.ratsimp import ratsimp
|
| 41 |
+
from sympy.simplify.simplify import simplify, nsimplify
|
| 42 |
+
from sympy.simplify.trigsimp import trigsimp
|
| 43 |
+
from sympy.tensor.indexed import Indexed
|
| 44 |
+
from sympy.physics.units import meter
|
| 45 |
+
|
| 46 |
+
from sympy.testing.pytest import raises, XFAIL
|
| 47 |
+
|
| 48 |
+
from sympy.abc import a, b, c, n, t, u, x, y, z
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
f, g, h = symbols('f,g,h', cls=Function)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
class DummyNumber:
|
| 55 |
+
"""
|
| 56 |
+
Minimal implementation of a number that works with SymPy.
|
| 57 |
+
|
| 58 |
+
If one has a Number class (e.g. Sage Integer, or some other custom class)
|
| 59 |
+
that one wants to work well with SymPy, one has to implement at least the
|
| 60 |
+
methods of this class DummyNumber, resp. its subclasses I5 and F1_1.
|
| 61 |
+
|
| 62 |
+
Basically, one just needs to implement either __int__() or __float__() and
|
| 63 |
+
then one needs to make sure that the class works with Python integers and
|
| 64 |
+
with itself.
|
| 65 |
+
"""
|
| 66 |
+
|
| 67 |
+
def __radd__(self, a):
|
| 68 |
+
if isinstance(a, (int, float)):
|
| 69 |
+
return a + self.number
|
| 70 |
+
return NotImplemented
|
| 71 |
+
|
| 72 |
+
def __add__(self, a):
|
| 73 |
+
if isinstance(a, (int, float, DummyNumber)):
|
| 74 |
+
return self.number + a
|
| 75 |
+
return NotImplemented
|
| 76 |
+
|
| 77 |
+
def __rsub__(self, a):
|
| 78 |
+
if isinstance(a, (int, float)):
|
| 79 |
+
return a - self.number
|
| 80 |
+
return NotImplemented
|
| 81 |
+
|
| 82 |
+
def __sub__(self, a):
|
| 83 |
+
if isinstance(a, (int, float, DummyNumber)):
|
| 84 |
+
return self.number - a
|
| 85 |
+
return NotImplemented
|
| 86 |
+
|
| 87 |
+
def __rmul__(self, a):
|
| 88 |
+
if isinstance(a, (int, float)):
|
| 89 |
+
return a * self.number
|
| 90 |
+
return NotImplemented
|
| 91 |
+
|
| 92 |
+
def __mul__(self, a):
|
| 93 |
+
if isinstance(a, (int, float, DummyNumber)):
|
| 94 |
+
return self.number * a
|
| 95 |
+
return NotImplemented
|
| 96 |
+
|
| 97 |
+
def __rtruediv__(self, a):
|
| 98 |
+
if isinstance(a, (int, float)):
|
| 99 |
+
return a / self.number
|
| 100 |
+
return NotImplemented
|
| 101 |
+
|
| 102 |
+
def __truediv__(self, a):
|
| 103 |
+
if isinstance(a, (int, float, DummyNumber)):
|
| 104 |
+
return self.number / a
|
| 105 |
+
return NotImplemented
|
| 106 |
+
|
| 107 |
+
def __rpow__(self, a):
|
| 108 |
+
if isinstance(a, (int, float)):
|
| 109 |
+
return a ** self.number
|
| 110 |
+
return NotImplemented
|
| 111 |
+
|
| 112 |
+
def __pow__(self, a):
|
| 113 |
+
if isinstance(a, (int, float, DummyNumber)):
|
| 114 |
+
return self.number ** a
|
| 115 |
+
return NotImplemented
|
| 116 |
+
|
| 117 |
+
def __pos__(self):
|
| 118 |
+
return self.number
|
| 119 |
+
|
| 120 |
+
def __neg__(self):
|
| 121 |
+
return - self.number
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
class I5(DummyNumber):
|
| 125 |
+
number = 5
|
| 126 |
+
|
| 127 |
+
def __int__(self):
|
| 128 |
+
return self.number
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
class F1_1(DummyNumber):
|
| 132 |
+
number = 1.1
|
| 133 |
+
|
| 134 |
+
def __float__(self):
|
| 135 |
+
return self.number
|
| 136 |
+
|
| 137 |
+
i5 = I5()
|
| 138 |
+
f1_1 = F1_1()
|
| 139 |
+
|
| 140 |
+
# basic SymPy objects
|
| 141 |
+
basic_objs = [
|
| 142 |
+
Rational(2),
|
| 143 |
+
Float("1.3"),
|
| 144 |
+
x,
|
| 145 |
+
y,
|
| 146 |
+
pow(x, y)*y,
|
| 147 |
+
]
|
| 148 |
+
|
| 149 |
+
# all supported objects
|
| 150 |
+
all_objs = basic_objs + [
|
| 151 |
+
5,
|
| 152 |
+
5.5,
|
| 153 |
+
i5,
|
| 154 |
+
f1_1
|
| 155 |
+
]
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
def dotest(s):
|
| 159 |
+
for xo in all_objs:
|
| 160 |
+
for yo in all_objs:
|
| 161 |
+
s(xo, yo)
|
| 162 |
+
return True
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
def test_basic():
|
| 166 |
+
def j(a, b):
|
| 167 |
+
x = a
|
| 168 |
+
x = +a
|
| 169 |
+
x = -a
|
| 170 |
+
x = a + b
|
| 171 |
+
x = a - b
|
| 172 |
+
x = a*b
|
| 173 |
+
x = a/b
|
| 174 |
+
x = a**b
|
| 175 |
+
del x
|
| 176 |
+
assert dotest(j)
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
def test_ibasic():
|
| 180 |
+
def s(a, b):
|
| 181 |
+
x = a
|
| 182 |
+
x += b
|
| 183 |
+
x = a
|
| 184 |
+
x -= b
|
| 185 |
+
x = a
|
| 186 |
+
x *= b
|
| 187 |
+
x = a
|
| 188 |
+
x /= b
|
| 189 |
+
assert dotest(s)
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
class NonBasic:
|
| 193 |
+
'''This class represents an object that knows how to implement binary
|
| 194 |
+
operations like +, -, etc with Expr but is not a subclass of Basic itself.
|
| 195 |
+
The NonExpr subclass below does subclass Basic but not Expr.
|
| 196 |
+
|
| 197 |
+
For both NonBasic and NonExpr it should be possible for them to override
|
| 198 |
+
Expr.__add__ etc because Expr.__add__ should be returning NotImplemented
|
| 199 |
+
for non Expr classes. Otherwise Expr.__add__ would create meaningless
|
| 200 |
+
objects like Add(Integer(1), FiniteSet(2)) and it wouldn't be possible for
|
| 201 |
+
other classes to override these operations when interacting with Expr.
|
| 202 |
+
'''
|
| 203 |
+
def __add__(self, other):
|
| 204 |
+
return SpecialOp('+', self, other)
|
| 205 |
+
|
| 206 |
+
def __radd__(self, other):
|
| 207 |
+
return SpecialOp('+', other, self)
|
| 208 |
+
|
| 209 |
+
def __sub__(self, other):
|
| 210 |
+
return SpecialOp('-', self, other)
|
| 211 |
+
|
| 212 |
+
def __rsub__(self, other):
|
| 213 |
+
return SpecialOp('-', other, self)
|
| 214 |
+
|
| 215 |
+
def __mul__(self, other):
|
| 216 |
+
return SpecialOp('*', self, other)
|
| 217 |
+
|
| 218 |
+
def __rmul__(self, other):
|
| 219 |
+
return SpecialOp('*', other, self)
|
| 220 |
+
|
| 221 |
+
def __truediv__(self, other):
|
| 222 |
+
return SpecialOp('/', self, other)
|
| 223 |
+
|
| 224 |
+
def __rtruediv__(self, other):
|
| 225 |
+
return SpecialOp('/', other, self)
|
| 226 |
+
|
| 227 |
+
def __floordiv__(self, other):
|
| 228 |
+
return SpecialOp('//', self, other)
|
| 229 |
+
|
| 230 |
+
def __rfloordiv__(self, other):
|
| 231 |
+
return SpecialOp('//', other, self)
|
| 232 |
+
|
| 233 |
+
def __mod__(self, other):
|
| 234 |
+
return SpecialOp('%', self, other)
|
| 235 |
+
|
| 236 |
+
def __rmod__(self, other):
|
| 237 |
+
return SpecialOp('%', other, self)
|
| 238 |
+
|
| 239 |
+
def __divmod__(self, other):
|
| 240 |
+
return SpecialOp('divmod', self, other)
|
| 241 |
+
|
| 242 |
+
def __rdivmod__(self, other):
|
| 243 |
+
return SpecialOp('divmod', other, self)
|
| 244 |
+
|
| 245 |
+
def __pow__(self, other):
|
| 246 |
+
return SpecialOp('**', self, other)
|
| 247 |
+
|
| 248 |
+
def __rpow__(self, other):
|
| 249 |
+
return SpecialOp('**', other, self)
|
| 250 |
+
|
| 251 |
+
def __lt__(self, other):
|
| 252 |
+
return SpecialOp('<', self, other)
|
| 253 |
+
|
| 254 |
+
def __gt__(self, other):
|
| 255 |
+
return SpecialOp('>', self, other)
|
| 256 |
+
|
| 257 |
+
def __le__(self, other):
|
| 258 |
+
return SpecialOp('<=', self, other)
|
| 259 |
+
|
| 260 |
+
def __ge__(self, other):
|
| 261 |
+
return SpecialOp('>=', self, other)
|
| 262 |
+
|
| 263 |
+
|
| 264 |
+
class NonExpr(Basic, NonBasic):
|
| 265 |
+
'''Like NonBasic above except this is a subclass of Basic but not Expr'''
|
| 266 |
+
pass
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
class SpecialOp():
|
| 270 |
+
'''Represents the results of operations with NonBasic and NonExpr'''
|
| 271 |
+
def __new__(cls, op, arg1, arg2):
|
| 272 |
+
obj = object.__new__(cls)
|
| 273 |
+
obj.args = (op, arg1, arg2)
|
| 274 |
+
return obj
|
| 275 |
+
|
| 276 |
+
|
| 277 |
+
class NonArithmetic(Basic):
|
| 278 |
+
'''Represents a Basic subclass that does not support arithmetic operations'''
|
| 279 |
+
pass
|
| 280 |
+
|
| 281 |
+
|
| 282 |
+
def test_cooperative_operations():
|
| 283 |
+
'''Tests that Expr uses binary operations cooperatively.
|
| 284 |
+
|
| 285 |
+
In particular it should be possible for non-Expr classes to override
|
| 286 |
+
binary operators like +, - etc when used with Expr instances. This should
|
| 287 |
+
work for non-Expr classes whether they are Basic subclasses or not. Also
|
| 288 |
+
non-Expr classes that do not define binary operators with Expr should give
|
| 289 |
+
TypeError.
|
| 290 |
+
'''
|
| 291 |
+
# A bunch of instances of Expr subclasses
|
| 292 |
+
exprs = [
|
| 293 |
+
Expr(),
|
| 294 |
+
S.Zero,
|
| 295 |
+
S.One,
|
| 296 |
+
S.Infinity,
|
| 297 |
+
S.NegativeInfinity,
|
| 298 |
+
S.ComplexInfinity,
|
| 299 |
+
S.Half,
|
| 300 |
+
Float(0.5),
|
| 301 |
+
Integer(2),
|
| 302 |
+
Symbol('x'),
|
| 303 |
+
Mul(2, Symbol('x')),
|
| 304 |
+
Add(2, Symbol('x')),
|
| 305 |
+
Pow(2, Symbol('x')),
|
| 306 |
+
]
|
| 307 |
+
|
| 308 |
+
for e in exprs:
|
| 309 |
+
# Test that these classes can override arithmetic operations in
|
| 310 |
+
# combination with various Expr types.
|
| 311 |
+
for ne in [NonBasic(), NonExpr()]:
|
| 312 |
+
|
| 313 |
+
results = [
|
| 314 |
+
(ne + e, ('+', ne, e)),
|
| 315 |
+
(e + ne, ('+', e, ne)),
|
| 316 |
+
(ne - e, ('-', ne, e)),
|
| 317 |
+
(e - ne, ('-', e, ne)),
|
| 318 |
+
(ne * e, ('*', ne, e)),
|
| 319 |
+
(e * ne, ('*', e, ne)),
|
| 320 |
+
(ne / e, ('/', ne, e)),
|
| 321 |
+
(e / ne, ('/', e, ne)),
|
| 322 |
+
(ne // e, ('//', ne, e)),
|
| 323 |
+
(e // ne, ('//', e, ne)),
|
| 324 |
+
(ne % e, ('%', ne, e)),
|
| 325 |
+
(e % ne, ('%', e, ne)),
|
| 326 |
+
(divmod(ne, e), ('divmod', ne, e)),
|
| 327 |
+
(divmod(e, ne), ('divmod', e, ne)),
|
| 328 |
+
(ne ** e, ('**', ne, e)),
|
| 329 |
+
(e ** ne, ('**', e, ne)),
|
| 330 |
+
(e < ne, ('>', ne, e)),
|
| 331 |
+
(ne < e, ('<', ne, e)),
|
| 332 |
+
(e > ne, ('<', ne, e)),
|
| 333 |
+
(ne > e, ('>', ne, e)),
|
| 334 |
+
(e <= ne, ('>=', ne, e)),
|
| 335 |
+
(ne <= e, ('<=', ne, e)),
|
| 336 |
+
(e >= ne, ('<=', ne, e)),
|
| 337 |
+
(ne >= e, ('>=', ne, e)),
|
| 338 |
+
]
|
| 339 |
+
|
| 340 |
+
for res, args in results:
|
| 341 |
+
assert type(res) is SpecialOp and res.args == args
|
| 342 |
+
|
| 343 |
+
# These classes do not support binary operators with Expr. Every
|
| 344 |
+
# operation should raise in combination with any of the Expr types.
|
| 345 |
+
for na in [NonArithmetic(), object()]:
|
| 346 |
+
|
| 347 |
+
raises(TypeError, lambda : e + na)
|
| 348 |
+
raises(TypeError, lambda : na + e)
|
| 349 |
+
raises(TypeError, lambda : e - na)
|
| 350 |
+
raises(TypeError, lambda : na - e)
|
| 351 |
+
raises(TypeError, lambda : e * na)
|
| 352 |
+
raises(TypeError, lambda : na * e)
|
| 353 |
+
raises(TypeError, lambda : e / na)
|
| 354 |
+
raises(TypeError, lambda : na / e)
|
| 355 |
+
raises(TypeError, lambda : e // na)
|
| 356 |
+
raises(TypeError, lambda : na // e)
|
| 357 |
+
raises(TypeError, lambda : e % na)
|
| 358 |
+
raises(TypeError, lambda : na % e)
|
| 359 |
+
raises(TypeError, lambda : divmod(e, na))
|
| 360 |
+
raises(TypeError, lambda : divmod(na, e))
|
| 361 |
+
raises(TypeError, lambda : e ** na)
|
| 362 |
+
raises(TypeError, lambda : na ** e)
|
| 363 |
+
raises(TypeError, lambda : e > na)
|
| 364 |
+
raises(TypeError, lambda : na > e)
|
| 365 |
+
raises(TypeError, lambda : e < na)
|
| 366 |
+
raises(TypeError, lambda : na < e)
|
| 367 |
+
raises(TypeError, lambda : e >= na)
|
| 368 |
+
raises(TypeError, lambda : na >= e)
|
| 369 |
+
raises(TypeError, lambda : e <= na)
|
| 370 |
+
raises(TypeError, lambda : na <= e)
|
| 371 |
+
|
| 372 |
+
|
| 373 |
+
def test_relational():
|
| 374 |
+
from sympy.core.relational import Lt
|
| 375 |
+
assert (pi < 3) is S.false
|
| 376 |
+
assert (pi <= 3) is S.false
|
| 377 |
+
assert (pi > 3) is S.true
|
| 378 |
+
assert (pi >= 3) is S.true
|
| 379 |
+
assert (-pi < 3) is S.true
|
| 380 |
+
assert (-pi <= 3) is S.true
|
| 381 |
+
assert (-pi > 3) is S.false
|
| 382 |
+
assert (-pi >= 3) is S.false
|
| 383 |
+
r = Symbol('r', real=True)
|
| 384 |
+
assert (r - 2 < r - 3) is S.false
|
| 385 |
+
assert Lt(x + I, x + I + 2).func == Lt # issue 8288
|
| 386 |
+
|
| 387 |
+
|
| 388 |
+
def test_relational_assumptions():
|
| 389 |
+
m1 = Symbol("m1", nonnegative=False)
|
| 390 |
+
m2 = Symbol("m2", positive=False)
|
| 391 |
+
m3 = Symbol("m3", nonpositive=False)
|
| 392 |
+
m4 = Symbol("m4", negative=False)
|
| 393 |
+
assert (m1 < 0) == Lt(m1, 0)
|
| 394 |
+
assert (m2 <= 0) == Le(m2, 0)
|
| 395 |
+
assert (m3 > 0) == Gt(m3, 0)
|
| 396 |
+
assert (m4 >= 0) == Ge(m4, 0)
|
| 397 |
+
m1 = Symbol("m1", nonnegative=False, real=True)
|
| 398 |
+
m2 = Symbol("m2", positive=False, real=True)
|
| 399 |
+
m3 = Symbol("m3", nonpositive=False, real=True)
|
| 400 |
+
m4 = Symbol("m4", negative=False, real=True)
|
| 401 |
+
assert (m1 < 0) is S.true
|
| 402 |
+
assert (m2 <= 0) is S.true
|
| 403 |
+
assert (m3 > 0) is S.true
|
| 404 |
+
assert (m4 >= 0) is S.true
|
| 405 |
+
m1 = Symbol("m1", negative=True)
|
| 406 |
+
m2 = Symbol("m2", nonpositive=True)
|
| 407 |
+
m3 = Symbol("m3", positive=True)
|
| 408 |
+
m4 = Symbol("m4", nonnegative=True)
|
| 409 |
+
assert (m1 < 0) is S.true
|
| 410 |
+
assert (m2 <= 0) is S.true
|
| 411 |
+
assert (m3 > 0) is S.true
|
| 412 |
+
assert (m4 >= 0) is S.true
|
| 413 |
+
m1 = Symbol("m1", negative=False, real=True)
|
| 414 |
+
m2 = Symbol("m2", nonpositive=False, real=True)
|
| 415 |
+
m3 = Symbol("m3", positive=False, real=True)
|
| 416 |
+
m4 = Symbol("m4", nonnegative=False, real=True)
|
| 417 |
+
assert (m1 < 0) is S.false
|
| 418 |
+
assert (m2 <= 0) is S.false
|
| 419 |
+
assert (m3 > 0) is S.false
|
| 420 |
+
assert (m4 >= 0) is S.false
|
| 421 |
+
|
| 422 |
+
|
| 423 |
+
# See https://github.com/sympy/sympy/issues/17708
|
| 424 |
+
#def test_relational_noncommutative():
|
| 425 |
+
# from sympy import Lt, Gt, Le, Ge
|
| 426 |
+
# A, B = symbols('A,B', commutative=False)
|
| 427 |
+
# assert (A < B) == Lt(A, B)
|
| 428 |
+
# assert (A <= B) == Le(A, B)
|
| 429 |
+
# assert (A > B) == Gt(A, B)
|
| 430 |
+
# assert (A >= B) == Ge(A, B)
|
| 431 |
+
|
| 432 |
+
|
| 433 |
+
def test_basic_nostr():
|
| 434 |
+
for obj in basic_objs:
|
| 435 |
+
raises(TypeError, lambda: obj + '1')
|
| 436 |
+
raises(TypeError, lambda: obj - '1')
|
| 437 |
+
if obj == 2:
|
| 438 |
+
assert obj * '1' == '11'
|
| 439 |
+
else:
|
| 440 |
+
raises(TypeError, lambda: obj * '1')
|
| 441 |
+
raises(TypeError, lambda: obj / '1')
|
| 442 |
+
raises(TypeError, lambda: obj ** '1')
|
| 443 |
+
|
| 444 |
+
|
| 445 |
+
def test_series_expansion_for_uniform_order():
|
| 446 |
+
assert (1/x + y + x).series(x, 0, 0) == 1/x + O(1, x)
|
| 447 |
+
assert (1/x + y + x).series(x, 0, 1) == 1/x + y + O(x)
|
| 448 |
+
assert (1/x + 1 + x).series(x, 0, 0) == 1/x + O(1, x)
|
| 449 |
+
assert (1/x + 1 + x).series(x, 0, 1) == 1/x + 1 + O(x)
|
| 450 |
+
assert (1/x + x).series(x, 0, 0) == 1/x + O(1, x)
|
| 451 |
+
assert (1/x + y + y*x + x).series(x, 0, 0) == 1/x + O(1, x)
|
| 452 |
+
assert (1/x + y + y*x + x).series(x, 0, 1) == 1/x + y + O(x)
|
| 453 |
+
|
| 454 |
+
|
| 455 |
+
def test_leadterm():
|
| 456 |
+
assert (3 + 2*x**(log(3)/log(2) - 1)).leadterm(x) == (3, 0)
|
| 457 |
+
|
| 458 |
+
assert (1/x**2 + 1 + x + x**2).leadterm(x)[1] == -2
|
| 459 |
+
assert (1/x + 1 + x + x**2).leadterm(x)[1] == -1
|
| 460 |
+
assert (x**2 + 1/x).leadterm(x)[1] == -1
|
| 461 |
+
assert (1 + x**2).leadterm(x)[1] == 0
|
| 462 |
+
assert (x + 1).leadterm(x)[1] == 0
|
| 463 |
+
assert (x + x**2).leadterm(x)[1] == 1
|
| 464 |
+
assert (x**2).leadterm(x)[1] == 2
|
| 465 |
+
|
| 466 |
+
|
| 467 |
+
def test_as_leading_term():
|
| 468 |
+
assert (3 + 2*x**(log(3)/log(2) - 1)).as_leading_term(x) == 3
|
| 469 |
+
assert (1/x**2 + 1 + x + x**2).as_leading_term(x) == 1/x**2
|
| 470 |
+
assert (1/x + 1 + x + x**2).as_leading_term(x) == 1/x
|
| 471 |
+
assert (x**2 + 1/x).as_leading_term(x) == 1/x
|
| 472 |
+
assert (1 + x**2).as_leading_term(x) == 1
|
| 473 |
+
assert (x + 1).as_leading_term(x) == 1
|
| 474 |
+
assert (x + x**2).as_leading_term(x) == x
|
| 475 |
+
assert (x**2).as_leading_term(x) == x**2
|
| 476 |
+
assert (x + oo).as_leading_term(x) is oo
|
| 477 |
+
|
| 478 |
+
raises(ValueError, lambda: (x + 1).as_leading_term(1))
|
| 479 |
+
|
| 480 |
+
# https://github.com/sympy/sympy/issues/21177
|
| 481 |
+
e = -3*x + (x + Rational(3, 2) - sqrt(3)*S.ImaginaryUnit/2)**2\
|
| 482 |
+
- Rational(3, 2) + 3*sqrt(3)*S.ImaginaryUnit/2
|
| 483 |
+
assert e.as_leading_term(x) == -sqrt(3)*I*x
|
| 484 |
+
|
| 485 |
+
# https://github.com/sympy/sympy/issues/21245
|
| 486 |
+
e = 1 - x - x**2
|
| 487 |
+
d = (1 + sqrt(5))/2
|
| 488 |
+
assert e.subs(x, y + 1/d).as_leading_term(y) == \
|
| 489 |
+
(-40*y - 16*sqrt(5)*y)/(16 + 8*sqrt(5))
|
| 490 |
+
|
| 491 |
+
# https://github.com/sympy/sympy/issues/26991
|
| 492 |
+
assert sinh(tanh(3/(100*x))).as_leading_term(x, cdir = 1) == sinh(1)
|
| 493 |
+
|
| 494 |
+
|
| 495 |
+
def test_leadterm2():
|
| 496 |
+
assert (x*cos(1)*cos(1 + sin(1)) + sin(1 + sin(1))).leadterm(x) == \
|
| 497 |
+
(sin(1 + sin(1)), 0)
|
| 498 |
+
|
| 499 |
+
|
| 500 |
+
def test_leadterm3():
|
| 501 |
+
assert (y + z + x).leadterm(x) == (y + z, 0)
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
def test_as_leading_term2():
|
| 505 |
+
assert (x*cos(1)*cos(1 + sin(1)) + sin(1 + sin(1))).as_leading_term(x) == \
|
| 506 |
+
sin(1 + sin(1))
|
| 507 |
+
|
| 508 |
+
|
| 509 |
+
def test_as_leading_term3():
|
| 510 |
+
assert (2 + pi + x).as_leading_term(x) == 2 + pi
|
| 511 |
+
assert (2*x + pi*x + x**2).as_leading_term(x) == 2*x + pi*x
|
| 512 |
+
|
| 513 |
+
|
| 514 |
+
def test_as_leading_term4():
|
| 515 |
+
# see issue 6843
|
| 516 |
+
n = Symbol('n', integer=True, positive=True)
|
| 517 |
+
r = -n**3/(2*n**2 + 4*n + 2) - n**2/(n**2 + 2*n + 1) + \
|
| 518 |
+
n**2/(n + 1) - n/(2*n**2 + 4*n + 2) + n/(n*x + x) + 2*n/(n + 1) - \
|
| 519 |
+
1 + 1/(n*x + x) + 1/(n + 1) - 1/x
|
| 520 |
+
assert r.as_leading_term(x).cancel() == n/2
|
| 521 |
+
|
| 522 |
+
|
| 523 |
+
def test_as_leading_term_stub():
|
| 524 |
+
class foo(Function):
|
| 525 |
+
pass
|
| 526 |
+
assert foo(1/x).as_leading_term(x) == foo(1/x)
|
| 527 |
+
assert foo(1).as_leading_term(x) == foo(1)
|
| 528 |
+
raises(NotImplementedError, lambda: foo(x).as_leading_term(x))
|
| 529 |
+
|
| 530 |
+
|
| 531 |
+
def test_as_leading_term_deriv_integral():
|
| 532 |
+
# related to issue 11313
|
| 533 |
+
assert Derivative(x ** 3, x).as_leading_term(x) == 3*x**2
|
| 534 |
+
assert Derivative(x ** 3, y).as_leading_term(x) == 0
|
| 535 |
+
|
| 536 |
+
assert Integral(x ** 3, x).as_leading_term(x) == x**4/4
|
| 537 |
+
assert Integral(x ** 3, y).as_leading_term(x) == y*x**3
|
| 538 |
+
|
| 539 |
+
assert Derivative(exp(x), x).as_leading_term(x) == 1
|
| 540 |
+
assert Derivative(log(x), x).as_leading_term(x) == (1/x).as_leading_term(x)
|
| 541 |
+
|
| 542 |
+
|
| 543 |
+
def test_atoms():
|
| 544 |
+
assert x.atoms() == {x}
|
| 545 |
+
assert (1 + x).atoms() == {x, S.One}
|
| 546 |
+
|
| 547 |
+
assert (1 + 2*cos(x)).atoms(Symbol) == {x}
|
| 548 |
+
assert (1 + 2*cos(x)).atoms(Symbol, Number) == {S.One, S(2), x}
|
| 549 |
+
|
| 550 |
+
assert (2*(x**(y**x))).atoms() == {S(2), x, y}
|
| 551 |
+
|
| 552 |
+
assert S.Half.atoms() == {S.Half}
|
| 553 |
+
assert S.Half.atoms(Symbol) == set()
|
| 554 |
+
|
| 555 |
+
assert sin(oo).atoms(oo) == set()
|
| 556 |
+
|
| 557 |
+
assert Poly(0, x).atoms() == {S.Zero, x}
|
| 558 |
+
assert Poly(1, x).atoms() == {S.One, x}
|
| 559 |
+
|
| 560 |
+
assert Poly(x, x).atoms() == {x}
|
| 561 |
+
assert Poly(x, x, y).atoms() == {x, y}
|
| 562 |
+
assert Poly(x + y, x, y).atoms() == {x, y}
|
| 563 |
+
assert Poly(x + y, x, y, z).atoms() == {x, y, z}
|
| 564 |
+
assert Poly(x + y*t, x, y, z).atoms() == {t, x, y, z}
|
| 565 |
+
|
| 566 |
+
assert (I*pi).atoms(NumberSymbol) == {pi}
|
| 567 |
+
assert (I*pi).atoms(NumberSymbol, I) == \
|
| 568 |
+
(I*pi).atoms(I, NumberSymbol) == {pi, I}
|
| 569 |
+
|
| 570 |
+
assert exp(exp(x)).atoms(exp) == {exp(exp(x)), exp(x)}
|
| 571 |
+
assert (1 + x*(2 + y) + exp(3 + z)).atoms(Add) == \
|
| 572 |
+
{1 + x*(2 + y) + exp(3 + z), 2 + y, 3 + z}
|
| 573 |
+
|
| 574 |
+
# issue 6132
|
| 575 |
+
e = (f(x) + sin(x) + 2)
|
| 576 |
+
assert e.atoms(AppliedUndef) == \
|
| 577 |
+
{f(x)}
|
| 578 |
+
assert e.atoms(AppliedUndef, Function) == \
|
| 579 |
+
{f(x), sin(x)}
|
| 580 |
+
assert e.atoms(Function) == \
|
| 581 |
+
{f(x), sin(x)}
|
| 582 |
+
assert e.atoms(AppliedUndef, Number) == \
|
| 583 |
+
{f(x), S(2)}
|
| 584 |
+
assert e.atoms(Function, Number) == \
|
| 585 |
+
{S(2), sin(x), f(x)}
|
| 586 |
+
|
| 587 |
+
|
| 588 |
+
def test_is_polynomial():
|
| 589 |
+
k = Symbol('k', nonnegative=True, integer=True)
|
| 590 |
+
|
| 591 |
+
assert Rational(2).is_polynomial(x, y, z) is True
|
| 592 |
+
assert (S.Pi).is_polynomial(x, y, z) is True
|
| 593 |
+
|
| 594 |
+
assert x.is_polynomial(x) is True
|
| 595 |
+
assert x.is_polynomial(y) is True
|
| 596 |
+
|
| 597 |
+
assert (x**2).is_polynomial(x) is True
|
| 598 |
+
assert (x**2).is_polynomial(y) is True
|
| 599 |
+
|
| 600 |
+
assert (x**(-2)).is_polynomial(x) is False
|
| 601 |
+
assert (x**(-2)).is_polynomial(y) is True
|
| 602 |
+
|
| 603 |
+
assert (2**x).is_polynomial(x) is False
|
| 604 |
+
assert (2**x).is_polynomial(y) is True
|
| 605 |
+
|
| 606 |
+
assert (x**k).is_polynomial(x) is False
|
| 607 |
+
assert (x**k).is_polynomial(k) is False
|
| 608 |
+
assert (x**x).is_polynomial(x) is False
|
| 609 |
+
assert (k**k).is_polynomial(k) is False
|
| 610 |
+
assert (k**x).is_polynomial(k) is False
|
| 611 |
+
|
| 612 |
+
assert (x**(-k)).is_polynomial(x) is False
|
| 613 |
+
assert ((2*x)**k).is_polynomial(x) is False
|
| 614 |
+
|
| 615 |
+
assert (x**2 + 3*x - 8).is_polynomial(x) is True
|
| 616 |
+
assert (x**2 + 3*x - 8).is_polynomial(y) is True
|
| 617 |
+
|
| 618 |
+
assert (x**2 + 3*x - 8).is_polynomial() is True
|
| 619 |
+
|
| 620 |
+
assert sqrt(x).is_polynomial(x) is False
|
| 621 |
+
assert (sqrt(x)**3).is_polynomial(x) is False
|
| 622 |
+
|
| 623 |
+
assert (x**2 + 3*x*sqrt(y) - 8).is_polynomial(x) is True
|
| 624 |
+
assert (x**2 + 3*x*sqrt(y) - 8).is_polynomial(y) is False
|
| 625 |
+
|
| 626 |
+
assert ((x**2)*(y**2) + x*(y**2) + y*x + exp(2)).is_polynomial() is True
|
| 627 |
+
assert ((x**2)*(y**2) + x*(y**2) + y*x + exp(x)).is_polynomial() is False
|
| 628 |
+
|
| 629 |
+
assert (
|
| 630 |
+
(x**2)*(y**2) + x*(y**2) + y*x + exp(2)).is_polynomial(x, y) is True
|
| 631 |
+
assert (
|
| 632 |
+
(x**2)*(y**2) + x*(y**2) + y*x + exp(x)).is_polynomial(x, y) is False
|
| 633 |
+
|
| 634 |
+
assert (1/f(x) + 1).is_polynomial(f(x)) is False
|
| 635 |
+
|
| 636 |
+
|
| 637 |
+
def test_is_rational_function():
|
| 638 |
+
assert Integer(1).is_rational_function() is True
|
| 639 |
+
assert Integer(1).is_rational_function(x) is True
|
| 640 |
+
|
| 641 |
+
assert Rational(17, 54).is_rational_function() is True
|
| 642 |
+
assert Rational(17, 54).is_rational_function(x) is True
|
| 643 |
+
|
| 644 |
+
assert (12/x).is_rational_function() is True
|
| 645 |
+
assert (12/x).is_rational_function(x) is True
|
| 646 |
+
|
| 647 |
+
assert (x/y).is_rational_function() is True
|
| 648 |
+
assert (x/y).is_rational_function(x) is True
|
| 649 |
+
assert (x/y).is_rational_function(x, y) is True
|
| 650 |
+
|
| 651 |
+
assert (x**2 + 1/x/y).is_rational_function() is True
|
| 652 |
+
assert (x**2 + 1/x/y).is_rational_function(x) is True
|
| 653 |
+
assert (x**2 + 1/x/y).is_rational_function(x, y) is True
|
| 654 |
+
|
| 655 |
+
assert (sin(y)/x).is_rational_function() is False
|
| 656 |
+
assert (sin(y)/x).is_rational_function(y) is False
|
| 657 |
+
assert (sin(y)/x).is_rational_function(x) is True
|
| 658 |
+
assert (sin(y)/x).is_rational_function(x, y) is False
|
| 659 |
+
|
| 660 |
+
for i in _illegal:
|
| 661 |
+
assert not i.is_rational_function()
|
| 662 |
+
for d in (1, x):
|
| 663 |
+
assert not (i/d).is_rational_function()
|
| 664 |
+
|
| 665 |
+
|
| 666 |
+
def test_is_meromorphic():
|
| 667 |
+
f = a/x**2 + b + x + c*x**2
|
| 668 |
+
assert f.is_meromorphic(x, 0) is True
|
| 669 |
+
assert f.is_meromorphic(x, 1) is True
|
| 670 |
+
assert f.is_meromorphic(x, zoo) is True
|
| 671 |
+
|
| 672 |
+
g = 3 + 2*x**(log(3)/log(2) - 1)
|
| 673 |
+
assert g.is_meromorphic(x, 0) is False
|
| 674 |
+
assert g.is_meromorphic(x, 1) is True
|
| 675 |
+
assert g.is_meromorphic(x, zoo) is False
|
| 676 |
+
|
| 677 |
+
n = Symbol('n', integer=True)
|
| 678 |
+
e = sin(1/x)**n*x
|
| 679 |
+
assert e.is_meromorphic(x, 0) is False
|
| 680 |
+
assert e.is_meromorphic(x, 1) is True
|
| 681 |
+
assert e.is_meromorphic(x, zoo) is False
|
| 682 |
+
|
| 683 |
+
e = log(x)**pi
|
| 684 |
+
assert e.is_meromorphic(x, 0) is False
|
| 685 |
+
assert e.is_meromorphic(x, 1) is False
|
| 686 |
+
assert e.is_meromorphic(x, 2) is True
|
| 687 |
+
assert e.is_meromorphic(x, zoo) is False
|
| 688 |
+
|
| 689 |
+
assert (log(x)**a).is_meromorphic(x, 0) is False
|
| 690 |
+
assert (log(x)**a).is_meromorphic(x, 1) is False
|
| 691 |
+
assert (a**log(x)).is_meromorphic(x, 0) is None
|
| 692 |
+
assert (3**log(x)).is_meromorphic(x, 0) is False
|
| 693 |
+
assert (3**log(x)).is_meromorphic(x, 1) is True
|
| 694 |
+
|
| 695 |
+
def test_is_algebraic_expr():
|
| 696 |
+
assert sqrt(3).is_algebraic_expr(x) is True
|
| 697 |
+
assert sqrt(3).is_algebraic_expr() is True
|
| 698 |
+
|
| 699 |
+
eq = ((1 + x**2)/(1 - y**2))**(S.One/3)
|
| 700 |
+
assert eq.is_algebraic_expr(x) is True
|
| 701 |
+
assert eq.is_algebraic_expr(y) is True
|
| 702 |
+
|
| 703 |
+
assert (sqrt(x) + y**(S(2)/3)).is_algebraic_expr(x) is True
|
| 704 |
+
assert (sqrt(x) + y**(S(2)/3)).is_algebraic_expr(y) is True
|
| 705 |
+
assert (sqrt(x) + y**(S(2)/3)).is_algebraic_expr() is True
|
| 706 |
+
|
| 707 |
+
assert (cos(y)/sqrt(x)).is_algebraic_expr() is False
|
| 708 |
+
assert (cos(y)/sqrt(x)).is_algebraic_expr(x) is True
|
| 709 |
+
assert (cos(y)/sqrt(x)).is_algebraic_expr(y) is False
|
| 710 |
+
assert (cos(y)/sqrt(x)).is_algebraic_expr(x, y) is False
|
| 711 |
+
|
| 712 |
+
|
| 713 |
+
def test_SAGE1():
|
| 714 |
+
#see https://github.com/sympy/sympy/issues/3346
|
| 715 |
+
class MyInt:
|
| 716 |
+
def _sympy_(self):
|
| 717 |
+
return Integer(5)
|
| 718 |
+
m = MyInt()
|
| 719 |
+
e = Rational(2)*m
|
| 720 |
+
assert e == 10
|
| 721 |
+
|
| 722 |
+
raises(TypeError, lambda: Rational(2)*MyInt)
|
| 723 |
+
|
| 724 |
+
|
| 725 |
+
def test_SAGE2():
|
| 726 |
+
class MyInt:
|
| 727 |
+
def __int__(self):
|
| 728 |
+
return 5
|
| 729 |
+
assert sympify(MyInt()) == 5
|
| 730 |
+
e = Rational(2)*MyInt()
|
| 731 |
+
assert e == 10
|
| 732 |
+
|
| 733 |
+
raises(TypeError, lambda: Rational(2)*MyInt)
|
| 734 |
+
|
| 735 |
+
|
| 736 |
+
def test_SAGE3():
|
| 737 |
+
class MySymbol:
|
| 738 |
+
def __rmul__(self, other):
|
| 739 |
+
return ('mys', other, self)
|
| 740 |
+
|
| 741 |
+
o = MySymbol()
|
| 742 |
+
e = x*o
|
| 743 |
+
|
| 744 |
+
assert e == ('mys', x, o)
|
| 745 |
+
|
| 746 |
+
|
| 747 |
+
def test_len():
|
| 748 |
+
e = x*y
|
| 749 |
+
assert len(e.args) == 2
|
| 750 |
+
e = x + y + z
|
| 751 |
+
assert len(e.args) == 3
|
| 752 |
+
|
| 753 |
+
|
| 754 |
+
def test_doit():
|
| 755 |
+
a = Integral(x**2, x)
|
| 756 |
+
|
| 757 |
+
assert isinstance(a.doit(), Integral) is False
|
| 758 |
+
|
| 759 |
+
assert isinstance(a.doit(integrals=True), Integral) is False
|
| 760 |
+
assert isinstance(a.doit(integrals=False), Integral) is True
|
| 761 |
+
|
| 762 |
+
assert (2*Integral(x, x)).doit() == x**2
|
| 763 |
+
|
| 764 |
+
|
| 765 |
+
def test_attribute_error():
|
| 766 |
+
raises(AttributeError, lambda: x.cos())
|
| 767 |
+
raises(AttributeError, lambda: x.sin())
|
| 768 |
+
raises(AttributeError, lambda: x.exp())
|
| 769 |
+
|
| 770 |
+
|
| 771 |
+
def test_args():
|
| 772 |
+
assert (x*y).args in ((x, y), (y, x))
|
| 773 |
+
assert (x + y).args in ((x, y), (y, x))
|
| 774 |
+
assert (x*y + 1).args in ((x*y, 1), (1, x*y))
|
| 775 |
+
assert sin(x*y).args == (x*y,)
|
| 776 |
+
assert sin(x*y).args[0] == x*y
|
| 777 |
+
assert (x**y).args == (x, y)
|
| 778 |
+
assert (x**y).args[0] == x
|
| 779 |
+
assert (x**y).args[1] == y
|
| 780 |
+
|
| 781 |
+
|
| 782 |
+
def test_noncommutative_expand_issue_3757():
|
| 783 |
+
A, B, C = symbols('A,B,C', commutative=False)
|
| 784 |
+
assert A*B - B*A != 0
|
| 785 |
+
assert (A*(A + B)*B).expand() == A**2*B + A*B**2
|
| 786 |
+
assert (A*(A + B + C)*B).expand() == A**2*B + A*B**2 + A*C*B
|
| 787 |
+
|
| 788 |
+
|
| 789 |
+
def test_as_numer_denom():
|
| 790 |
+
a, b, c = symbols('a, b, c')
|
| 791 |
+
|
| 792 |
+
assert nan.as_numer_denom() == (nan, 1)
|
| 793 |
+
assert oo.as_numer_denom() == (oo, 1)
|
| 794 |
+
assert (-oo).as_numer_denom() == (-oo, 1)
|
| 795 |
+
assert zoo.as_numer_denom() == (zoo, 1)
|
| 796 |
+
assert (-zoo).as_numer_denom() == (zoo, 1)
|
| 797 |
+
|
| 798 |
+
assert x.as_numer_denom() == (x, 1)
|
| 799 |
+
assert (1/x).as_numer_denom() == (1, x)
|
| 800 |
+
assert (x/y).as_numer_denom() == (x, y)
|
| 801 |
+
assert (x/2).as_numer_denom() == (x, 2)
|
| 802 |
+
assert (x*y/z).as_numer_denom() == (x*y, z)
|
| 803 |
+
assert (x/(y*z)).as_numer_denom() == (x, y*z)
|
| 804 |
+
assert S.Half.as_numer_denom() == (1, 2)
|
| 805 |
+
assert (1/y**2).as_numer_denom() == (1, y**2)
|
| 806 |
+
assert (x/y**2).as_numer_denom() == (x, y**2)
|
| 807 |
+
assert ((x**2 + 1)/y).as_numer_denom() == (x**2 + 1, y)
|
| 808 |
+
assert (x*(y + 1)/y**7).as_numer_denom() == (x*(y + 1), y**7)
|
| 809 |
+
assert (x**-2).as_numer_denom() == (1, x**2)
|
| 810 |
+
assert (a/x + b/2/x + c/3/x).as_numer_denom() == \
|
| 811 |
+
(6*a + 3*b + 2*c, 6*x)
|
| 812 |
+
assert (a/x + b/2/x + c/3/y).as_numer_denom() == \
|
| 813 |
+
(2*c*x + y*(6*a + 3*b), 6*x*y)
|
| 814 |
+
assert (a/x + b/2/x + c/.5/x).as_numer_denom() == \
|
| 815 |
+
(2*a + b + 4.0*c, 2*x)
|
| 816 |
+
# this should take no more than a few seconds
|
| 817 |
+
assert int(log(Add(*[Dummy()/i/x for i in range(1, 705)]
|
| 818 |
+
).as_numer_denom()[1]/x).n(4)) == 705
|
| 819 |
+
for i in [S.Infinity, S.NegativeInfinity, S.ComplexInfinity]:
|
| 820 |
+
assert (i + x/3).as_numer_denom() == \
|
| 821 |
+
(x + i, 3)
|
| 822 |
+
assert (S.Infinity + x/3 + y/4).as_numer_denom() == \
|
| 823 |
+
(4*x + 3*y + S.Infinity, 12)
|
| 824 |
+
assert (oo*x + zoo*y).as_numer_denom() == \
|
| 825 |
+
(zoo*y + oo*x, 1)
|
| 826 |
+
|
| 827 |
+
A, B, C = symbols('A,B,C', commutative=False)
|
| 828 |
+
|
| 829 |
+
assert (A*B*C**-1).as_numer_denom() == (A*B*C**-1, 1)
|
| 830 |
+
assert (A*B*C**-1/x).as_numer_denom() == (A*B*C**-1, x)
|
| 831 |
+
assert (C**-1*A*B).as_numer_denom() == (C**-1*A*B, 1)
|
| 832 |
+
assert (C**-1*A*B/x).as_numer_denom() == (C**-1*A*B, x)
|
| 833 |
+
assert ((A*B*C)**-1).as_numer_denom() == ((A*B*C)**-1, 1)
|
| 834 |
+
assert ((A*B*C)**-1/x).as_numer_denom() == ((A*B*C)**-1, x)
|
| 835 |
+
|
| 836 |
+
# the following morphs from Add to Mul during processing
|
| 837 |
+
assert Add(0, (x + y)/z/-2, evaluate=False).as_numer_denom(
|
| 838 |
+
) == (-x - y, 2*z)
|
| 839 |
+
|
| 840 |
+
|
| 841 |
+
def test_trunc():
|
| 842 |
+
import math
|
| 843 |
+
x, y = symbols('x y')
|
| 844 |
+
assert math.trunc(2) == 2
|
| 845 |
+
assert math.trunc(4.57) == 4
|
| 846 |
+
assert math.trunc(-5.79) == -5
|
| 847 |
+
assert math.trunc(pi) == 3
|
| 848 |
+
assert math.trunc(log(7)) == 1
|
| 849 |
+
assert math.trunc(exp(5)) == 148
|
| 850 |
+
assert math.trunc(cos(pi)) == -1
|
| 851 |
+
assert math.trunc(sin(5)) == 0
|
| 852 |
+
|
| 853 |
+
raises(TypeError, lambda: math.trunc(x))
|
| 854 |
+
raises(TypeError, lambda: math.trunc(x + y**2))
|
| 855 |
+
raises(TypeError, lambda: math.trunc(oo))
|
| 856 |
+
|
| 857 |
+
|
| 858 |
+
def test_as_independent():
|
| 859 |
+
assert S.Zero.as_independent(x, as_Add=True) == (0, 0)
|
| 860 |
+
assert S.Zero.as_independent(x, as_Add=False) == (0, 0)
|
| 861 |
+
assert (2*x*sin(x) + y + x).as_independent(x) == (y, x + 2*x*sin(x))
|
| 862 |
+
assert (2*x*sin(x) + y + x).as_independent(y) == (x + 2*x*sin(x), y)
|
| 863 |
+
|
| 864 |
+
assert (2*x*sin(x) + y + x).as_independent(x, y) == (0, y + x + 2*x*sin(x))
|
| 865 |
+
|
| 866 |
+
assert (x*sin(x)*cos(y)).as_independent(x) == (cos(y), x*sin(x))
|
| 867 |
+
assert (x*sin(x)*cos(y)).as_independent(y) == (x*sin(x), cos(y))
|
| 868 |
+
|
| 869 |
+
assert (x*sin(x)*cos(y)).as_independent(x, y) == (1, x*sin(x)*cos(y))
|
| 870 |
+
|
| 871 |
+
assert (sin(x)).as_independent(x) == (1, sin(x))
|
| 872 |
+
assert (sin(x)).as_independent(y) == (sin(x), 1)
|
| 873 |
+
|
| 874 |
+
assert (2*sin(x)).as_independent(x) == (2, sin(x))
|
| 875 |
+
assert (2*sin(x)).as_independent(y) == (2*sin(x), 1)
|
| 876 |
+
|
| 877 |
+
# issue 4903 = 1766b
|
| 878 |
+
n1, n2, n3 = symbols('n1 n2 n3', commutative=False)
|
| 879 |
+
assert (n1 + n1*n2).as_independent(n2) == (n1, n1*n2)
|
| 880 |
+
assert (n2*n1 + n1*n2).as_independent(n2) == (0, n1*n2 + n2*n1)
|
| 881 |
+
assert (n1*n2*n1).as_independent(n2) == (n1, n2*n1)
|
| 882 |
+
assert (n1*n2*n1).as_independent(n1) == (1, n1*n2*n1)
|
| 883 |
+
|
| 884 |
+
assert (3*x).as_independent(x, as_Add=True) == (0, 3*x)
|
| 885 |
+
assert (3*x).as_independent(x, as_Add=False) == (3, x)
|
| 886 |
+
assert (3 + x).as_independent(x, as_Add=True) == (3, x)
|
| 887 |
+
assert (3 + x).as_independent(x, as_Add=False) == (1, 3 + x)
|
| 888 |
+
|
| 889 |
+
# issue 5479
|
| 890 |
+
assert (3*x).as_independent(Symbol) == (3, x)
|
| 891 |
+
|
| 892 |
+
# issue 5648
|
| 893 |
+
assert (n1*x*y).as_independent(x) == (n1*y, x)
|
| 894 |
+
assert ((x + n1)*(x - y)).as_independent(x) == (1, (x + n1)*(x - y))
|
| 895 |
+
assert ((x + n1)*(x - y)).as_independent(y) == (x + n1, x - y)
|
| 896 |
+
assert (DiracDelta(x - n1)*DiracDelta(x - y)).as_independent(x) \
|
| 897 |
+
== (1, DiracDelta(x - n1)*DiracDelta(x - y))
|
| 898 |
+
assert (x*y*n1*n2*n3).as_independent(n2) == (x*y*n1, n2*n3)
|
| 899 |
+
assert (x*y*n1*n2*n3).as_independent(n1) == (x*y, n1*n2*n3)
|
| 900 |
+
assert (x*y*n1*n2*n3).as_independent(n3) == (x*y*n1*n2, n3)
|
| 901 |
+
assert (DiracDelta(x - n1)*DiracDelta(y - n1)*DiracDelta(x - n2)).as_independent(y) == \
|
| 902 |
+
(DiracDelta(x - n1)*DiracDelta(x - n2), DiracDelta(y - n1))
|
| 903 |
+
|
| 904 |
+
# issue 5784
|
| 905 |
+
assert (x + Integral(x, (x, 1, 2))).as_independent(x, strict=True) == \
|
| 906 |
+
(Integral(x, (x, 1, 2)), x)
|
| 907 |
+
|
| 908 |
+
eq = Add(x, -x, 2, -3, evaluate=False)
|
| 909 |
+
assert eq.as_independent(x) == (-1, Add(x, -x, evaluate=False))
|
| 910 |
+
eq = Mul(x, 1/x, 2, -3, evaluate=False)
|
| 911 |
+
assert eq.as_independent(x) == (-6, Mul(x, 1/x, evaluate=False))
|
| 912 |
+
|
| 913 |
+
assert (x*y).as_independent(z, as_Add=True) == (x*y, 0)
|
| 914 |
+
|
| 915 |
+
@XFAIL
|
| 916 |
+
def test_call_2():
|
| 917 |
+
# TODO UndefinedFunction does not subclass Expr
|
| 918 |
+
assert (2*f)(x) == 2*f(x)
|
| 919 |
+
|
| 920 |
+
|
| 921 |
+
def test_replace():
|
| 922 |
+
e = log(sin(x)) + tan(sin(x**2))
|
| 923 |
+
|
| 924 |
+
assert e.replace(sin, cos) == log(cos(x)) + tan(cos(x**2))
|
| 925 |
+
assert e.replace(
|
| 926 |
+
sin, lambda a: sin(2*a)) == log(sin(2*x)) + tan(sin(2*x**2))
|
| 927 |
+
|
| 928 |
+
a = Wild('a')
|
| 929 |
+
b = Wild('b')
|
| 930 |
+
|
| 931 |
+
assert e.replace(sin(a), cos(a)) == log(cos(x)) + tan(cos(x**2))
|
| 932 |
+
assert e.replace(
|
| 933 |
+
sin(a), lambda a: sin(2*a)) == log(sin(2*x)) + tan(sin(2*x**2))
|
| 934 |
+
# test exact
|
| 935 |
+
assert (2*x).replace(a*x + b, b - a, exact=True) == 2*x
|
| 936 |
+
assert (2*x).replace(a*x + b, b - a) == 2*x
|
| 937 |
+
assert (2*x).replace(a*x + b, b - a, exact=False) == 2/x
|
| 938 |
+
assert (2*x).replace(a*x + b, lambda a, b: b - a, exact=True) == 2*x
|
| 939 |
+
assert (2*x).replace(a*x + b, lambda a, b: b - a) == 2*x
|
| 940 |
+
assert (2*x).replace(a*x + b, lambda a, b: b - a, exact=False) == 2/x
|
| 941 |
+
|
| 942 |
+
g = 2*sin(x**3)
|
| 943 |
+
|
| 944 |
+
assert g.replace(
|
| 945 |
+
lambda expr: expr.is_Number, lambda expr: expr**2) == 4*sin(x**9)
|
| 946 |
+
|
| 947 |
+
assert cos(x).replace(cos, sin, map=True) == (sin(x), {cos(x): sin(x)})
|
| 948 |
+
assert sin(x).replace(cos, sin) == sin(x)
|
| 949 |
+
|
| 950 |
+
cond, func = lambda x: x.is_Mul, lambda x: 2*x
|
| 951 |
+
assert (x*y).replace(cond, func, map=True) == (2*x*y, {x*y: 2*x*y})
|
| 952 |
+
assert (x*(1 + x*y)).replace(cond, func, map=True) == \
|
| 953 |
+
(2*x*(2*x*y + 1), {x*(2*x*y + 1): 2*x*(2*x*y + 1), x*y: 2*x*y})
|
| 954 |
+
assert (y*sin(x)).replace(sin, lambda expr: sin(expr)/y, map=True) == \
|
| 955 |
+
(sin(x), {sin(x): sin(x)/y})
|
| 956 |
+
# if not simultaneous then y*sin(x) -> y*sin(x)/y = sin(x) -> sin(x)/y
|
| 957 |
+
assert (y*sin(x)).replace(sin, lambda expr: sin(expr)/y,
|
| 958 |
+
simultaneous=False) == sin(x)/y
|
| 959 |
+
assert (x**2 + O(x**3)).replace(Pow, lambda b, e: b**e/e
|
| 960 |
+
) == x**2/2 + O(x**3)
|
| 961 |
+
assert (x**2 + O(x**3)).replace(Pow, lambda b, e: b**e/e,
|
| 962 |
+
simultaneous=False) == x**2/2 + O(x**3)
|
| 963 |
+
assert (x*(x*y + 3)).replace(lambda x: x.is_Mul, lambda x: 2 + x) == \
|
| 964 |
+
x*(x*y + 5) + 2
|
| 965 |
+
e = (x*y + 1)*(2*x*y + 1) + 1
|
| 966 |
+
assert e.replace(cond, func, map=True) == (
|
| 967 |
+
2*((2*x*y + 1)*(4*x*y + 1)) + 1,
|
| 968 |
+
{2*x*y: 4*x*y, x*y: 2*x*y, (2*x*y + 1)*(4*x*y + 1):
|
| 969 |
+
2*((2*x*y + 1)*(4*x*y + 1))})
|
| 970 |
+
assert x.replace(x, y) == y
|
| 971 |
+
assert (x + 1).replace(1, 2) == x + 2
|
| 972 |
+
|
| 973 |
+
# https://groups.google.com/forum/#!topic/sympy/8wCgeC95tz0
|
| 974 |
+
n1, n2, n3 = symbols('n1:4', commutative=False)
|
| 975 |
+
assert (n1*f(n2)).replace(f, lambda x: x) == n1*n2
|
| 976 |
+
assert (n3*f(n2)).replace(f, lambda x: x) == n3*n2
|
| 977 |
+
|
| 978 |
+
# issue 16725
|
| 979 |
+
assert S.Zero.replace(Wild('x'), 1) == 1
|
| 980 |
+
# let the user override the default decision of False
|
| 981 |
+
assert S.Zero.replace(Wild('x'), 1, exact=True) == 0
|
| 982 |
+
|
| 983 |
+
|
| 984 |
+
def test_replace_integral():
|
| 985 |
+
# https://github.com/sympy/sympy/issues/27142
|
| 986 |
+
q, p, s, t = symbols('q p s t', cls=Wild)
|
| 987 |
+
a, b, c, d = symbols('a b c d')
|
| 988 |
+
i = Integral(a + b, (b, c, d))
|
| 989 |
+
pattern = Integral(q, (p, s, t))
|
| 990 |
+
assert i.replace(pattern, q) == a + b
|
| 991 |
+
|
| 992 |
+
|
| 993 |
+
def test_find():
|
| 994 |
+
expr = (x + y + 2 + sin(3*x))
|
| 995 |
+
|
| 996 |
+
assert expr.find(lambda u: u.is_Integer) == {S(2), S(3)}
|
| 997 |
+
assert expr.find(lambda u: u.is_Symbol) == {x, y}
|
| 998 |
+
|
| 999 |
+
assert expr.find(lambda u: u.is_Integer, group=True) == {S(2): 1, S(3): 1}
|
| 1000 |
+
assert expr.find(lambda u: u.is_Symbol, group=True) == {x: 2, y: 1}
|
| 1001 |
+
|
| 1002 |
+
assert expr.find(Integer) == {S(2), S(3)}
|
| 1003 |
+
assert expr.find(Symbol) == {x, y}
|
| 1004 |
+
|
| 1005 |
+
assert expr.find(Integer, group=True) == {S(2): 1, S(3): 1}
|
| 1006 |
+
assert expr.find(Symbol, group=True) == {x: 2, y: 1}
|
| 1007 |
+
|
| 1008 |
+
a = Wild('a')
|
| 1009 |
+
|
| 1010 |
+
expr = sin(sin(x)) + sin(x) + cos(x) + x
|
| 1011 |
+
|
| 1012 |
+
assert expr.find(lambda u: type(u) is sin) == {sin(x), sin(sin(x))}
|
| 1013 |
+
assert expr.find(
|
| 1014 |
+
lambda u: type(u) is sin, group=True) == {sin(x): 2, sin(sin(x)): 1}
|
| 1015 |
+
|
| 1016 |
+
assert expr.find(sin(a)) == {sin(x), sin(sin(x))}
|
| 1017 |
+
assert expr.find(sin(a), group=True) == {sin(x): 2, sin(sin(x)): 1}
|
| 1018 |
+
|
| 1019 |
+
assert expr.find(sin) == {sin(x), sin(sin(x))}
|
| 1020 |
+
assert expr.find(sin, group=True) == {sin(x): 2, sin(sin(x)): 1}
|
| 1021 |
+
|
| 1022 |
+
|
| 1023 |
+
def test_count():
|
| 1024 |
+
expr = (x + y + 2 + sin(3*x))
|
| 1025 |
+
|
| 1026 |
+
assert expr.count(lambda u: u.is_Integer) == 2
|
| 1027 |
+
assert expr.count(lambda u: u.is_Symbol) == 3
|
| 1028 |
+
|
| 1029 |
+
assert expr.count(Integer) == 2
|
| 1030 |
+
assert expr.count(Symbol) == 3
|
| 1031 |
+
assert expr.count(2) == 1
|
| 1032 |
+
|
| 1033 |
+
a = Wild('a')
|
| 1034 |
+
|
| 1035 |
+
assert expr.count(sin) == 1
|
| 1036 |
+
assert expr.count(sin(a)) == 1
|
| 1037 |
+
assert expr.count(lambda u: type(u) is sin) == 1
|
| 1038 |
+
|
| 1039 |
+
assert f(x).count(f(x)) == 1
|
| 1040 |
+
assert f(x).diff(x).count(f(x)) == 1
|
| 1041 |
+
assert f(x).diff(x).count(x) == 2
|
| 1042 |
+
|
| 1043 |
+
|
| 1044 |
+
def test_has_basics():
|
| 1045 |
+
p = Wild('p')
|
| 1046 |
+
|
| 1047 |
+
assert sin(x).has(x)
|
| 1048 |
+
assert sin(x).has(sin)
|
| 1049 |
+
assert not sin(x).has(y)
|
| 1050 |
+
assert not sin(x).has(cos)
|
| 1051 |
+
assert f(x).has(x)
|
| 1052 |
+
assert f(x).has(f)
|
| 1053 |
+
assert not f(x).has(y)
|
| 1054 |
+
assert not f(x).has(g)
|
| 1055 |
+
|
| 1056 |
+
assert f(x).diff(x).has(x)
|
| 1057 |
+
assert f(x).diff(x).has(f)
|
| 1058 |
+
assert f(x).diff(x).has(Derivative)
|
| 1059 |
+
assert not f(x).diff(x).has(y)
|
| 1060 |
+
assert not f(x).diff(x).has(g)
|
| 1061 |
+
assert not f(x).diff(x).has(sin)
|
| 1062 |
+
|
| 1063 |
+
assert (x**2).has(Symbol)
|
| 1064 |
+
assert not (x**2).has(Wild)
|
| 1065 |
+
assert (2*p).has(Wild)
|
| 1066 |
+
|
| 1067 |
+
assert not x.has()
|
| 1068 |
+
|
| 1069 |
+
# see issue at https://github.com/sympy/sympy/issues/5190
|
| 1070 |
+
assert not S(1).has(Wild)
|
| 1071 |
+
assert not x.has(Wild)
|
| 1072 |
+
|
| 1073 |
+
|
| 1074 |
+
def test_has_multiple():
|
| 1075 |
+
f = x**2*y + sin(2**t + log(z))
|
| 1076 |
+
|
| 1077 |
+
assert f.has(x)
|
| 1078 |
+
assert f.has(y)
|
| 1079 |
+
assert f.has(z)
|
| 1080 |
+
assert f.has(t)
|
| 1081 |
+
|
| 1082 |
+
assert not f.has(u)
|
| 1083 |
+
|
| 1084 |
+
assert f.has(x, y, z, t)
|
| 1085 |
+
assert f.has(x, y, z, t, u)
|
| 1086 |
+
|
| 1087 |
+
i = Integer(4400)
|
| 1088 |
+
|
| 1089 |
+
assert not i.has(x)
|
| 1090 |
+
|
| 1091 |
+
assert (i*x**i).has(x)
|
| 1092 |
+
assert not (i*y**i).has(x)
|
| 1093 |
+
assert (i*y**i).has(x, y)
|
| 1094 |
+
assert not (i*y**i).has(x, z)
|
| 1095 |
+
|
| 1096 |
+
|
| 1097 |
+
def test_has_piecewise():
|
| 1098 |
+
f = (x*y + 3/y)**(3 + 2)
|
| 1099 |
+
p = Piecewise((g(x), x < -1), (1, x <= 1), (f, True))
|
| 1100 |
+
|
| 1101 |
+
assert p.has(x)
|
| 1102 |
+
assert p.has(y)
|
| 1103 |
+
assert not p.has(z)
|
| 1104 |
+
assert p.has(1)
|
| 1105 |
+
assert p.has(3)
|
| 1106 |
+
assert not p.has(4)
|
| 1107 |
+
assert p.has(f)
|
| 1108 |
+
assert p.has(g)
|
| 1109 |
+
assert not p.has(h)
|
| 1110 |
+
|
| 1111 |
+
|
| 1112 |
+
def test_has_iterative():
|
| 1113 |
+
A, B, C = symbols('A,B,C', commutative=False)
|
| 1114 |
+
f = x*gamma(x)*sin(x)*exp(x*y)*A*B*C*cos(x*A*B)
|
| 1115 |
+
|
| 1116 |
+
assert f.has(x)
|
| 1117 |
+
assert f.has(x*y)
|
| 1118 |
+
assert f.has(x*sin(x))
|
| 1119 |
+
assert not f.has(x*sin(y))
|
| 1120 |
+
assert f.has(x*A)
|
| 1121 |
+
assert f.has(x*A*B)
|
| 1122 |
+
assert not f.has(x*A*C)
|
| 1123 |
+
assert f.has(x*A*B*C)
|
| 1124 |
+
assert not f.has(x*A*C*B)
|
| 1125 |
+
assert f.has(x*sin(x)*A*B*C)
|
| 1126 |
+
assert not f.has(x*sin(x)*A*C*B)
|
| 1127 |
+
assert not f.has(x*sin(y)*A*B*C)
|
| 1128 |
+
assert f.has(x*gamma(x))
|
| 1129 |
+
assert not f.has(x + sin(x))
|
| 1130 |
+
|
| 1131 |
+
assert (x & y & z).has(x & z)
|
| 1132 |
+
|
| 1133 |
+
|
| 1134 |
+
def test_has_integrals():
|
| 1135 |
+
f = Integral(x**2 + sin(x*y*z), (x, 0, x + y + z))
|
| 1136 |
+
|
| 1137 |
+
assert f.has(x + y)
|
| 1138 |
+
assert f.has(x + z)
|
| 1139 |
+
assert f.has(y + z)
|
| 1140 |
+
|
| 1141 |
+
assert f.has(x*y)
|
| 1142 |
+
assert f.has(x*z)
|
| 1143 |
+
assert f.has(y*z)
|
| 1144 |
+
|
| 1145 |
+
assert not f.has(2*x + y)
|
| 1146 |
+
assert not f.has(2*x*y)
|
| 1147 |
+
|
| 1148 |
+
|
| 1149 |
+
def test_has_tuple():
|
| 1150 |
+
assert Tuple(x, y).has(x)
|
| 1151 |
+
assert not Tuple(x, y).has(z)
|
| 1152 |
+
assert Tuple(f(x), g(x)).has(x)
|
| 1153 |
+
assert not Tuple(f(x), g(x)).has(y)
|
| 1154 |
+
assert Tuple(f(x), g(x)).has(f)
|
| 1155 |
+
assert Tuple(f(x), g(x)).has(f(x))
|
| 1156 |
+
# XXX to be deprecated
|
| 1157 |
+
#assert not Tuple(f, g).has(x)
|
| 1158 |
+
#assert Tuple(f, g).has(f)
|
| 1159 |
+
#assert not Tuple(f, g).has(h)
|
| 1160 |
+
assert Tuple(True).has(True)
|
| 1161 |
+
assert Tuple(True).has(S.true)
|
| 1162 |
+
assert not Tuple(True).has(1)
|
| 1163 |
+
|
| 1164 |
+
|
| 1165 |
+
def test_has_units():
|
| 1166 |
+
from sympy.physics.units import m, s
|
| 1167 |
+
|
| 1168 |
+
assert (x*m/s).has(x)
|
| 1169 |
+
assert (x*m/s).has(y, z) is False
|
| 1170 |
+
|
| 1171 |
+
|
| 1172 |
+
def test_has_polys():
|
| 1173 |
+
poly = Poly(x**2 + x*y*sin(z), x, y, t)
|
| 1174 |
+
|
| 1175 |
+
assert poly.has(x)
|
| 1176 |
+
assert poly.has(x, y, z)
|
| 1177 |
+
assert poly.has(x, y, z, t)
|
| 1178 |
+
|
| 1179 |
+
|
| 1180 |
+
def test_has_physics():
|
| 1181 |
+
assert FockState((x, y)).has(x)
|
| 1182 |
+
|
| 1183 |
+
|
| 1184 |
+
def test_as_poly_as_expr():
|
| 1185 |
+
f = x**2 + 2*x*y
|
| 1186 |
+
|
| 1187 |
+
assert f.as_poly().as_expr() == f
|
| 1188 |
+
assert f.as_poly(x, y).as_expr() == f
|
| 1189 |
+
|
| 1190 |
+
assert (f + sin(x)).as_poly(x, y) is None
|
| 1191 |
+
|
| 1192 |
+
p = Poly(f, x, y)
|
| 1193 |
+
|
| 1194 |
+
assert p.as_poly() == p
|
| 1195 |
+
|
| 1196 |
+
# https://github.com/sympy/sympy/issues/20610
|
| 1197 |
+
assert S(2).as_poly() is None
|
| 1198 |
+
assert sqrt(2).as_poly(extension=True) is None
|
| 1199 |
+
|
| 1200 |
+
raises(AttributeError, lambda: Tuple(x, x).as_poly(x))
|
| 1201 |
+
raises(AttributeError, lambda: Tuple(x ** 2, x, y).as_poly(x))
|
| 1202 |
+
|
| 1203 |
+
|
| 1204 |
+
def test_nonzero():
|
| 1205 |
+
assert bool(S.Zero) is False
|
| 1206 |
+
assert bool(S.One) is True
|
| 1207 |
+
assert bool(x) is True
|
| 1208 |
+
assert bool(x + y) is True
|
| 1209 |
+
assert bool(x - x) is False
|
| 1210 |
+
assert bool(x*y) is True
|
| 1211 |
+
assert bool(x*1) is True
|
| 1212 |
+
assert bool(x*0) is False
|
| 1213 |
+
|
| 1214 |
+
|
| 1215 |
+
def test_is_number():
|
| 1216 |
+
assert Float(3.14).is_number is True
|
| 1217 |
+
assert Integer(737).is_number is True
|
| 1218 |
+
assert Rational(3, 2).is_number is True
|
| 1219 |
+
assert Rational(8).is_number is True
|
| 1220 |
+
assert x.is_number is False
|
| 1221 |
+
assert (2*x).is_number is False
|
| 1222 |
+
assert (x + y).is_number is False
|
| 1223 |
+
assert log(2).is_number is True
|
| 1224 |
+
assert log(x).is_number is False
|
| 1225 |
+
assert (2 + log(2)).is_number is True
|
| 1226 |
+
assert (8 + log(2)).is_number is True
|
| 1227 |
+
assert (2 + log(x)).is_number is False
|
| 1228 |
+
assert (8 + log(2) + x).is_number is False
|
| 1229 |
+
assert (1 + x**2/x - x).is_number is True
|
| 1230 |
+
assert Tuple(Integer(1)).is_number is False
|
| 1231 |
+
assert Add(2, x).is_number is False
|
| 1232 |
+
assert Mul(3, 4).is_number is True
|
| 1233 |
+
assert Pow(log(2), 2).is_number is True
|
| 1234 |
+
assert oo.is_number is True
|
| 1235 |
+
g = WildFunction('g')
|
| 1236 |
+
assert g.is_number is False
|
| 1237 |
+
assert (2*g).is_number is False
|
| 1238 |
+
assert (x**2).subs(x, 3).is_number is True
|
| 1239 |
+
|
| 1240 |
+
# test extensibility of .is_number
|
| 1241 |
+
# on subinstances of Basic
|
| 1242 |
+
class A(Basic):
|
| 1243 |
+
pass
|
| 1244 |
+
a = A()
|
| 1245 |
+
assert a.is_number is False
|
| 1246 |
+
|
| 1247 |
+
|
| 1248 |
+
def test_as_coeff_add():
|
| 1249 |
+
assert S(2).as_coeff_add() == (2, ())
|
| 1250 |
+
assert S(3.0).as_coeff_add() == (0, (S(3.0),))
|
| 1251 |
+
assert S(-3.0).as_coeff_add() == (0, (S(-3.0),))
|
| 1252 |
+
assert x.as_coeff_add() == (0, (x,))
|
| 1253 |
+
assert (x - 1).as_coeff_add() == (-1, (x,))
|
| 1254 |
+
assert (x + 1).as_coeff_add() == (1, (x,))
|
| 1255 |
+
assert (x + 2).as_coeff_add() == (2, (x,))
|
| 1256 |
+
assert (x + y).as_coeff_add(y) == (x, (y,))
|
| 1257 |
+
assert (3*x).as_coeff_add(y) == (3*x, ())
|
| 1258 |
+
# don't do expansion
|
| 1259 |
+
e = (x + y)**2
|
| 1260 |
+
assert e.as_coeff_add(y) == (0, (e,))
|
| 1261 |
+
|
| 1262 |
+
|
| 1263 |
+
def test_as_coeff_mul():
|
| 1264 |
+
assert S(2).as_coeff_mul() == (2, ())
|
| 1265 |
+
assert S(3.0).as_coeff_mul() == (1, (S(3.0),))
|
| 1266 |
+
assert S(-3.0).as_coeff_mul() == (-1, (S(3.0),))
|
| 1267 |
+
assert S(-3.0).as_coeff_mul(rational=False) == (-S(3.0), ())
|
| 1268 |
+
assert x.as_coeff_mul() == (1, (x,))
|
| 1269 |
+
assert (-x).as_coeff_mul() == (-1, (x,))
|
| 1270 |
+
assert (2*x).as_coeff_mul() == (2, (x,))
|
| 1271 |
+
assert (x*y).as_coeff_mul(y) == (x, (y,))
|
| 1272 |
+
assert (3 + x).as_coeff_mul() == (1, (3 + x,))
|
| 1273 |
+
assert (3 + x).as_coeff_mul(y) == (3 + x, ())
|
| 1274 |
+
# don't do expansion
|
| 1275 |
+
e = exp(x + y)
|
| 1276 |
+
assert e.as_coeff_mul(y) == (1, (e,))
|
| 1277 |
+
e = 2**(x + y)
|
| 1278 |
+
assert e.as_coeff_mul(y) == (1, (e,))
|
| 1279 |
+
assert (1.1*x).as_coeff_mul(rational=False) == (1.1, (x,))
|
| 1280 |
+
assert (1.1*x).as_coeff_mul() == (1, (1.1, x))
|
| 1281 |
+
assert (-oo*x).as_coeff_mul(rational=True) == (-1, (oo, x))
|
| 1282 |
+
|
| 1283 |
+
|
| 1284 |
+
def test_as_coeff_exponent():
|
| 1285 |
+
assert (3*x**4).as_coeff_exponent(x) == (3, 4)
|
| 1286 |
+
assert (2*x**3).as_coeff_exponent(x) == (2, 3)
|
| 1287 |
+
assert (4*x**2).as_coeff_exponent(x) == (4, 2)
|
| 1288 |
+
assert (6*x**1).as_coeff_exponent(x) == (6, 1)
|
| 1289 |
+
assert (3*x**0).as_coeff_exponent(x) == (3, 0)
|
| 1290 |
+
assert (2*x**0).as_coeff_exponent(x) == (2, 0)
|
| 1291 |
+
assert (1*x**0).as_coeff_exponent(x) == (1, 0)
|
| 1292 |
+
assert (0*x**0).as_coeff_exponent(x) == (0, 0)
|
| 1293 |
+
assert (-1*x**0).as_coeff_exponent(x) == (-1, 0)
|
| 1294 |
+
assert (-2*x**0).as_coeff_exponent(x) == (-2, 0)
|
| 1295 |
+
assert (2*x**3 + pi*x**3).as_coeff_exponent(x) == (2 + pi, 3)
|
| 1296 |
+
assert (x*log(2)/(2*x + pi*x)).as_coeff_exponent(x) == \
|
| 1297 |
+
(log(2)/(2 + pi), 0)
|
| 1298 |
+
# issue 4784
|
| 1299 |
+
D = Derivative
|
| 1300 |
+
fx = D(f(x), x)
|
| 1301 |
+
assert fx.as_coeff_exponent(f(x)) == (fx, 0)
|
| 1302 |
+
|
| 1303 |
+
|
| 1304 |
+
def test_extractions():
|
| 1305 |
+
for base in (2, S.Exp1):
|
| 1306 |
+
assert Pow(base**x, 3, evaluate=False
|
| 1307 |
+
).extract_multiplicatively(base**x) == base**(2*x)
|
| 1308 |
+
assert (base**(5*x)).extract_multiplicatively(
|
| 1309 |
+
base**(3*x)) == base**(2*x)
|
| 1310 |
+
assert ((x*y)**3).extract_multiplicatively(x**2 * y) == x*y**2
|
| 1311 |
+
assert ((x*y)**3).extract_multiplicatively(x**4 * y) is None
|
| 1312 |
+
assert (2*x).extract_multiplicatively(2) == x
|
| 1313 |
+
assert (2*x).extract_multiplicatively(3) is None
|
| 1314 |
+
assert (2*x).extract_multiplicatively(-1) is None
|
| 1315 |
+
assert (S.Half*x).extract_multiplicatively(3) == x/6
|
| 1316 |
+
assert (sqrt(x)).extract_multiplicatively(x) is None
|
| 1317 |
+
assert (sqrt(x)).extract_multiplicatively(1/x) is None
|
| 1318 |
+
assert x.extract_multiplicatively(-x) is None
|
| 1319 |
+
assert (-2 - 4*I).extract_multiplicatively(-2) == 1 + 2*I
|
| 1320 |
+
assert (-2 - 4*I).extract_multiplicatively(3) is None
|
| 1321 |
+
assert (-2*x - 4*y - 8).extract_multiplicatively(-2) == x + 2*y + 4
|
| 1322 |
+
assert (-2*x*y - 4*x**2*y).extract_multiplicatively(-2*y) == 2*x**2 + x
|
| 1323 |
+
assert (2*x*y + 4*x**2*y).extract_multiplicatively(2*y) == 2*x**2 + x
|
| 1324 |
+
assert (-4*y**2*x).extract_multiplicatively(-3*y) is None
|
| 1325 |
+
assert (2*x).extract_multiplicatively(1) == 2*x
|
| 1326 |
+
assert (-oo).extract_multiplicatively(5) is -oo
|
| 1327 |
+
assert (oo).extract_multiplicatively(5) is oo
|
| 1328 |
+
|
| 1329 |
+
assert ((x*y)**3).extract_additively(1) is None
|
| 1330 |
+
assert (x + 1).extract_additively(x) == 1
|
| 1331 |
+
assert (x + 1).extract_additively(2*x) is None
|
| 1332 |
+
assert (x + 1).extract_additively(-x) is None
|
| 1333 |
+
assert (-x + 1).extract_additively(2*x) is None
|
| 1334 |
+
assert (2*x + 3).extract_additively(x) == x + 3
|
| 1335 |
+
assert (2*x + 3).extract_additively(2) == 2*x + 1
|
| 1336 |
+
assert (2*x + 3).extract_additively(3) == 2*x
|
| 1337 |
+
assert (2*x + 3).extract_additively(-2) is None
|
| 1338 |
+
assert (2*x + 3).extract_additively(3*x) is None
|
| 1339 |
+
assert (2*x + 3).extract_additively(2*x) == 3
|
| 1340 |
+
assert x.extract_additively(0) == x
|
| 1341 |
+
assert S(2).extract_additively(x) is None
|
| 1342 |
+
assert S(2.).extract_additively(2.) is S.Zero
|
| 1343 |
+
assert S(2.).extract_additively(2) is S.Zero
|
| 1344 |
+
assert S(2*x + 3).extract_additively(x + 1) == x + 2
|
| 1345 |
+
assert S(2*x + 3).extract_additively(y + 1) is None
|
| 1346 |
+
assert S(2*x - 3).extract_additively(x + 1) is None
|
| 1347 |
+
assert S(2*x - 3).extract_additively(y + z) is None
|
| 1348 |
+
assert ((a + 1)*x*4 + y).extract_additively(x).expand() == \
|
| 1349 |
+
4*a*x + 3*x + y
|
| 1350 |
+
assert ((a + 1)*x*4 + 3*y).extract_additively(x + 2*y).expand() == \
|
| 1351 |
+
4*a*x + 3*x + y
|
| 1352 |
+
assert (y*(x + 1)).extract_additively(x + 1) is None
|
| 1353 |
+
assert ((y + 1)*(x + 1) + 3).extract_additively(x + 1) == \
|
| 1354 |
+
y*(x + 1) + 3
|
| 1355 |
+
assert ((x + y)*(x + 1) + x + y + 3).extract_additively(x + y) == \
|
| 1356 |
+
x*(x + y) + 3
|
| 1357 |
+
assert (x + y + 2*((x + y)*(x + 1)) + 3).extract_additively((x + y)*(x + 1)) == \
|
| 1358 |
+
x + y + (x + 1)*(x + y) + 3
|
| 1359 |
+
assert ((y + 1)*(x + 2*y + 1) + 3).extract_additively(y + 1) == \
|
| 1360 |
+
(x + 2*y)*(y + 1) + 3
|
| 1361 |
+
assert (-x - x*I).extract_additively(-x) == -I*x
|
| 1362 |
+
# extraction does not leave artificats, now
|
| 1363 |
+
assert (4*x*(y + 1) + y).extract_additively(x) == x*(4*y + 3) + y
|
| 1364 |
+
|
| 1365 |
+
n = Symbol("n", integer=True)
|
| 1366 |
+
assert (Integer(-3)).could_extract_minus_sign() is True
|
| 1367 |
+
assert (-n*x + x).could_extract_minus_sign() != \
|
| 1368 |
+
(n*x - x).could_extract_minus_sign()
|
| 1369 |
+
assert (x - y).could_extract_minus_sign() != \
|
| 1370 |
+
(-x + y).could_extract_minus_sign()
|
| 1371 |
+
assert (1 - x - y).could_extract_minus_sign() is True
|
| 1372 |
+
assert (1 - x + y).could_extract_minus_sign() is False
|
| 1373 |
+
assert ((-x - x*y)/y).could_extract_minus_sign() is False
|
| 1374 |
+
assert ((x + x*y)/(-y)).could_extract_minus_sign() is True
|
| 1375 |
+
assert ((x + x*y)/y).could_extract_minus_sign() is False
|
| 1376 |
+
assert ((-x - y)/(x + y)).could_extract_minus_sign() is False
|
| 1377 |
+
|
| 1378 |
+
class sign_invariant(Function, Expr):
|
| 1379 |
+
nargs = 1
|
| 1380 |
+
def __neg__(self):
|
| 1381 |
+
return self
|
| 1382 |
+
foo = sign_invariant(x)
|
| 1383 |
+
assert foo == -foo
|
| 1384 |
+
assert foo.could_extract_minus_sign() is False
|
| 1385 |
+
assert (x - y).could_extract_minus_sign() is False
|
| 1386 |
+
assert (-x + y).could_extract_minus_sign() is True
|
| 1387 |
+
assert (x - 1).could_extract_minus_sign() is False
|
| 1388 |
+
assert (1 - x).could_extract_minus_sign() is True
|
| 1389 |
+
assert (sqrt(2) - 1).could_extract_minus_sign() is True
|
| 1390 |
+
assert (1 - sqrt(2)).could_extract_minus_sign() is False
|
| 1391 |
+
# check that result is canonical
|
| 1392 |
+
eq = (3*x + 15*y).extract_multiplicatively(3)
|
| 1393 |
+
assert eq.args == eq.func(*eq.args).args
|
| 1394 |
+
|
| 1395 |
+
|
| 1396 |
+
def test_nan_extractions():
|
| 1397 |
+
for r in (1, 0, I, nan):
|
| 1398 |
+
assert nan.extract_additively(r) is None
|
| 1399 |
+
assert nan.extract_multiplicatively(r) is None
|
| 1400 |
+
|
| 1401 |
+
|
| 1402 |
+
def test_coeff():
|
| 1403 |
+
assert (x + 1).coeff(x + 1) == 1
|
| 1404 |
+
assert (3*x).coeff(0) == 0
|
| 1405 |
+
assert (z*(1 + x)*x**2).coeff(1 + x) == z*x**2
|
| 1406 |
+
assert (1 + 2*x*x**(1 + x)).coeff(x*x**(1 + x)) == 2
|
| 1407 |
+
assert (1 + 2*x**(y + z)).coeff(x**(y + z)) == 2
|
| 1408 |
+
assert (3 + 2*x + 4*x**2).coeff(1) == 0
|
| 1409 |
+
assert (3 + 2*x + 4*x**2).coeff(-1) == 0
|
| 1410 |
+
assert (3 + 2*x + 4*x**2).coeff(x) == 2
|
| 1411 |
+
assert (3 + 2*x + 4*x**2).coeff(x**2) == 4
|
| 1412 |
+
assert (3 + 2*x + 4*x**2).coeff(x**3) == 0
|
| 1413 |
+
|
| 1414 |
+
assert (-x/8 + x*y).coeff(x) == Rational(-1, 8) + y
|
| 1415 |
+
assert (-x/8 + x*y).coeff(-x) == S.One/8
|
| 1416 |
+
assert (4*x).coeff(2*x) == 0
|
| 1417 |
+
assert (2*x).coeff(2*x) == 1
|
| 1418 |
+
assert (-oo*x).coeff(x*oo) == -1
|
| 1419 |
+
assert (10*x).coeff(x, 0) == 0
|
| 1420 |
+
assert (10*x).coeff(10*x, 0) == 0
|
| 1421 |
+
|
| 1422 |
+
n1, n2 = symbols('n1 n2', commutative=False)
|
| 1423 |
+
assert (n1*n2).coeff(n1) == 1
|
| 1424 |
+
assert (n1*n2).coeff(n2) == n1
|
| 1425 |
+
assert (n1*n2 + x*n1).coeff(n1) == 1 # 1*n1*(n2+x)
|
| 1426 |
+
assert (n2*n1 + x*n1).coeff(n1) == n2 + x
|
| 1427 |
+
assert (n2*n1 + x*n1**2).coeff(n1) == n2
|
| 1428 |
+
assert (n1**x).coeff(n1) == 0
|
| 1429 |
+
assert (n1*n2 + n2*n1).coeff(n1) == 0
|
| 1430 |
+
assert (2*(n1 + n2)*n2).coeff(n1 + n2, right=1) == n2
|
| 1431 |
+
assert (2*(n1 + n2)*n2).coeff(n1 + n2, right=0) == 2
|
| 1432 |
+
|
| 1433 |
+
assert (2*f(x) + 3*f(x).diff(x)).coeff(f(x)) == 2
|
| 1434 |
+
|
| 1435 |
+
expr = z*(x + y)**2
|
| 1436 |
+
expr2 = z*(x + y)**2 + z*(2*x + 2*y)**2
|
| 1437 |
+
assert expr.coeff(z) == (x + y)**2
|
| 1438 |
+
assert expr.coeff(x + y) == 0
|
| 1439 |
+
assert expr2.coeff(z) == (x + y)**2 + (2*x + 2*y)**2
|
| 1440 |
+
|
| 1441 |
+
assert (x + y + 3*z).coeff(1) == x + y
|
| 1442 |
+
assert (-x + 2*y).coeff(-1) == x
|
| 1443 |
+
assert (x - 2*y).coeff(-1) == 2*y
|
| 1444 |
+
assert (3 + 2*x + 4*x**2).coeff(1) == 0
|
| 1445 |
+
assert (-x - 2*y).coeff(2) == -y
|
| 1446 |
+
assert (x + sqrt(2)*x).coeff(sqrt(2)) == x
|
| 1447 |
+
assert (3 + 2*x + 4*x**2).coeff(x) == 2
|
| 1448 |
+
assert (3 + 2*x + 4*x**2).coeff(x**2) == 4
|
| 1449 |
+
assert (3 + 2*x + 4*x**2).coeff(x**3) == 0
|
| 1450 |
+
assert (z*(x + y)**2).coeff((x + y)**2) == z
|
| 1451 |
+
assert (z*(x + y)**2).coeff(x + y) == 0
|
| 1452 |
+
assert (2 + 2*x + (x + 1)*y).coeff(x + 1) == y
|
| 1453 |
+
|
| 1454 |
+
assert (x + 2*y + 3).coeff(1) == x
|
| 1455 |
+
assert (x + 2*y + 3).coeff(x, 0) == 2*y + 3
|
| 1456 |
+
assert (x**2 + 2*y + 3*x).coeff(x**2, 0) == 2*y + 3*x
|
| 1457 |
+
assert x.coeff(0, 0) == 0
|
| 1458 |
+
assert x.coeff(x, 0) == 0
|
| 1459 |
+
|
| 1460 |
+
n, m, o, l = symbols('n m o l', commutative=False)
|
| 1461 |
+
assert n.coeff(n) == 1
|
| 1462 |
+
assert y.coeff(n) == 0
|
| 1463 |
+
assert (3*n).coeff(n) == 3
|
| 1464 |
+
assert (2 + n).coeff(x*m) == 0
|
| 1465 |
+
assert (2*x*n*m).coeff(x) == 2*n*m
|
| 1466 |
+
assert (2 + n).coeff(x*m*n + y) == 0
|
| 1467 |
+
assert (2*x*n*m).coeff(3*n) == 0
|
| 1468 |
+
assert (n*m + m*n*m).coeff(n) == 1 + m
|
| 1469 |
+
assert (n*m + m*n*m).coeff(n, right=True) == m # = (1 + m)*n*m
|
| 1470 |
+
assert (n*m + m*n).coeff(n) == 0
|
| 1471 |
+
assert (n*m + o*m*n).coeff(m*n) == o
|
| 1472 |
+
assert (n*m + o*m*n).coeff(m*n, right=True) == 1
|
| 1473 |
+
assert (n*m + n*m*n).coeff(n*m, right=True) == 1 + n # = n*m*(n + 1)
|
| 1474 |
+
|
| 1475 |
+
assert (x*y).coeff(z, 0) == x*y
|
| 1476 |
+
|
| 1477 |
+
assert (x*n + y*n + z*m).coeff(n) == x + y
|
| 1478 |
+
assert (n*m + n*o + o*l).coeff(n, right=True) == m + o
|
| 1479 |
+
assert (x*n*m*n + y*n*m*o + z*l).coeff(m, right=True) == x*n + y*o
|
| 1480 |
+
assert (x*n*m*n + x*n*m*o + z*l).coeff(m, right=True) == n + o
|
| 1481 |
+
assert (x*n*m*n + x*n*m*o + z*l).coeff(m) == x*n
|
| 1482 |
+
|
| 1483 |
+
|
| 1484 |
+
def test_coeff2():
|
| 1485 |
+
r, kappa = symbols('r, kappa')
|
| 1486 |
+
psi = Function("psi")
|
| 1487 |
+
g = 1/r**2 * (2*r*psi(r).diff(r, 1) + r**2 * psi(r).diff(r, 2))
|
| 1488 |
+
g = g.expand()
|
| 1489 |
+
assert g.coeff(psi(r).diff(r)) == 2/r
|
| 1490 |
+
|
| 1491 |
+
|
| 1492 |
+
def test_coeff2_0():
|
| 1493 |
+
r, kappa = symbols('r, kappa')
|
| 1494 |
+
psi = Function("psi")
|
| 1495 |
+
g = 1/r**2 * (2*r*psi(r).diff(r, 1) + r**2 * psi(r).diff(r, 2))
|
| 1496 |
+
g = g.expand()
|
| 1497 |
+
|
| 1498 |
+
assert g.coeff(psi(r).diff(r, 2)) == 1
|
| 1499 |
+
|
| 1500 |
+
|
| 1501 |
+
def test_coeff_expand():
|
| 1502 |
+
expr = z*(x + y)**2
|
| 1503 |
+
expr2 = z*(x + y)**2 + z*(2*x + 2*y)**2
|
| 1504 |
+
assert expr.coeff(z) == (x + y)**2
|
| 1505 |
+
assert expr2.coeff(z) == (x + y)**2 + (2*x + 2*y)**2
|
| 1506 |
+
|
| 1507 |
+
|
| 1508 |
+
def test_integrate():
|
| 1509 |
+
assert x.integrate(x) == x**2/2
|
| 1510 |
+
assert x.integrate((x, 0, 1)) == S.Half
|
| 1511 |
+
|
| 1512 |
+
|
| 1513 |
+
def test_as_base_exp():
|
| 1514 |
+
assert x.as_base_exp() == (x, S.One)
|
| 1515 |
+
assert (x*y*z).as_base_exp() == (x*y*z, S.One)
|
| 1516 |
+
assert (x + y + z).as_base_exp() == (x + y + z, S.One)
|
| 1517 |
+
assert ((x + y)**z).as_base_exp() == (x + y, z)
|
| 1518 |
+
assert (x**2*y**2).as_base_exp() == (x*y, 2)
|
| 1519 |
+
assert (x**z*y**z).as_base_exp() == (x**z*y**z, S.One)
|
| 1520 |
+
|
| 1521 |
+
|
| 1522 |
+
def test_issue_4963():
|
| 1523 |
+
assert hasattr(Mul(x, y), "is_commutative")
|
| 1524 |
+
assert hasattr(Mul(x, y, evaluate=False), "is_commutative")
|
| 1525 |
+
assert hasattr(Pow(x, y), "is_commutative")
|
| 1526 |
+
assert hasattr(Pow(x, y, evaluate=False), "is_commutative")
|
| 1527 |
+
expr = Mul(Pow(2, 2, evaluate=False), 3, evaluate=False) + 1
|
| 1528 |
+
assert hasattr(expr, "is_commutative")
|
| 1529 |
+
|
| 1530 |
+
|
| 1531 |
+
def test_action_verbs():
|
| 1532 |
+
assert nsimplify(1/(exp(3*pi*x/5) + 1)) == \
|
| 1533 |
+
(1/(exp(3*pi*x/5) + 1)).nsimplify()
|
| 1534 |
+
assert ratsimp(1/x + 1/y) == (1/x + 1/y).ratsimp()
|
| 1535 |
+
assert trigsimp(log(x), deep=True) == (log(x)).trigsimp(deep=True)
|
| 1536 |
+
assert radsimp(1/(2 + sqrt(2))) == (1/(2 + sqrt(2))).radsimp()
|
| 1537 |
+
assert radsimp(1/(a + b*sqrt(c)), symbolic=False) == \
|
| 1538 |
+
(1/(a + b*sqrt(c))).radsimp(symbolic=False)
|
| 1539 |
+
assert powsimp(x**y*x**z*y**z, combine='all') == \
|
| 1540 |
+
(x**y*x**z*y**z).powsimp(combine='all')
|
| 1541 |
+
assert (x**t*y**t).powsimp(force=True) == (x*y)**t
|
| 1542 |
+
assert simplify(x**y*x**z*y**z) == (x**y*x**z*y**z).simplify()
|
| 1543 |
+
assert together(1/x + 1/y) == (1/x + 1/y).together()
|
| 1544 |
+
assert collect(a*x**2 + b*x**2 + a*x - b*x + c, x) == \
|
| 1545 |
+
(a*x**2 + b*x**2 + a*x - b*x + c).collect(x)
|
| 1546 |
+
assert apart(y/(y + 2)/(y + 1), y) == (y/(y + 2)/(y + 1)).apart(y)
|
| 1547 |
+
assert combsimp(y/(x + 2)/(x + 1)) == (y/(x + 2)/(x + 1)).combsimp()
|
| 1548 |
+
assert gammasimp(gamma(x)/gamma(x-5)) == (gamma(x)/gamma(x-5)).gammasimp()
|
| 1549 |
+
assert factor(x**2 + 5*x + 6) == (x**2 + 5*x + 6).factor()
|
| 1550 |
+
assert refine(sqrt(x**2)) == sqrt(x**2).refine()
|
| 1551 |
+
assert cancel((x**2 + 5*x + 6)/(x + 2)) == ((x**2 + 5*x + 6)/(x + 2)).cancel()
|
| 1552 |
+
|
| 1553 |
+
|
| 1554 |
+
def test_as_powers_dict():
|
| 1555 |
+
assert x.as_powers_dict() == {x: 1}
|
| 1556 |
+
assert (x**y*z).as_powers_dict() == {x: y, z: 1}
|
| 1557 |
+
assert Mul(2, 2, evaluate=False).as_powers_dict() == {S(2): S(2)}
|
| 1558 |
+
assert (x*y).as_powers_dict()[z] == 0
|
| 1559 |
+
assert (x + y).as_powers_dict()[z] == 0
|
| 1560 |
+
|
| 1561 |
+
|
| 1562 |
+
def test_as_coefficients_dict():
|
| 1563 |
+
check = [S.One, x, y, x*y, 1]
|
| 1564 |
+
assert [Add(3*x, 2*x, y, 3).as_coefficients_dict()[i] for i in check] == \
|
| 1565 |
+
[3, 5, 1, 0, 3]
|
| 1566 |
+
assert [Add(3*x, 2*x, y, 3, evaluate=False).as_coefficients_dict()[i]
|
| 1567 |
+
for i in check] == [3, 5, 1, 0, 3]
|
| 1568 |
+
assert [(3*x*y).as_coefficients_dict()[i] for i in check] == \
|
| 1569 |
+
[0, 0, 0, 3, 0]
|
| 1570 |
+
assert [(3.0*x*y).as_coefficients_dict()[i] for i in check] == \
|
| 1571 |
+
[0, 0, 0, 3.0, 0]
|
| 1572 |
+
assert (3.0*x*y).as_coefficients_dict()[3.0*x*y] == 0
|
| 1573 |
+
eq = x*(x + 1)*a + x*b + c/x
|
| 1574 |
+
assert eq.as_coefficients_dict(x) == {x: b, 1/x: c,
|
| 1575 |
+
x*(x + 1): a}
|
| 1576 |
+
assert eq.expand().as_coefficients_dict(x) == {x**2: a, x: a + b, 1/x: c}
|
| 1577 |
+
assert x.as_coefficients_dict() == {x: S.One}
|
| 1578 |
+
|
| 1579 |
+
|
| 1580 |
+
def test_args_cnc():
|
| 1581 |
+
A = symbols('A', commutative=False)
|
| 1582 |
+
assert (x + A).args_cnc() == \
|
| 1583 |
+
[[], [x + A]]
|
| 1584 |
+
assert (x + a).args_cnc() == \
|
| 1585 |
+
[[a + x], []]
|
| 1586 |
+
assert (x*a).args_cnc() == \
|
| 1587 |
+
[[a, x], []]
|
| 1588 |
+
assert (x*y*A*(A + 1)).args_cnc(cset=True) == \
|
| 1589 |
+
[{x, y}, [A, 1 + A]]
|
| 1590 |
+
assert Mul(x, x, evaluate=False).args_cnc(cset=True, warn=False) == \
|
| 1591 |
+
[{x}, []]
|
| 1592 |
+
assert Mul(x, x**2, evaluate=False).args_cnc(cset=True, warn=False) == \
|
| 1593 |
+
[{x, x**2}, []]
|
| 1594 |
+
raises(ValueError, lambda: Mul(x, x, evaluate=False).args_cnc(cset=True))
|
| 1595 |
+
assert Mul(x, y, x, evaluate=False).args_cnc() == \
|
| 1596 |
+
[[x, y, x], []]
|
| 1597 |
+
# always split -1 from leading number
|
| 1598 |
+
assert (-1.*x).args_cnc() == [[-1, 1.0, x], []]
|
| 1599 |
+
|
| 1600 |
+
|
| 1601 |
+
def test_new_rawargs():
|
| 1602 |
+
n = Symbol('n', commutative=False)
|
| 1603 |
+
a = x + n
|
| 1604 |
+
assert a.is_commutative is False
|
| 1605 |
+
assert a._new_rawargs(x).is_commutative
|
| 1606 |
+
assert a._new_rawargs(x, y).is_commutative
|
| 1607 |
+
assert a._new_rawargs(x, n).is_commutative is False
|
| 1608 |
+
assert a._new_rawargs(x, y, n).is_commutative is False
|
| 1609 |
+
m = x*n
|
| 1610 |
+
assert m.is_commutative is False
|
| 1611 |
+
assert m._new_rawargs(x).is_commutative
|
| 1612 |
+
assert m._new_rawargs(n).is_commutative is False
|
| 1613 |
+
assert m._new_rawargs(x, y).is_commutative
|
| 1614 |
+
assert m._new_rawargs(x, n).is_commutative is False
|
| 1615 |
+
assert m._new_rawargs(x, y, n).is_commutative is False
|
| 1616 |
+
|
| 1617 |
+
assert m._new_rawargs(x, n, reeval=False).is_commutative is False
|
| 1618 |
+
assert m._new_rawargs(S.One) is S.One
|
| 1619 |
+
|
| 1620 |
+
|
| 1621 |
+
def test_issue_5226():
|
| 1622 |
+
assert Add(evaluate=False) == 0
|
| 1623 |
+
assert Mul(evaluate=False) == 1
|
| 1624 |
+
assert Mul(x + y, evaluate=False).is_Add
|
| 1625 |
+
|
| 1626 |
+
|
| 1627 |
+
def test_free_symbols():
|
| 1628 |
+
# free_symbols should return the free symbols of an object
|
| 1629 |
+
assert S.One.free_symbols == set()
|
| 1630 |
+
assert x.free_symbols == {x}
|
| 1631 |
+
assert Integral(x, (x, 1, y)).free_symbols == {y}
|
| 1632 |
+
assert (-Integral(x, (x, 1, y))).free_symbols == {y}
|
| 1633 |
+
assert meter.free_symbols == set()
|
| 1634 |
+
assert (meter**x).free_symbols == {x}
|
| 1635 |
+
|
| 1636 |
+
|
| 1637 |
+
def test_has_free():
|
| 1638 |
+
assert x.has_free(x)
|
| 1639 |
+
assert not x.has_free(y)
|
| 1640 |
+
assert (x + y).has_free(x)
|
| 1641 |
+
assert (x + y).has_free(*(x, z))
|
| 1642 |
+
assert f(x).has_free(x)
|
| 1643 |
+
assert f(x).has_free(f(x))
|
| 1644 |
+
assert Integral(f(x), (f(x), 1, y)).has_free(y)
|
| 1645 |
+
assert not Integral(f(x), (f(x), 1, y)).has_free(x)
|
| 1646 |
+
assert not Integral(f(x), (f(x), 1, y)).has_free(f(x))
|
| 1647 |
+
# simple extraction
|
| 1648 |
+
assert (x + 1 + y).has_free(x + 1)
|
| 1649 |
+
assert not (x + 2 + y).has_free(x + 1)
|
| 1650 |
+
assert (2 + 3*x*y).has_free(3*x)
|
| 1651 |
+
raises(TypeError, lambda: x.has_free({x, y}))
|
| 1652 |
+
s = FiniteSet(1, 2)
|
| 1653 |
+
assert Piecewise((s, x > 3), (4, True)).has_free(s)
|
| 1654 |
+
assert not Piecewise((1, x > 3), (4, True)).has_free(s)
|
| 1655 |
+
# can't make set of these, but fallback will handle
|
| 1656 |
+
raises(TypeError, lambda: x.has_free(y, []))
|
| 1657 |
+
|
| 1658 |
+
|
| 1659 |
+
def test_has_xfree():
|
| 1660 |
+
assert (x + 1).has_xfree({x})
|
| 1661 |
+
assert ((x + 1)**2).has_xfree({x + 1})
|
| 1662 |
+
assert not (x + y + 1).has_xfree({x + 1})
|
| 1663 |
+
raises(TypeError, lambda: x.has_xfree(x))
|
| 1664 |
+
raises(TypeError, lambda: x.has_xfree([x]))
|
| 1665 |
+
|
| 1666 |
+
|
| 1667 |
+
def test_issue_5300():
|
| 1668 |
+
x = Symbol('x', commutative=False)
|
| 1669 |
+
assert x*sqrt(2)/sqrt(6) == x*sqrt(3)/3
|
| 1670 |
+
|
| 1671 |
+
|
| 1672 |
+
def test_floordiv():
|
| 1673 |
+
from sympy.functions.elementary.integers import floor
|
| 1674 |
+
assert x // y == floor(x / y)
|
| 1675 |
+
|
| 1676 |
+
|
| 1677 |
+
def test_as_coeff_Mul():
|
| 1678 |
+
assert Integer(3).as_coeff_Mul() == (Integer(3), Integer(1))
|
| 1679 |
+
assert Rational(3, 4).as_coeff_Mul() == (Rational(3, 4), Integer(1))
|
| 1680 |
+
assert Float(5.0).as_coeff_Mul() == (Float(5.0), Integer(1))
|
| 1681 |
+
assert Float(0.0).as_coeff_Mul() == (Float(0.0), Integer(1))
|
| 1682 |
+
|
| 1683 |
+
assert (Integer(3)*x).as_coeff_Mul() == (Integer(3), x)
|
| 1684 |
+
assert (Rational(3, 4)*x).as_coeff_Mul() == (Rational(3, 4), x)
|
| 1685 |
+
assert (Float(5.0)*x).as_coeff_Mul() == (Float(5.0), x)
|
| 1686 |
+
|
| 1687 |
+
assert (Integer(3)*x*y).as_coeff_Mul() == (Integer(3), x*y)
|
| 1688 |
+
assert (Rational(3, 4)*x*y).as_coeff_Mul() == (Rational(3, 4), x*y)
|
| 1689 |
+
assert (Float(5.0)*x*y).as_coeff_Mul() == (Float(5.0), x*y)
|
| 1690 |
+
|
| 1691 |
+
assert (x).as_coeff_Mul() == (S.One, x)
|
| 1692 |
+
assert (x*y).as_coeff_Mul() == (S.One, x*y)
|
| 1693 |
+
assert (-oo*x).as_coeff_Mul(rational=True) == (-1, oo*x)
|
| 1694 |
+
|
| 1695 |
+
|
| 1696 |
+
def test_as_coeff_Add():
|
| 1697 |
+
assert Integer(3).as_coeff_Add() == (Integer(3), Integer(0))
|
| 1698 |
+
assert Rational(3, 4).as_coeff_Add() == (Rational(3, 4), Integer(0))
|
| 1699 |
+
assert Float(5.0).as_coeff_Add() == (Float(5.0), Integer(0))
|
| 1700 |
+
|
| 1701 |
+
assert (Integer(3) + x).as_coeff_Add() == (Integer(3), x)
|
| 1702 |
+
assert (Rational(3, 4) + x).as_coeff_Add() == (Rational(3, 4), x)
|
| 1703 |
+
assert (Float(5.0) + x).as_coeff_Add() == (Float(5.0), x)
|
| 1704 |
+
assert (Float(5.0) + x).as_coeff_Add(rational=True) == (0, Float(5.0) + x)
|
| 1705 |
+
|
| 1706 |
+
assert (Integer(3) + x + y).as_coeff_Add() == (Integer(3), x + y)
|
| 1707 |
+
assert (Rational(3, 4) + x + y).as_coeff_Add() == (Rational(3, 4), x + y)
|
| 1708 |
+
assert (Float(5.0) + x + y).as_coeff_Add() == (Float(5.0), x + y)
|
| 1709 |
+
|
| 1710 |
+
assert (x).as_coeff_Add() == (S.Zero, x)
|
| 1711 |
+
assert (x*y).as_coeff_Add() == (S.Zero, x*y)
|
| 1712 |
+
|
| 1713 |
+
|
| 1714 |
+
def test_expr_sorting():
|
| 1715 |
+
|
| 1716 |
+
exprs = [1/x**2, 1/x, sqrt(sqrt(x)), sqrt(x), x, sqrt(x)**3, x**2]
|
| 1717 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1718 |
+
|
| 1719 |
+
exprs = [x, 2*x, 2*x**2, 2*x**3, x**n, 2*x**n, sin(x), sin(x)**n,
|
| 1720 |
+
sin(x**2), cos(x), cos(x**2), tan(x)]
|
| 1721 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1722 |
+
|
| 1723 |
+
exprs = [x + 1, x**2 + x + 1, x**3 + x**2 + x + 1]
|
| 1724 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1725 |
+
|
| 1726 |
+
exprs = [S(4), x - 3*I/2, x + 3*I/2, x - 4*I + 1, x + 4*I + 1]
|
| 1727 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1728 |
+
|
| 1729 |
+
exprs = [f(1), f(2), f(3), f(1, 2, 3), g(1), g(2), g(3), g(1, 2, 3)]
|
| 1730 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1731 |
+
|
| 1732 |
+
exprs = [f(x), g(x), exp(x), sin(x), cos(x), factorial(x)]
|
| 1733 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1734 |
+
|
| 1735 |
+
exprs = [Tuple(x, y), Tuple(x, z), Tuple(x, y, z)]
|
| 1736 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1737 |
+
|
| 1738 |
+
exprs = [[3], [1, 2]]
|
| 1739 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1740 |
+
|
| 1741 |
+
exprs = [[1, 2], [2, 3]]
|
| 1742 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1743 |
+
|
| 1744 |
+
exprs = [[1, 2], [1, 2, 3]]
|
| 1745 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1746 |
+
|
| 1747 |
+
exprs = [{x: -y}, {x: y}]
|
| 1748 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1749 |
+
|
| 1750 |
+
exprs = [{1}, {1, 2}]
|
| 1751 |
+
assert sorted(exprs, key=default_sort_key) == exprs
|
| 1752 |
+
|
| 1753 |
+
a, b = exprs = [Dummy('x'), Dummy('x')]
|
| 1754 |
+
assert sorted([b, a], key=default_sort_key) == exprs
|
| 1755 |
+
|
| 1756 |
+
|
| 1757 |
+
def test_as_ordered_factors():
|
| 1758 |
+
|
| 1759 |
+
assert x.as_ordered_factors() == [x]
|
| 1760 |
+
assert (2*x*x**n*sin(x)*cos(x)).as_ordered_factors() \
|
| 1761 |
+
== [Integer(2), x, x**n, sin(x), cos(x)]
|
| 1762 |
+
|
| 1763 |
+
args = [f(1), f(2), f(3), f(1, 2, 3), g(1), g(2), g(3), g(1, 2, 3)]
|
| 1764 |
+
expr = Mul(*args)
|
| 1765 |
+
|
| 1766 |
+
assert expr.as_ordered_factors() == args
|
| 1767 |
+
|
| 1768 |
+
A, B = symbols('A,B', commutative=False)
|
| 1769 |
+
|
| 1770 |
+
assert (A*B).as_ordered_factors() == [A, B]
|
| 1771 |
+
assert (B*A).as_ordered_factors() == [B, A]
|
| 1772 |
+
|
| 1773 |
+
|
| 1774 |
+
def test_as_ordered_terms():
|
| 1775 |
+
|
| 1776 |
+
assert x.as_ordered_terms() == [x]
|
| 1777 |
+
assert (sin(x)**2*cos(x) + sin(x)*cos(x)**2 + 1).as_ordered_terms() \
|
| 1778 |
+
== [sin(x)**2*cos(x), sin(x)*cos(x)**2, 1]
|
| 1779 |
+
|
| 1780 |
+
args = [f(1), f(2), f(3), f(1, 2, 3), g(1), g(2), g(3), g(1, 2, 3)]
|
| 1781 |
+
expr = Add(*args)
|
| 1782 |
+
|
| 1783 |
+
assert expr.as_ordered_terms() == args
|
| 1784 |
+
|
| 1785 |
+
assert (1 + 4*sqrt(3)*pi*x).as_ordered_terms() == [4*pi*x*sqrt(3), 1]
|
| 1786 |
+
|
| 1787 |
+
assert ( 2 + 3*I).as_ordered_terms() == [2, 3*I]
|
| 1788 |
+
assert (-2 + 3*I).as_ordered_terms() == [-2, 3*I]
|
| 1789 |
+
assert ( 2 - 3*I).as_ordered_terms() == [2, -3*I]
|
| 1790 |
+
assert (-2 - 3*I).as_ordered_terms() == [-2, -3*I]
|
| 1791 |
+
|
| 1792 |
+
assert ( 4 + 3*I).as_ordered_terms() == [4, 3*I]
|
| 1793 |
+
assert (-4 + 3*I).as_ordered_terms() == [-4, 3*I]
|
| 1794 |
+
assert ( 4 - 3*I).as_ordered_terms() == [4, -3*I]
|
| 1795 |
+
assert (-4 - 3*I).as_ordered_terms() == [-4, -3*I]
|
| 1796 |
+
|
| 1797 |
+
e = x**2*y**2 + x*y**4 + y + 2
|
| 1798 |
+
|
| 1799 |
+
assert e.as_ordered_terms(order="lex") == [x**2*y**2, x*y**4, y, 2]
|
| 1800 |
+
assert e.as_ordered_terms(order="grlex") == [x*y**4, x**2*y**2, y, 2]
|
| 1801 |
+
assert e.as_ordered_terms(order="rev-lex") == [2, y, x*y**4, x**2*y**2]
|
| 1802 |
+
assert e.as_ordered_terms(order="rev-grlex") == [2, y, x**2*y**2, x*y**4]
|
| 1803 |
+
|
| 1804 |
+
k = symbols('k')
|
| 1805 |
+
assert k.as_ordered_terms(data=True) == ([(k, ((1.0, 0.0), (1,), ()))], [k])
|
| 1806 |
+
|
| 1807 |
+
|
| 1808 |
+
def test_sort_key_atomic_expr():
|
| 1809 |
+
from sympy.physics.units import m, s
|
| 1810 |
+
assert sorted([-m, s], key=lambda arg: arg.sort_key()) == [-m, s]
|
| 1811 |
+
|
| 1812 |
+
|
| 1813 |
+
def test_eval_interval():
|
| 1814 |
+
assert exp(x)._eval_interval(*Tuple(x, 0, 1)) == exp(1) - exp(0)
|
| 1815 |
+
|
| 1816 |
+
# issue 4199
|
| 1817 |
+
a = x/y
|
| 1818 |
+
raises(NotImplementedError, lambda: a._eval_interval(x, S.Zero, oo)._eval_interval(y, oo, S.Zero))
|
| 1819 |
+
raises(NotImplementedError, lambda: a._eval_interval(x, S.Zero, oo)._eval_interval(y, S.Zero, oo))
|
| 1820 |
+
a = x - y
|
| 1821 |
+
raises(NotImplementedError, lambda: a._eval_interval(x, S.One, oo)._eval_interval(y, oo, S.One))
|
| 1822 |
+
raises(ValueError, lambda: x._eval_interval(x, None, None))
|
| 1823 |
+
a = -y*Heaviside(x - y)
|
| 1824 |
+
assert a._eval_interval(x, -oo, oo) == -y
|
| 1825 |
+
assert a._eval_interval(x, oo, -oo) == y
|
| 1826 |
+
|
| 1827 |
+
|
| 1828 |
+
def test_eval_interval_zoo():
|
| 1829 |
+
# Test that limit is used when zoo is returned
|
| 1830 |
+
assert Si(1/x)._eval_interval(x, S.Zero, S.One) == -pi/2 + Si(1)
|
| 1831 |
+
|
| 1832 |
+
|
| 1833 |
+
def test_primitive():
|
| 1834 |
+
assert (3*(x + 1)**2).primitive() == (3, (x + 1)**2)
|
| 1835 |
+
assert (6*x + 2).primitive() == (2, 3*x + 1)
|
| 1836 |
+
assert (x/2 + 3).primitive() == (S.Half, x + 6)
|
| 1837 |
+
eq = (6*x + 2)*(x/2 + 3)
|
| 1838 |
+
assert eq.primitive()[0] == 1
|
| 1839 |
+
eq = (2 + 2*x)**2
|
| 1840 |
+
assert eq.primitive()[0] == 1
|
| 1841 |
+
assert (4.0*x).primitive() == (1, 4.0*x)
|
| 1842 |
+
assert (4.0*x + y/2).primitive() == (S.Half, 8.0*x + y)
|
| 1843 |
+
assert (-2*x).primitive() == (2, -x)
|
| 1844 |
+
assert Add(5*z/7, 0.5*x, 3*y/2, evaluate=False).primitive() == \
|
| 1845 |
+
(S.One/14, 7.0*x + 21*y + 10*z)
|
| 1846 |
+
for i in [S.Infinity, S.NegativeInfinity, S.ComplexInfinity]:
|
| 1847 |
+
assert (i + x/3).primitive() == \
|
| 1848 |
+
(S.One/3, i + x)
|
| 1849 |
+
assert (S.Infinity + 2*x/3 + 4*y/7).primitive() == \
|
| 1850 |
+
(S.One/21, 14*x + 12*y + oo)
|
| 1851 |
+
assert S.Zero.primitive() == (S.One, S.Zero)
|
| 1852 |
+
|
| 1853 |
+
|
| 1854 |
+
def test_issue_5843():
|
| 1855 |
+
a = 1 + x
|
| 1856 |
+
assert (2*a).extract_multiplicatively(a) == 2
|
| 1857 |
+
assert (4*a).extract_multiplicatively(2*a) == 2
|
| 1858 |
+
assert ((3*a)*(2*a)).extract_multiplicatively(a) == 6*a
|
| 1859 |
+
|
| 1860 |
+
|
| 1861 |
+
def test_is_constant():
|
| 1862 |
+
from sympy.solvers.solvers import checksol
|
| 1863 |
+
assert Sum(x, (x, 1, 10)).is_constant() is True
|
| 1864 |
+
assert Sum(x, (x, 1, n)).is_constant() is False
|
| 1865 |
+
assert Sum(x, (x, 1, n)).is_constant(y) is True
|
| 1866 |
+
assert Sum(x, (x, 1, n)).is_constant(n) is False
|
| 1867 |
+
assert Sum(x, (x, 1, n)).is_constant(x) is True
|
| 1868 |
+
eq = a*cos(x)**2 + a*sin(x)**2 - a
|
| 1869 |
+
assert eq.is_constant() is True
|
| 1870 |
+
assert eq.subs({x: pi, a: 2}) == eq.subs({x: pi, a: 3}) == 0
|
| 1871 |
+
assert x.is_constant() is False
|
| 1872 |
+
assert x.is_constant(y) is True
|
| 1873 |
+
assert log(x/y).is_constant() is False
|
| 1874 |
+
|
| 1875 |
+
assert checksol(x, x, Sum(x, (x, 1, n))) is False
|
| 1876 |
+
assert checksol(x, x, Sum(x, (x, 1, n))) is False
|
| 1877 |
+
assert f(1).is_constant
|
| 1878 |
+
assert checksol(x, x, f(x)) is False
|
| 1879 |
+
|
| 1880 |
+
assert Pow(x, S.Zero, evaluate=False).is_constant() is True # == 1
|
| 1881 |
+
assert Pow(S.Zero, x, evaluate=False).is_constant() is False # == 0 or 1
|
| 1882 |
+
assert (2**x).is_constant() is False
|
| 1883 |
+
assert Pow(S(2), S(3), evaluate=False).is_constant() is True
|
| 1884 |
+
|
| 1885 |
+
z1, z2 = symbols('z1 z2', zero=True)
|
| 1886 |
+
assert (z1 + 2*z2).is_constant() is True
|
| 1887 |
+
|
| 1888 |
+
assert meter.is_constant() is True
|
| 1889 |
+
assert (3*meter).is_constant() is True
|
| 1890 |
+
assert (x*meter).is_constant() is False
|
| 1891 |
+
|
| 1892 |
+
|
| 1893 |
+
def test_equals():
|
| 1894 |
+
assert (-3 - sqrt(5) + (-sqrt(10)/2 - sqrt(2)/2)**2).equals(0)
|
| 1895 |
+
assert (x**2 - 1).equals((x + 1)*(x - 1))
|
| 1896 |
+
assert (cos(x)**2 + sin(x)**2).equals(1)
|
| 1897 |
+
assert (a*cos(x)**2 + a*sin(x)**2).equals(a)
|
| 1898 |
+
r = sqrt(2)
|
| 1899 |
+
assert (-1/(r + r*x) + 1/r/(1 + x)).equals(0)
|
| 1900 |
+
assert factorial(x + 1).equals((x + 1)*factorial(x))
|
| 1901 |
+
assert sqrt(3).equals(2*sqrt(3)) is False
|
| 1902 |
+
assert (sqrt(5)*sqrt(3)).equals(sqrt(3)) is False
|
| 1903 |
+
assert (sqrt(5) + sqrt(3)).equals(0) is False
|
| 1904 |
+
assert (sqrt(5) + pi).equals(0) is False
|
| 1905 |
+
assert meter.equals(0) is False
|
| 1906 |
+
assert (3*meter**2).equals(0) is False
|
| 1907 |
+
eq = -(-1)**(S(3)/4)*6**(S.One/4) + (-6)**(S.One/4)*I
|
| 1908 |
+
if eq != 0: # if canonicalization makes this zero, skip the test
|
| 1909 |
+
assert eq.equals(0)
|
| 1910 |
+
assert sqrt(x).equals(0) is False
|
| 1911 |
+
|
| 1912 |
+
# from integrate(x*sqrt(1 + 2*x), x);
|
| 1913 |
+
# diff is zero only when assumptions allow
|
| 1914 |
+
i = 2*sqrt(2)*x**(S(5)/2)*(1 + 1/(2*x))**(S(5)/2)/5 + \
|
| 1915 |
+
2*sqrt(2)*x**(S(3)/2)*(1 + 1/(2*x))**(S(5)/2)/(-6 - 3/x)
|
| 1916 |
+
ans = sqrt(2*x + 1)*(6*x**2 + x - 1)/15
|
| 1917 |
+
diff = i - ans
|
| 1918 |
+
assert diff.equals(0) is None # should be False, but previously this was False due to wrong intermediate result
|
| 1919 |
+
assert diff.subs(x, Rational(-1, 2)/2) == 7*sqrt(2)/120
|
| 1920 |
+
# there are regions for x for which the expression is True, for
|
| 1921 |
+
# example, when x < -1/2 or x > 0 the expression is zero
|
| 1922 |
+
p = Symbol('p', positive=True)
|
| 1923 |
+
assert diff.subs(x, p).equals(0) is True
|
| 1924 |
+
assert diff.subs(x, -1).equals(0) is True
|
| 1925 |
+
|
| 1926 |
+
# prove via minimal_polynomial or self-consistency
|
| 1927 |
+
eq = sqrt(1 + sqrt(3)) + sqrt(3 + 3*sqrt(3)) - sqrt(10 + 6*sqrt(3))
|
| 1928 |
+
assert eq.equals(0)
|
| 1929 |
+
q = 3**Rational(1, 3) + 3
|
| 1930 |
+
p = expand(q**3)**Rational(1, 3)
|
| 1931 |
+
assert (p - q).equals(0)
|
| 1932 |
+
|
| 1933 |
+
# issue 6829
|
| 1934 |
+
# eq = q*x + q/4 + x**4 + x**3 + 2*x**2 - S.One/3
|
| 1935 |
+
# z = eq.subs(x, solve(eq, x)[0])
|
| 1936 |
+
q = symbols('q')
|
| 1937 |
+
z = (q*(-sqrt(-2*(-(q - S(7)/8)**S(2)/8 - S(2197)/13824)**(S.One/3) -
|
| 1938 |
+
S(13)/12)/2 - sqrt((2*q - S(7)/4)/sqrt(-2*(-(q - S(7)/8)**S(2)/8 -
|
| 1939 |
+
S(2197)/13824)**(S.One/3) - S(13)/12) + 2*(-(q - S(7)/8)**S(2)/8 -
|
| 1940 |
+
S(2197)/13824)**(S.One/3) - S(13)/6)/2 - S.One/4) + q/4 + (-sqrt(-2*(-(q
|
| 1941 |
+
- S(7)/8)**S(2)/8 - S(2197)/13824)**(S.One/3) - S(13)/12)/2 - sqrt((2*q
|
| 1942 |
+
- S(7)/4)/sqrt(-2*(-(q - S(7)/8)**S(2)/8 - S(2197)/13824)**(S.One/3) -
|
| 1943 |
+
S(13)/12) + 2*(-(q - S(7)/8)**S(2)/8 - S(2197)/13824)**(S.One/3) -
|
| 1944 |
+
S(13)/6)/2 - S.One/4)**4 + (-sqrt(-2*(-(q - S(7)/8)**S(2)/8 -
|
| 1945 |
+
S(2197)/13824)**(S.One/3) - S(13)/12)/2 - sqrt((2*q -
|
| 1946 |
+
S(7)/4)/sqrt(-2*(-(q - S(7)/8)**S(2)/8 - S(2197)/13824)**(S.One/3) -
|
| 1947 |
+
S(13)/12) + 2*(-(q - S(7)/8)**S(2)/8 - S(2197)/13824)**(S.One/3) -
|
| 1948 |
+
S(13)/6)/2 - S.One/4)**3 + 2*(-sqrt(-2*(-(q - S(7)/8)**S(2)/8 -
|
| 1949 |
+
S(2197)/13824)**(S.One/3) - S(13)/12)/2 - sqrt((2*q -
|
| 1950 |
+
S(7)/4)/sqrt(-2*(-(q - S(7)/8)**S(2)/8 - S(2197)/13824)**(S.One/3) -
|
| 1951 |
+
S(13)/12) + 2*(-(q - S(7)/8)**S(2)/8 - S(2197)/13824)**(S.One/3) -
|
| 1952 |
+
S(13)/6)/2 - S.One/4)**2 - Rational(1, 3))
|
| 1953 |
+
assert z.equals(0)
|
| 1954 |
+
|
| 1955 |
+
|
| 1956 |
+
def test_random():
|
| 1957 |
+
from sympy.functions.combinatorial.numbers import lucas
|
| 1958 |
+
from sympy.simplify.simplify import posify
|
| 1959 |
+
assert posify(x)[0]._random() is not None
|
| 1960 |
+
assert lucas(n)._random(2, -2, 0, -1, 1) is None
|
| 1961 |
+
|
| 1962 |
+
# issue 8662
|
| 1963 |
+
assert Piecewise((Max(x, y), z))._random() is None
|
| 1964 |
+
|
| 1965 |
+
|
| 1966 |
+
def test_round():
|
| 1967 |
+
assert str(Float('0.1249999').round(2)) == '0.12'
|
| 1968 |
+
d20 = 12345678901234567890
|
| 1969 |
+
ans = S(d20).round(2)
|
| 1970 |
+
assert ans.is_Integer and ans == d20
|
| 1971 |
+
ans = S(d20).round(-2)
|
| 1972 |
+
assert ans.is_Integer and ans == 12345678901234567900
|
| 1973 |
+
assert str(S('1/7').round(4)) == '0.1429'
|
| 1974 |
+
assert str(S('.[12345]').round(4)) == '0.1235'
|
| 1975 |
+
assert str(S('.1349').round(2)) == '0.13'
|
| 1976 |
+
n = S(12345)
|
| 1977 |
+
ans = n.round()
|
| 1978 |
+
assert ans.is_Integer
|
| 1979 |
+
assert ans == n
|
| 1980 |
+
ans = n.round(1)
|
| 1981 |
+
assert ans.is_Integer
|
| 1982 |
+
assert ans == n
|
| 1983 |
+
ans = n.round(4)
|
| 1984 |
+
assert ans.is_Integer
|
| 1985 |
+
assert ans == n
|
| 1986 |
+
assert n.round(-1) == 12340
|
| 1987 |
+
|
| 1988 |
+
r = Float(str(n)).round(-4)
|
| 1989 |
+
assert r == 10000.0
|
| 1990 |
+
|
| 1991 |
+
assert n.round(-5) == 0
|
| 1992 |
+
|
| 1993 |
+
assert str((pi + sqrt(2)).round(2)) == '4.56'
|
| 1994 |
+
assert (10*(pi + sqrt(2))).round(-1) == 50.0
|
| 1995 |
+
raises(TypeError, lambda: round(x + 2, 2))
|
| 1996 |
+
assert str(S(2.3).round(1)) == '2.3'
|
| 1997 |
+
# rounding in SymPy (as in Decimal) should be
|
| 1998 |
+
# exact for the given precision; we check here
|
| 1999 |
+
# that when a 5 follows the last digit that
|
| 2000 |
+
# the rounded digit will be even.
|
| 2001 |
+
for i in range(-99, 100):
|
| 2002 |
+
# construct a decimal that ends in 5, e.g. 123 -> 0.1235
|
| 2003 |
+
s = str(abs(i))
|
| 2004 |
+
p = len(s) # we are going to round to the last digit of i
|
| 2005 |
+
n = '0.%s5' % s # put a 5 after i's digits
|
| 2006 |
+
j = p + 2 # 2 for '0.'
|
| 2007 |
+
if i < 0: # 1 for '-'
|
| 2008 |
+
j += 1
|
| 2009 |
+
n = '-' + n
|
| 2010 |
+
v = str(Float(n).round(p))[:j] # pertinent digits
|
| 2011 |
+
if v.endswith('.'):
|
| 2012 |
+
continue # it ends with 0 which is even
|
| 2013 |
+
L = int(v[-1]) # last digit
|
| 2014 |
+
assert L % 2 == 0, (n, '->', v)
|
| 2015 |
+
|
| 2016 |
+
assert (Float(.3, 3) + 2*pi).round() == 7
|
| 2017 |
+
assert (Float(.3, 3) + 2*pi*100).round() == 629
|
| 2018 |
+
assert (pi + 2*E*I).round() == 3 + 5*I
|
| 2019 |
+
# don't let request for extra precision give more than
|
| 2020 |
+
# what is known (in this case, only 3 digits)
|
| 2021 |
+
assert str((Float(.03, 3) + 2*pi/100).round(5)) == '0.0928'
|
| 2022 |
+
assert str((Float(.03, 3) + 2*pi/100).round(4)) == '0.0928'
|
| 2023 |
+
|
| 2024 |
+
assert S.Zero.round() == 0
|
| 2025 |
+
|
| 2026 |
+
a = (Add(1, Float('1.' + '9'*27, ''), evaluate=False))
|
| 2027 |
+
assert a.round(10) == Float('3.000000000000000000000000000', '')
|
| 2028 |
+
assert a.round(25) == Float('3.000000000000000000000000000', '')
|
| 2029 |
+
assert a.round(26) == Float('3.000000000000000000000000000', '')
|
| 2030 |
+
assert a.round(27) == Float('2.999999999999999999999999999', '')
|
| 2031 |
+
assert a.round(30) == Float('2.999999999999999999999999999', '')
|
| 2032 |
+
#assert a.round(10) == Float('3.0000000000', '')
|
| 2033 |
+
#assert a.round(25) == Float('3.0000000000000000000000000', '')
|
| 2034 |
+
#assert a.round(26) == Float('3.00000000000000000000000000', '')
|
| 2035 |
+
#assert a.round(27) == Float('2.999999999999999999999999999', '')
|
| 2036 |
+
#assert a.round(30) == Float('2.999999999999999999999999999', '')
|
| 2037 |
+
|
| 2038 |
+
# XXX: Should round set the precision of the result?
|
| 2039 |
+
# The previous version of the tests above is this but they only pass
|
| 2040 |
+
# because Floats with unequal precision compare equal:
|
| 2041 |
+
#
|
| 2042 |
+
# assert a.round(10) == Float('3.0000000000', '')
|
| 2043 |
+
# assert a.round(25) == Float('3.0000000000000000000000000', '')
|
| 2044 |
+
# assert a.round(26) == Float('3.00000000000000000000000000', '')
|
| 2045 |
+
# assert a.round(27) == Float('2.999999999999999999999999999', '')
|
| 2046 |
+
# assert a.round(30) == Float('2.999999999999999999999999999', '')
|
| 2047 |
+
|
| 2048 |
+
raises(TypeError, lambda: x.round())
|
| 2049 |
+
raises(TypeError, lambda: f(1).round())
|
| 2050 |
+
|
| 2051 |
+
# exact magnitude of 10
|
| 2052 |
+
assert str(S.One.round()) == '1'
|
| 2053 |
+
assert str(S(100).round()) == '100'
|
| 2054 |
+
|
| 2055 |
+
# applied to real and imaginary portions
|
| 2056 |
+
assert (2*pi + E*I).round() == 6 + 3*I
|
| 2057 |
+
assert (2*pi + I/10).round() == 6
|
| 2058 |
+
assert (pi/10 + 2*I).round() == 2*I
|
| 2059 |
+
# the lhs re and im parts are Float with dps of 2
|
| 2060 |
+
# and those on the right have dps of 15 so they won't compare
|
| 2061 |
+
# equal unless we use string or compare components (which will
|
| 2062 |
+
# then coerce the floats to the same precision) or re-create
|
| 2063 |
+
# the floats
|
| 2064 |
+
assert str((pi/10 + E*I).round(2)) == '0.31 + 2.72*I'
|
| 2065 |
+
assert str((pi/10 + E*I).round(2).as_real_imag()) == '(0.31, 2.72)'
|
| 2066 |
+
assert str((pi/10 + E*I).round(2)) == '0.31 + 2.72*I'
|
| 2067 |
+
|
| 2068 |
+
# issue 6914
|
| 2069 |
+
assert (I**(I + 3)).round(3) == Float('-0.208', '')*I
|
| 2070 |
+
|
| 2071 |
+
# issue 8720
|
| 2072 |
+
assert S(-123.6).round() == -124
|
| 2073 |
+
assert S(-1.5).round() == -2
|
| 2074 |
+
assert S(-100.5).round() == -100
|
| 2075 |
+
assert S(-1.5 - 10.5*I).round() == -2 - 10*I
|
| 2076 |
+
|
| 2077 |
+
# issue 7961
|
| 2078 |
+
assert str(S(0.006).round(2)) == '0.01'
|
| 2079 |
+
assert str(S(0.00106).round(4)) == '0.0011'
|
| 2080 |
+
|
| 2081 |
+
# issue 8147
|
| 2082 |
+
assert S.NaN.round() is S.NaN
|
| 2083 |
+
assert S.Infinity.round() is S.Infinity
|
| 2084 |
+
assert S.NegativeInfinity.round() is S.NegativeInfinity
|
| 2085 |
+
assert S.ComplexInfinity.round() is S.ComplexInfinity
|
| 2086 |
+
|
| 2087 |
+
# check that types match
|
| 2088 |
+
for i in range(2):
|
| 2089 |
+
fi = float(i)
|
| 2090 |
+
# 2 args
|
| 2091 |
+
assert all(type(round(i, p)) is int for p in (-1, 0, 1))
|
| 2092 |
+
assert all(S(i).round(p).is_Integer for p in (-1, 0, 1))
|
| 2093 |
+
assert all(type(round(fi, p)) is float for p in (-1, 0, 1))
|
| 2094 |
+
assert all(S(fi).round(p).is_Float for p in (-1, 0, 1))
|
| 2095 |
+
# 1 arg (p is None)
|
| 2096 |
+
assert type(round(i)) is int
|
| 2097 |
+
assert S(i).round().is_Integer
|
| 2098 |
+
assert type(round(fi)) is int
|
| 2099 |
+
assert S(fi).round().is_Integer
|
| 2100 |
+
|
| 2101 |
+
# issue 25698
|
| 2102 |
+
n = 6000002
|
| 2103 |
+
assert int(n*(log(n) + log(log(n)))) == 110130079
|
| 2104 |
+
one = cos(2)**2 + sin(2)**2
|
| 2105 |
+
eq = exp(one*I*pi)
|
| 2106 |
+
qr, qi = eq.as_real_imag()
|
| 2107 |
+
assert qi.round(2) == 0.0
|
| 2108 |
+
assert eq.round(2) == -1.0
|
| 2109 |
+
eq = one - 1/S(10**120)
|
| 2110 |
+
assert S.true not in (eq > 1, eq < 1)
|
| 2111 |
+
assert int(eq) == int(.9) == 0
|
| 2112 |
+
assert int(-eq) == int(-.9) == 0
|
| 2113 |
+
|
| 2114 |
+
|
| 2115 |
+
def test_held_expression_UnevaluatedExpr():
|
| 2116 |
+
x = symbols("x")
|
| 2117 |
+
he = UnevaluatedExpr(1/x)
|
| 2118 |
+
e1 = x*he
|
| 2119 |
+
|
| 2120 |
+
assert isinstance(e1, Mul)
|
| 2121 |
+
assert e1.args == (x, he)
|
| 2122 |
+
assert e1.doit() == 1
|
| 2123 |
+
assert UnevaluatedExpr(Derivative(x, x)).doit(deep=False
|
| 2124 |
+
) == Derivative(x, x)
|
| 2125 |
+
assert UnevaluatedExpr(Derivative(x, x)).doit() == 1
|
| 2126 |
+
|
| 2127 |
+
xx = Mul(x, x, evaluate=False)
|
| 2128 |
+
assert xx != x**2
|
| 2129 |
+
|
| 2130 |
+
ue2 = UnevaluatedExpr(xx)
|
| 2131 |
+
assert isinstance(ue2, UnevaluatedExpr)
|
| 2132 |
+
assert ue2.args == (xx,)
|
| 2133 |
+
assert ue2.doit() == x**2
|
| 2134 |
+
assert ue2.doit(deep=False) == xx
|
| 2135 |
+
|
| 2136 |
+
x2 = UnevaluatedExpr(2)*2
|
| 2137 |
+
assert type(x2) is Mul
|
| 2138 |
+
assert x2.args == (2, UnevaluatedExpr(2))
|
| 2139 |
+
|
| 2140 |
+
def test_round_exception_nostr():
|
| 2141 |
+
# Don't use the string form of the expression in the round exception, as
|
| 2142 |
+
# it's too slow
|
| 2143 |
+
s = Symbol('bad')
|
| 2144 |
+
try:
|
| 2145 |
+
s.round()
|
| 2146 |
+
except TypeError as e:
|
| 2147 |
+
assert 'bad' not in str(e)
|
| 2148 |
+
else:
|
| 2149 |
+
# Did not raise
|
| 2150 |
+
raise AssertionError("Did not raise")
|
| 2151 |
+
|
| 2152 |
+
|
| 2153 |
+
def test_extract_branch_factor():
|
| 2154 |
+
assert exp_polar(2.0*I*pi).extract_branch_factor() == (1, 1)
|
| 2155 |
+
|
| 2156 |
+
|
| 2157 |
+
def test_identity_removal():
|
| 2158 |
+
assert Add.make_args(x + 0) == (x,)
|
| 2159 |
+
assert Mul.make_args(x*1) == (x,)
|
| 2160 |
+
|
| 2161 |
+
|
| 2162 |
+
def test_float_0():
|
| 2163 |
+
assert Float(0.0) + 1 == Float(1.0)
|
| 2164 |
+
|
| 2165 |
+
|
| 2166 |
+
@XFAIL
|
| 2167 |
+
def test_float_0_fail():
|
| 2168 |
+
assert Float(0.0)*x == Float(0.0)
|
| 2169 |
+
assert (x + Float(0.0)).is_Add
|
| 2170 |
+
|
| 2171 |
+
|
| 2172 |
+
def test_issue_6325():
|
| 2173 |
+
ans = (b**2 + z**2 - (b*(a + b*t) + z*(c + t*z))**2/(
|
| 2174 |
+
(a + b*t)**2 + (c + t*z)**2))/sqrt((a + b*t)**2 + (c + t*z)**2)
|
| 2175 |
+
e = sqrt((a + b*t)**2 + (c + z*t)**2)
|
| 2176 |
+
assert diff(e, t, 2) == ans
|
| 2177 |
+
assert e.diff(t, 2) == ans
|
| 2178 |
+
assert diff(e, t, 2, simplify=False) != ans
|
| 2179 |
+
|
| 2180 |
+
|
| 2181 |
+
def test_issue_7426():
|
| 2182 |
+
f1 = a % c
|
| 2183 |
+
f2 = x % z
|
| 2184 |
+
assert f1.equals(f2) is None
|
| 2185 |
+
|
| 2186 |
+
|
| 2187 |
+
def test_issue_11122():
|
| 2188 |
+
x = Symbol('x', extended_positive=False)
|
| 2189 |
+
assert unchanged(Gt, x, 0) # (x > 0)
|
| 2190 |
+
# (x > 0) should remain unevaluated after PR #16956
|
| 2191 |
+
|
| 2192 |
+
x = Symbol('x', positive=False, real=True)
|
| 2193 |
+
assert (x > 0) is S.false
|
| 2194 |
+
|
| 2195 |
+
|
| 2196 |
+
def test_issue_10651():
|
| 2197 |
+
x = Symbol('x', real=True)
|
| 2198 |
+
e1 = (-1 + x)/(1 - x)
|
| 2199 |
+
e3 = (4*x**2 - 4)/((1 - x)*(1 + x))
|
| 2200 |
+
e4 = 1/(cos(x)**2) - (tan(x))**2
|
| 2201 |
+
x = Symbol('x', positive=True)
|
| 2202 |
+
e5 = (1 + x)/x
|
| 2203 |
+
assert e1.is_constant() is None
|
| 2204 |
+
assert e3.is_constant() is None
|
| 2205 |
+
assert e4.is_constant() is None
|
| 2206 |
+
assert e5.is_constant() is False
|
| 2207 |
+
|
| 2208 |
+
|
| 2209 |
+
def test_issue_10161():
|
| 2210 |
+
x = symbols('x', real=True)
|
| 2211 |
+
assert x*abs(x)*abs(x) == x**3
|
| 2212 |
+
|
| 2213 |
+
|
| 2214 |
+
def test_issue_10755():
|
| 2215 |
+
x = symbols('x')
|
| 2216 |
+
raises(TypeError, lambda: int(log(x)))
|
| 2217 |
+
raises(TypeError, lambda: log(x).round(2))
|
| 2218 |
+
|
| 2219 |
+
|
| 2220 |
+
def test_issue_11877():
|
| 2221 |
+
x = symbols('x')
|
| 2222 |
+
assert integrate(log(S.Half - x), (x, 0, S.Half)) == Rational(-1, 2) -log(2)/2
|
| 2223 |
+
|
| 2224 |
+
|
| 2225 |
+
def test_normal():
|
| 2226 |
+
x = symbols('x')
|
| 2227 |
+
e = Mul(S.Half, 1 + x, evaluate=False)
|
| 2228 |
+
assert e.normal() == e
|
| 2229 |
+
|
| 2230 |
+
|
| 2231 |
+
def test_expr():
|
| 2232 |
+
x = symbols('x')
|
| 2233 |
+
raises(TypeError, lambda: tan(x).series(x, 2, oo, "+"))
|
| 2234 |
+
|
| 2235 |
+
|
| 2236 |
+
def test_ExprBuilder():
|
| 2237 |
+
eb = ExprBuilder(Mul)
|
| 2238 |
+
eb.args.extend([x, x])
|
| 2239 |
+
assert eb.build() == x**2
|
| 2240 |
+
|
| 2241 |
+
|
| 2242 |
+
def test_issue_22020():
|
| 2243 |
+
from sympy.parsing.sympy_parser import parse_expr
|
| 2244 |
+
x = parse_expr("log((2*V/3-V)/C)/-(R+r)*C")
|
| 2245 |
+
y = parse_expr("log((2*V/3-V)/C)/-(R+r)*2")
|
| 2246 |
+
assert x.equals(y) is False
|
| 2247 |
+
|
| 2248 |
+
|
| 2249 |
+
def test_non_string_equality():
|
| 2250 |
+
# Expressions should not compare equal to strings
|
| 2251 |
+
x = symbols('x')
|
| 2252 |
+
one = sympify(1)
|
| 2253 |
+
assert (x == 'x') is False
|
| 2254 |
+
assert (x != 'x') is True
|
| 2255 |
+
assert (one == '1') is False
|
| 2256 |
+
assert (one != '1') is True
|
| 2257 |
+
assert (x + 1 == 'x + 1') is False
|
| 2258 |
+
assert (x + 1 != 'x + 1') is True
|
| 2259 |
+
|
| 2260 |
+
# Make sure == doesn't try to convert the resulting expression to a string
|
| 2261 |
+
# (e.g., by calling sympify() instead of _sympify())
|
| 2262 |
+
|
| 2263 |
+
class BadRepr:
|
| 2264 |
+
def __repr__(self):
|
| 2265 |
+
raise RuntimeError
|
| 2266 |
+
|
| 2267 |
+
assert (x == BadRepr()) is False
|
| 2268 |
+
assert (x != BadRepr()) is True
|
| 2269 |
+
|
| 2270 |
+
|
| 2271 |
+
def test_21494():
|
| 2272 |
+
from sympy.testing.pytest import warns_deprecated_sympy
|
| 2273 |
+
|
| 2274 |
+
with warns_deprecated_sympy():
|
| 2275 |
+
assert x.expr_free_symbols == {x}
|
| 2276 |
+
|
| 2277 |
+
with warns_deprecated_sympy():
|
| 2278 |
+
assert Basic().expr_free_symbols == set()
|
| 2279 |
+
|
| 2280 |
+
with warns_deprecated_sympy():
|
| 2281 |
+
assert S(2).expr_free_symbols == {S(2)}
|
| 2282 |
+
|
| 2283 |
+
with warns_deprecated_sympy():
|
| 2284 |
+
assert Indexed("A", x).expr_free_symbols == {Indexed("A", x)}
|
| 2285 |
+
|
| 2286 |
+
with warns_deprecated_sympy():
|
| 2287 |
+
assert Subs(x, x, 0).expr_free_symbols == set()
|
| 2288 |
+
|
| 2289 |
+
|
| 2290 |
+
def test_Expr__eq__iterable_handling():
|
| 2291 |
+
assert x != range(3)
|
| 2292 |
+
|
| 2293 |
+
|
| 2294 |
+
def test_format():
|
| 2295 |
+
assert '{:1.2f}'.format(S.Zero) == '0.00'
|
| 2296 |
+
assert '{:+3.0f}'.format(S(3)) == ' +3'
|
| 2297 |
+
assert '{:23.20f}'.format(pi) == ' 3.14159265358979323846'
|
| 2298 |
+
assert '{:50.48f}'.format(exp(sin(1))) == '2.319776824715853173956590377503266813254904772376'
|
| 2299 |
+
|
| 2300 |
+
|
| 2301 |
+
def test_issue_24045():
|
| 2302 |
+
assert powsimp(exp(a)/((c*a - c*b)*(Float(1.0)*c*a - Float(1.0)*c*b))) # doesn't raise
|
| 2303 |
+
|
| 2304 |
+
|
| 2305 |
+
def test__unevaluated_Mul():
|
| 2306 |
+
A, B = symbols('A B', commutative=False)
|
| 2307 |
+
assert _unevaluated_Mul(x, A, B, S(2), A).args == (2, x, A, B, A)
|
| 2308 |
+
assert _unevaluated_Mul(-x*A*B, S(2), A).args == (-2, x, A, B, A)
|
| 2309 |
+
|
| 2310 |
+
|
| 2311 |
+
def test_Float_zero_division_error():
|
| 2312 |
+
# issue 27165
|
| 2313 |
+
assert Float('1.7567e-1417').round(15) == Float(0)
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_exprtools.py
ADDED
|
@@ -0,0 +1,493 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Tests for tools for manipulating of large commutative expressions. """
|
| 2 |
+
|
| 3 |
+
from sympy.concrete.summations import Sum
|
| 4 |
+
from sympy.core.add import Add
|
| 5 |
+
from sympy.core.basic import Basic
|
| 6 |
+
from sympy.core.containers import (Dict, Tuple)
|
| 7 |
+
from sympy.core.function import Function
|
| 8 |
+
from sympy.core.mul import Mul
|
| 9 |
+
from sympy.core.numbers import (I, Rational, oo)
|
| 10 |
+
from sympy.core.singleton import S
|
| 11 |
+
from sympy.core.symbol import (Dummy, Symbol, symbols)
|
| 12 |
+
from sympy.functions.elementary.exponential import (exp, log)
|
| 13 |
+
from sympy.functions.elementary.miscellaneous import (root, sqrt)
|
| 14 |
+
from sympy.functions.elementary.trigonometric import (cos, sin)
|
| 15 |
+
from sympy.integrals.integrals import Integral
|
| 16 |
+
from sympy.series.order import O
|
| 17 |
+
from sympy.sets.sets import Interval
|
| 18 |
+
from sympy.simplify.radsimp import collect
|
| 19 |
+
from sympy.simplify.simplify import simplify
|
| 20 |
+
from sympy.core.exprtools import (decompose_power, Factors, Term, _gcd_terms,
|
| 21 |
+
gcd_terms, factor_terms, factor_nc, _mask_nc,
|
| 22 |
+
_monotonic_sign)
|
| 23 |
+
from sympy.core.mul import _keep_coeff as _keep_coeff
|
| 24 |
+
from sympy.simplify.cse_opts import sub_pre
|
| 25 |
+
from sympy.testing.pytest import raises
|
| 26 |
+
|
| 27 |
+
from sympy.abc import a, b, t, x, y, z
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def test_decompose_power():
|
| 31 |
+
assert decompose_power(x) == (x, 1)
|
| 32 |
+
assert decompose_power(x**2) == (x, 2)
|
| 33 |
+
assert decompose_power(x**(2*y)) == (x**y, 2)
|
| 34 |
+
assert decompose_power(x**(2*y/3)) == (x**(y/3), 2)
|
| 35 |
+
assert decompose_power(x**(y*Rational(2, 3))) == (x**(y/3), 2)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def test_Factors():
|
| 39 |
+
assert Factors() == Factors({}) == Factors(S.One)
|
| 40 |
+
assert Factors().as_expr() is S.One
|
| 41 |
+
assert Factors({x: 2, y: 3, sin(x): 4}).as_expr() == x**2*y**3*sin(x)**4
|
| 42 |
+
assert Factors(S.Infinity) == Factors({oo: 1})
|
| 43 |
+
assert Factors(S.NegativeInfinity) == Factors({oo: 1, -1: 1})
|
| 44 |
+
# issue #18059:
|
| 45 |
+
assert Factors((x**2)**S.Half).as_expr() == (x**2)**S.Half
|
| 46 |
+
|
| 47 |
+
a = Factors({x: 5, y: 3, z: 7})
|
| 48 |
+
b = Factors({ y: 4, z: 3, t: 10})
|
| 49 |
+
|
| 50 |
+
assert a.mul(b) == a*b == Factors({x: 5, y: 7, z: 10, t: 10})
|
| 51 |
+
|
| 52 |
+
assert a.div(b) == divmod(a, b) == \
|
| 53 |
+
(Factors({x: 5, z: 4}), Factors({y: 1, t: 10}))
|
| 54 |
+
assert a.quo(b) == a/b == Factors({x: 5, z: 4})
|
| 55 |
+
assert a.rem(b) == a % b == Factors({y: 1, t: 10})
|
| 56 |
+
|
| 57 |
+
assert a.pow(3) == a**3 == Factors({x: 15, y: 9, z: 21})
|
| 58 |
+
assert b.pow(3) == b**3 == Factors({y: 12, z: 9, t: 30})
|
| 59 |
+
|
| 60 |
+
assert a.gcd(b) == Factors({y: 3, z: 3})
|
| 61 |
+
assert a.lcm(b) == Factors({x: 5, y: 4, z: 7, t: 10})
|
| 62 |
+
|
| 63 |
+
a = Factors({x: 4, y: 7, t: 7})
|
| 64 |
+
b = Factors({z: 1, t: 3})
|
| 65 |
+
|
| 66 |
+
assert a.normal(b) == (Factors({x: 4, y: 7, t: 4}), Factors({z: 1}))
|
| 67 |
+
|
| 68 |
+
assert Factors(sqrt(2)*x).as_expr() == sqrt(2)*x
|
| 69 |
+
|
| 70 |
+
assert Factors(-I)*I == Factors()
|
| 71 |
+
assert Factors({S.NegativeOne: S(3)})*Factors({S.NegativeOne: S.One, I: S(5)}) == \
|
| 72 |
+
Factors(I)
|
| 73 |
+
assert Factors(sqrt(I)*I) == Factors(I**(S(3)/2)) == Factors({I: S(3)/2})
|
| 74 |
+
assert Factors({I: S(3)/2}).as_expr() == I**(S(3)/2)
|
| 75 |
+
|
| 76 |
+
assert Factors(S(2)**x).div(S(3)**x) == \
|
| 77 |
+
(Factors({S(2): x}), Factors({S(3): x}))
|
| 78 |
+
assert Factors(2**(2*x + 2)).div(S(8)) == \
|
| 79 |
+
(Factors({S(2): 2*x + 2}), Factors({S(8): S.One}))
|
| 80 |
+
|
| 81 |
+
# coverage
|
| 82 |
+
# /!\ things break if this is not True
|
| 83 |
+
assert Factors({S.NegativeOne: Rational(3, 2)}) == Factors({I: S.One, S.NegativeOne: S.One})
|
| 84 |
+
assert Factors({I: S.One, S.NegativeOne: Rational(1, 3)}).as_expr() == I*(-1)**Rational(1, 3)
|
| 85 |
+
|
| 86 |
+
assert Factors(-1.) == Factors({S.NegativeOne: S.One, S(1.): 1})
|
| 87 |
+
assert Factors(-2.) == Factors({S.NegativeOne: S.One, S(2.): 1})
|
| 88 |
+
assert Factors((-2.)**x) == Factors({S(-2.): x})
|
| 89 |
+
assert Factors(S(-2)) == Factors({S.NegativeOne: S.One, S(2): 1})
|
| 90 |
+
assert Factors(S.Half) == Factors({S(2): -S.One})
|
| 91 |
+
assert Factors(Rational(3, 2)) == Factors({S(3): S.One, S(2): S.NegativeOne})
|
| 92 |
+
assert Factors({I: S.One}) == Factors(I)
|
| 93 |
+
assert Factors({-1.0: 2, I: 1}) == Factors({S(1.0): 1, I: 1})
|
| 94 |
+
assert Factors({S.NegativeOne: Rational(-3, 2)}).as_expr() == I
|
| 95 |
+
A = symbols('A', commutative=False)
|
| 96 |
+
assert Factors(2*A**2) == Factors({S(2): 1, A**2: 1})
|
| 97 |
+
assert Factors(I) == Factors({I: S.One})
|
| 98 |
+
assert Factors(x).normal(S(2)) == (Factors(x), Factors(S(2)))
|
| 99 |
+
assert Factors(x).normal(S.Zero) == (Factors(), Factors(S.Zero))
|
| 100 |
+
raises(ZeroDivisionError, lambda: Factors(x).div(S.Zero))
|
| 101 |
+
assert Factors(x).mul(S(2)) == Factors(2*x)
|
| 102 |
+
assert Factors(x).mul(S.Zero).is_zero
|
| 103 |
+
assert Factors(x).mul(1/x).is_one
|
| 104 |
+
assert Factors(x**sqrt(2)**3).as_expr() == x**(2*sqrt(2))
|
| 105 |
+
assert Factors(x)**Factors(S(2)) == Factors(x**2)
|
| 106 |
+
assert Factors(x).gcd(S.Zero) == Factors(x)
|
| 107 |
+
assert Factors(x).lcm(S.Zero).is_zero
|
| 108 |
+
assert Factors(S.Zero).div(x) == (Factors(S.Zero), Factors())
|
| 109 |
+
assert Factors(x).div(x) == (Factors(), Factors())
|
| 110 |
+
assert Factors({x: .2})/Factors({x: .2}) == Factors()
|
| 111 |
+
assert Factors(x) != Factors()
|
| 112 |
+
assert Factors(S.Zero).normal(x) == (Factors(S.Zero), Factors())
|
| 113 |
+
n, d = x**(2 + y), x**2
|
| 114 |
+
f = Factors(n)
|
| 115 |
+
assert f.div(d) == f.normal(d) == (Factors(x**y), Factors())
|
| 116 |
+
assert f.gcd(d) == Factors()
|
| 117 |
+
d = x**y
|
| 118 |
+
assert f.div(d) == f.normal(d) == (Factors(x**2), Factors())
|
| 119 |
+
assert f.gcd(d) == Factors(d)
|
| 120 |
+
n = d = 2**x
|
| 121 |
+
f = Factors(n)
|
| 122 |
+
assert f.div(d) == f.normal(d) == (Factors(), Factors())
|
| 123 |
+
assert f.gcd(d) == Factors(d)
|
| 124 |
+
n, d = 2**x, 2**y
|
| 125 |
+
f = Factors(n)
|
| 126 |
+
assert f.div(d) == f.normal(d) == (Factors({S(2): x}), Factors({S(2): y}))
|
| 127 |
+
assert f.gcd(d) == Factors()
|
| 128 |
+
|
| 129 |
+
# extraction of constant only
|
| 130 |
+
n = x**(x + 3)
|
| 131 |
+
assert Factors(n).normal(x**-3) == (Factors({x: x + 6}), Factors({}))
|
| 132 |
+
assert Factors(n).normal(x**3) == (Factors({x: x}), Factors({}))
|
| 133 |
+
assert Factors(n).normal(x**4) == (Factors({x: x}), Factors({x: 1}))
|
| 134 |
+
assert Factors(n).normal(x**(y - 3)) == \
|
| 135 |
+
(Factors({x: x + 6}), Factors({x: y}))
|
| 136 |
+
assert Factors(n).normal(x**(y + 3)) == (Factors({x: x}), Factors({x: y}))
|
| 137 |
+
assert Factors(n).normal(x**(y + 4)) == \
|
| 138 |
+
(Factors({x: x}), Factors({x: y + 1}))
|
| 139 |
+
|
| 140 |
+
assert Factors(n).div(x**-3) == (Factors({x: x + 6}), Factors({}))
|
| 141 |
+
assert Factors(n).div(x**3) == (Factors({x: x}), Factors({}))
|
| 142 |
+
assert Factors(n).div(x**4) == (Factors({x: x}), Factors({x: 1}))
|
| 143 |
+
assert Factors(n).div(x**(y - 3)) == \
|
| 144 |
+
(Factors({x: x + 6}), Factors({x: y}))
|
| 145 |
+
assert Factors(n).div(x**(y + 3)) == (Factors({x: x}), Factors({x: y}))
|
| 146 |
+
assert Factors(n).div(x**(y + 4)) == \
|
| 147 |
+
(Factors({x: x}), Factors({x: y + 1}))
|
| 148 |
+
|
| 149 |
+
assert Factors(3 * x / 2) == Factors({3: 1, 2: -1, x: 1})
|
| 150 |
+
assert Factors(x * x / y) == Factors({x: 2, y: -1})
|
| 151 |
+
assert Factors(27 * x / y**9) == Factors({27: 1, x: 1, y: -9})
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def test_Term():
|
| 155 |
+
a = Term(4*x*y**2/z/t**3)
|
| 156 |
+
b = Term(2*x**3*y**5/t**3)
|
| 157 |
+
|
| 158 |
+
assert a == Term(4, Factors({x: 1, y: 2}), Factors({z: 1, t: 3}))
|
| 159 |
+
assert b == Term(2, Factors({x: 3, y: 5}), Factors({t: 3}))
|
| 160 |
+
|
| 161 |
+
assert a.as_expr() == 4*x*y**2/z/t**3
|
| 162 |
+
assert b.as_expr() == 2*x**3*y**5/t**3
|
| 163 |
+
|
| 164 |
+
assert a.inv() == \
|
| 165 |
+
Term(S.One/4, Factors({z: 1, t: 3}), Factors({x: 1, y: 2}))
|
| 166 |
+
assert b.inv() == Term(S.Half, Factors({t: 3}), Factors({x: 3, y: 5}))
|
| 167 |
+
|
| 168 |
+
assert a.mul(b) == a*b == \
|
| 169 |
+
Term(8, Factors({x: 4, y: 7}), Factors({z: 1, t: 6}))
|
| 170 |
+
assert a.quo(b) == a/b == Term(2, Factors({}), Factors({x: 2, y: 3, z: 1}))
|
| 171 |
+
|
| 172 |
+
assert a.pow(3) == a**3 == \
|
| 173 |
+
Term(64, Factors({x: 3, y: 6}), Factors({z: 3, t: 9}))
|
| 174 |
+
assert b.pow(3) == b**3 == Term(8, Factors({x: 9, y: 15}), Factors({t: 9}))
|
| 175 |
+
|
| 176 |
+
assert a.pow(-3) == a**(-3) == \
|
| 177 |
+
Term(S.One/64, Factors({z: 3, t: 9}), Factors({x: 3, y: 6}))
|
| 178 |
+
assert b.pow(-3) == b**(-3) == \
|
| 179 |
+
Term(S.One/8, Factors({t: 9}), Factors({x: 9, y: 15}))
|
| 180 |
+
|
| 181 |
+
assert a.gcd(b) == Term(2, Factors({x: 1, y: 2}), Factors({t: 3}))
|
| 182 |
+
assert a.lcm(b) == Term(4, Factors({x: 3, y: 5}), Factors({z: 1, t: 3}))
|
| 183 |
+
|
| 184 |
+
a = Term(4*x*y**2/z/t**3)
|
| 185 |
+
b = Term(2*x**3*y**5*t**7)
|
| 186 |
+
|
| 187 |
+
assert a.mul(b) == Term(8, Factors({x: 4, y: 7, t: 4}), Factors({z: 1}))
|
| 188 |
+
|
| 189 |
+
assert Term((2*x + 2)**3) == Term(8, Factors({x + 1: 3}), Factors({}))
|
| 190 |
+
assert Term((2*x + 2)*(3*x + 6)**2) == \
|
| 191 |
+
Term(18, Factors({x + 1: 1, x + 2: 2}), Factors({}))
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
def test_gcd_terms():
|
| 195 |
+
f = 2*(x + 1)*(x + 4)/(5*x**2 + 5) + (2*x + 2)*(x + 5)/(x**2 + 1)/5 + \
|
| 196 |
+
(2*x + 2)*(x + 6)/(5*x**2 + 5)
|
| 197 |
+
|
| 198 |
+
assert _gcd_terms(f) == ((Rational(6, 5))*((1 + x)/(1 + x**2)), 5 + x, 1)
|
| 199 |
+
assert _gcd_terms(Add.make_args(f)) == \
|
| 200 |
+
((Rational(6, 5))*((1 + x)/(1 + x**2)), 5 + x, 1)
|
| 201 |
+
|
| 202 |
+
newf = (Rational(6, 5))*((1 + x)*(5 + x)/(1 + x**2))
|
| 203 |
+
assert gcd_terms(f) == newf
|
| 204 |
+
args = Add.make_args(f)
|
| 205 |
+
# non-Basic sequences of terms treated as terms of Add
|
| 206 |
+
assert gcd_terms(list(args)) == newf
|
| 207 |
+
assert gcd_terms(tuple(args)) == newf
|
| 208 |
+
assert gcd_terms(set(args)) == newf
|
| 209 |
+
# but a Basic sequence is treated as a container
|
| 210 |
+
assert gcd_terms(Tuple(*args)) != newf
|
| 211 |
+
assert gcd_terms(Basic(Tuple(S(1), 3*y + 3*x*y), Tuple(S(1), S(3)))) == \
|
| 212 |
+
Basic(Tuple(S(1), 3*y*(x + 1)), Tuple(S(1), S(3)))
|
| 213 |
+
# but we shouldn't change keys of a dictionary or some may be lost
|
| 214 |
+
assert gcd_terms(Dict((x*(1 + y), S(2)), (x + x*y, y + x*y))) == \
|
| 215 |
+
Dict({x*(y + 1): S(2), x + x*y: y*(1 + x)})
|
| 216 |
+
|
| 217 |
+
assert gcd_terms((2*x + 2)**3 + (2*x + 2)**2) == 4*(x + 1)**2*(2*x + 3)
|
| 218 |
+
|
| 219 |
+
assert gcd_terms(0) == 0
|
| 220 |
+
assert gcd_terms(1) == 1
|
| 221 |
+
assert gcd_terms(x) == x
|
| 222 |
+
assert gcd_terms(2 + 2*x) == Mul(2, 1 + x, evaluate=False)
|
| 223 |
+
arg = x*(2*x + 4*y)
|
| 224 |
+
garg = 2*x*(x + 2*y)
|
| 225 |
+
assert gcd_terms(arg) == garg
|
| 226 |
+
assert gcd_terms(sin(arg)) == sin(garg)
|
| 227 |
+
|
| 228 |
+
# issue 6139-like
|
| 229 |
+
alpha, alpha1, alpha2, alpha3 = symbols('alpha:4')
|
| 230 |
+
a = alpha**2 - alpha*x**2 + alpha + x**3 - x*(alpha + 1)
|
| 231 |
+
rep = (alpha, (1 + sqrt(5))/2 + alpha1*x + alpha2*x**2 + alpha3*x**3)
|
| 232 |
+
s = (a/(x - alpha)).subs(*rep).series(x, 0, 1)
|
| 233 |
+
assert simplify(collect(s, x)) == -sqrt(5)/2 - Rational(3, 2) + O(x)
|
| 234 |
+
|
| 235 |
+
# issue 5917
|
| 236 |
+
assert _gcd_terms([S.Zero, S.Zero]) == (0, 0, 1)
|
| 237 |
+
assert _gcd_terms([2*x + 4]) == (2, x + 2, 1)
|
| 238 |
+
|
| 239 |
+
eq = x/(x + 1/x)
|
| 240 |
+
assert gcd_terms(eq, fraction=False) == eq
|
| 241 |
+
eq = x/2/y + 1/x/y
|
| 242 |
+
assert gcd_terms(eq, fraction=True, clear=True) == \
|
| 243 |
+
(x**2 + 2)/(2*x*y)
|
| 244 |
+
assert gcd_terms(eq, fraction=True, clear=False) == \
|
| 245 |
+
(x**2/2 + 1)/(x*y)
|
| 246 |
+
assert gcd_terms(eq, fraction=False, clear=True) == \
|
| 247 |
+
(x + 2/x)/(2*y)
|
| 248 |
+
assert gcd_terms(eq, fraction=False, clear=False) == \
|
| 249 |
+
(x/2 + 1/x)/y
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
def test_factor_terms():
|
| 253 |
+
A = Symbol('A', commutative=False)
|
| 254 |
+
assert factor_terms(9*(x + x*y + 1) + (3*x + 3)**(2 + 2*x)) == \
|
| 255 |
+
9*x*y + 9*x + _keep_coeff(S(3), x + 1)**_keep_coeff(S(2), x + 1) + 9
|
| 256 |
+
assert factor_terms(9*(x + x*y + 1) + (3)**(2 + 2*x)) == \
|
| 257 |
+
_keep_coeff(S(9), 3**(2*x) + x*y + x + 1)
|
| 258 |
+
assert factor_terms(3**(2 + 2*x) + a*3**(2 + 2*x)) == \
|
| 259 |
+
9*3**(2*x)*(a + 1)
|
| 260 |
+
assert factor_terms(x + x*A) == \
|
| 261 |
+
x*(1 + A)
|
| 262 |
+
assert factor_terms(sin(x + x*A)) == \
|
| 263 |
+
sin(x*(1 + A))
|
| 264 |
+
assert factor_terms((3*x + 3)**((2 + 2*x)/3)) == \
|
| 265 |
+
_keep_coeff(S(3), x + 1)**_keep_coeff(Rational(2, 3), x + 1)
|
| 266 |
+
assert factor_terms(x + (x*y + x)**(3*x + 3)) == \
|
| 267 |
+
x + (x*(y + 1))**_keep_coeff(S(3), x + 1)
|
| 268 |
+
assert factor_terms(a*(x + x*y) + b*(x*2 + y*x*2)) == \
|
| 269 |
+
x*(a + 2*b)*(y + 1)
|
| 270 |
+
i = Integral(x, (x, 0, oo))
|
| 271 |
+
assert factor_terms(i) == i
|
| 272 |
+
|
| 273 |
+
assert factor_terms(x/2 + y) == x/2 + y
|
| 274 |
+
# fraction doesn't apply to integer denominators
|
| 275 |
+
assert factor_terms(x/2 + y, fraction=True) == x/2 + y
|
| 276 |
+
# clear *does* apply to the integer denominators
|
| 277 |
+
assert factor_terms(x/2 + y, clear=True) == Mul(S.Half, x + 2*y, evaluate=False)
|
| 278 |
+
|
| 279 |
+
# check radical extraction
|
| 280 |
+
eq = sqrt(2) + sqrt(10)
|
| 281 |
+
assert factor_terms(eq) == eq
|
| 282 |
+
assert factor_terms(eq, radical=True) == sqrt(2)*(1 + sqrt(5))
|
| 283 |
+
eq = root(-6, 3) + root(6, 3)
|
| 284 |
+
assert factor_terms(eq, radical=True) == 6**(S.One/3)*(1 + (-1)**(S.One/3))
|
| 285 |
+
|
| 286 |
+
eq = [x + x*y]
|
| 287 |
+
ans = [x*(y + 1)]
|
| 288 |
+
for c in [list, tuple, set]:
|
| 289 |
+
assert factor_terms(c(eq)) == c(ans)
|
| 290 |
+
assert factor_terms(Tuple(x + x*y)) == Tuple(x*(y + 1))
|
| 291 |
+
assert factor_terms(Interval(0, 1)) == Interval(0, 1)
|
| 292 |
+
e = 1/sqrt(a/2 + 1)
|
| 293 |
+
assert factor_terms(e, clear=False) == 1/sqrt(a/2 + 1)
|
| 294 |
+
assert factor_terms(e, clear=True) == sqrt(2)/sqrt(a + 2)
|
| 295 |
+
|
| 296 |
+
eq = x/(x + 1/x) + 1/(x**2 + 1)
|
| 297 |
+
assert factor_terms(eq, fraction=False) == eq
|
| 298 |
+
assert factor_terms(eq, fraction=True) == 1
|
| 299 |
+
|
| 300 |
+
assert factor_terms((1/(x**3 + x**2) + 2/x**2)*y) == \
|
| 301 |
+
y*(2 + 1/(x + 1))/x**2
|
| 302 |
+
|
| 303 |
+
# if not True, then processesing for this in factor_terms is not necessary
|
| 304 |
+
assert gcd_terms(-x - y) == -x - y
|
| 305 |
+
assert factor_terms(-x - y) == Mul(-1, x + y, evaluate=False)
|
| 306 |
+
|
| 307 |
+
# if not True, then "special" processesing in factor_terms is not necessary
|
| 308 |
+
assert gcd_terms(exp(Mul(-1, x + 1))) == exp(-x - 1)
|
| 309 |
+
e = exp(-x - 2) + x
|
| 310 |
+
assert factor_terms(e) == exp(Mul(-1, x + 2, evaluate=False)) + x
|
| 311 |
+
assert factor_terms(e, sign=False) == e
|
| 312 |
+
assert factor_terms(exp(-4*x - 2) - x) == -x + exp(Mul(-2, 2*x + 1, evaluate=False))
|
| 313 |
+
|
| 314 |
+
# sum/integral tests
|
| 315 |
+
for F in (Sum, Integral):
|
| 316 |
+
assert factor_terms(F(x, (y, 1, 10))) == x * F(1, (y, 1, 10))
|
| 317 |
+
assert factor_terms(F(x, (y, 1, 10)) + x) == x * (1 + F(1, (y, 1, 10)))
|
| 318 |
+
assert factor_terms(F(x*y + x*y**2, (y, 1, 10))) == x*F(y*(y + 1), (y, 1, 10))
|
| 319 |
+
|
| 320 |
+
# expressions involving Pow terms with base 0
|
| 321 |
+
assert factor_terms(0**(x - 2) - 1) == 0**(x - 2) - 1
|
| 322 |
+
assert factor_terms(0**(x + 2) - 1) == 0**(x + 2) - 1
|
| 323 |
+
assert factor_terms((0**(x + 2) - 1).subs(x,-2)) == 0
|
| 324 |
+
|
| 325 |
+
|
| 326 |
+
def test_xreplace():
|
| 327 |
+
e = Mul(2, 1 + x, evaluate=False)
|
| 328 |
+
assert e.xreplace({}) == e
|
| 329 |
+
assert e.xreplace({y: x}) == e
|
| 330 |
+
|
| 331 |
+
|
| 332 |
+
def test_factor_nc():
|
| 333 |
+
x, y = symbols('x,y')
|
| 334 |
+
k = symbols('k', integer=True)
|
| 335 |
+
n, m, o = symbols('n,m,o', commutative=False)
|
| 336 |
+
|
| 337 |
+
# mul and multinomial expansion is needed
|
| 338 |
+
from sympy.core.function import _mexpand
|
| 339 |
+
e = x*(1 + y)**2
|
| 340 |
+
assert _mexpand(e) == x + x*2*y + x*y**2
|
| 341 |
+
|
| 342 |
+
def factor_nc_test(e):
|
| 343 |
+
ex = _mexpand(e)
|
| 344 |
+
assert ex.is_Add
|
| 345 |
+
f = factor_nc(ex)
|
| 346 |
+
assert not f.is_Add and _mexpand(f) == ex
|
| 347 |
+
|
| 348 |
+
factor_nc_test(x*(1 + y))
|
| 349 |
+
factor_nc_test(n*(x + 1))
|
| 350 |
+
factor_nc_test(n*(x + m))
|
| 351 |
+
factor_nc_test((x + m)*n)
|
| 352 |
+
factor_nc_test(n*m*(x*o + n*o*m)*n)
|
| 353 |
+
s = Sum(x, (x, 1, 2))
|
| 354 |
+
factor_nc_test(x*(1 + s))
|
| 355 |
+
factor_nc_test(x*(1 + s)*s)
|
| 356 |
+
factor_nc_test(x*(1 + sin(s)))
|
| 357 |
+
factor_nc_test((1 + n)**2)
|
| 358 |
+
|
| 359 |
+
factor_nc_test((x + n)*(x + m)*(x + y))
|
| 360 |
+
factor_nc_test(x*(n*m + 1))
|
| 361 |
+
factor_nc_test(x*(n*m + x))
|
| 362 |
+
factor_nc_test(x*(x*n*m + 1))
|
| 363 |
+
factor_nc_test(n*(m/x + o))
|
| 364 |
+
factor_nc_test(m*(n + o/2))
|
| 365 |
+
factor_nc_test(x*n*(x*m + 1))
|
| 366 |
+
factor_nc_test(x*(m*n + x*n*m))
|
| 367 |
+
factor_nc_test(n*(1 - m)*n**2)
|
| 368 |
+
|
| 369 |
+
factor_nc_test((n + m)**2)
|
| 370 |
+
factor_nc_test((n - m)*(n + m)**2)
|
| 371 |
+
factor_nc_test((n + m)**2*(n - m))
|
| 372 |
+
factor_nc_test((m - n)*(n + m)**2*(n - m))
|
| 373 |
+
|
| 374 |
+
assert factor_nc(n*(n + n*m)) == n**2*(1 + m)
|
| 375 |
+
assert factor_nc(m*(m*n + n*m*n**2)) == m*(m + n*m*n)*n
|
| 376 |
+
eq = m*sin(n) - sin(n)*m
|
| 377 |
+
assert factor_nc(eq) == eq
|
| 378 |
+
|
| 379 |
+
# for coverage:
|
| 380 |
+
from sympy.physics.secondquant import Commutator
|
| 381 |
+
from sympy.polys.polytools import factor
|
| 382 |
+
eq = 1 + x*Commutator(m, n)
|
| 383 |
+
assert factor_nc(eq) == eq
|
| 384 |
+
eq = x*Commutator(m, n) + x*Commutator(m, o)*Commutator(m, n)
|
| 385 |
+
assert factor(eq) == x*(1 + Commutator(m, o))*Commutator(m, n)
|
| 386 |
+
|
| 387 |
+
# issue 6534
|
| 388 |
+
assert (2*n + 2*m).factor() == 2*(n + m)
|
| 389 |
+
|
| 390 |
+
# issue 6701
|
| 391 |
+
_n = symbols('nz', zero=False, commutative=False)
|
| 392 |
+
assert factor_nc(_n**k + _n**(k + 1)) == _n**k*(1 + _n)
|
| 393 |
+
assert factor_nc((m*n)**k + (m*n)**(k + 1)) == (1 + m*n)*(m*n)**k
|
| 394 |
+
|
| 395 |
+
# issue 6918
|
| 396 |
+
assert factor_nc(-n*(2*x**2 + 2*x)) == -2*n*x*(x + 1)
|
| 397 |
+
|
| 398 |
+
|
| 399 |
+
def test_issue_6360():
|
| 400 |
+
a, b = symbols("a b")
|
| 401 |
+
apb = a + b
|
| 402 |
+
eq = apb + apb**2*(-2*a - 2*b)
|
| 403 |
+
assert factor_terms(sub_pre(eq)) == a + b - 2*(a + b)**3
|
| 404 |
+
|
| 405 |
+
|
| 406 |
+
def test_issue_7903():
|
| 407 |
+
a = symbols(r'a', real=True)
|
| 408 |
+
t = exp(I*cos(a)) + exp(-I*sin(a))
|
| 409 |
+
assert t.simplify()
|
| 410 |
+
|
| 411 |
+
def test_issue_8263():
|
| 412 |
+
F, G = symbols('F, G', commutative=False, cls=Function)
|
| 413 |
+
x, y = symbols('x, y')
|
| 414 |
+
expr, dummies, _ = _mask_nc(F(x)*G(y) - G(y)*F(x))
|
| 415 |
+
for v in dummies.values():
|
| 416 |
+
assert not v.is_commutative
|
| 417 |
+
assert not expr.is_zero
|
| 418 |
+
|
| 419 |
+
def test_monotonic_sign():
|
| 420 |
+
F = _monotonic_sign
|
| 421 |
+
x = symbols('x')
|
| 422 |
+
assert F(x) is None
|
| 423 |
+
assert F(-x) is None
|
| 424 |
+
assert F(Dummy(prime=True)) == 2
|
| 425 |
+
assert F(Dummy(prime=True, odd=True)) == 3
|
| 426 |
+
assert F(Dummy(composite=True)) == 4
|
| 427 |
+
assert F(Dummy(composite=True, odd=True)) == 9
|
| 428 |
+
assert F(Dummy(positive=True, integer=True)) == 1
|
| 429 |
+
assert F(Dummy(positive=True, even=True)) == 2
|
| 430 |
+
assert F(Dummy(positive=True, even=True, prime=False)) == 4
|
| 431 |
+
assert F(Dummy(negative=True, integer=True)) == -1
|
| 432 |
+
assert F(Dummy(negative=True, even=True)) == -2
|
| 433 |
+
assert F(Dummy(zero=True)) == 0
|
| 434 |
+
assert F(Dummy(nonnegative=True)) == 0
|
| 435 |
+
assert F(Dummy(nonpositive=True)) == 0
|
| 436 |
+
|
| 437 |
+
assert F(Dummy(positive=True) + 1).is_positive
|
| 438 |
+
assert F(Dummy(positive=True, integer=True) - 1).is_nonnegative
|
| 439 |
+
assert F(Dummy(positive=True) - 1) is None
|
| 440 |
+
assert F(Dummy(negative=True) + 1) is None
|
| 441 |
+
assert F(Dummy(negative=True, integer=True) - 1).is_nonpositive
|
| 442 |
+
assert F(Dummy(negative=True) - 1).is_negative
|
| 443 |
+
assert F(-Dummy(positive=True) + 1) is None
|
| 444 |
+
assert F(-Dummy(positive=True, integer=True) - 1).is_negative
|
| 445 |
+
assert F(-Dummy(positive=True) - 1).is_negative
|
| 446 |
+
assert F(-Dummy(negative=True) + 1).is_positive
|
| 447 |
+
assert F(-Dummy(negative=True, integer=True) - 1).is_nonnegative
|
| 448 |
+
assert F(-Dummy(negative=True) - 1) is None
|
| 449 |
+
x = Dummy(negative=True)
|
| 450 |
+
assert F(x**3).is_nonpositive
|
| 451 |
+
assert F(x**3 + log(2)*x - 1).is_negative
|
| 452 |
+
x = Dummy(positive=True)
|
| 453 |
+
assert F(-x**3).is_nonpositive
|
| 454 |
+
|
| 455 |
+
p = Dummy(positive=True)
|
| 456 |
+
assert F(1/p).is_positive
|
| 457 |
+
assert F(p/(p + 1)).is_positive
|
| 458 |
+
p = Dummy(nonnegative=True)
|
| 459 |
+
assert F(p/(p + 1)).is_nonnegative
|
| 460 |
+
p = Dummy(positive=True)
|
| 461 |
+
assert F(-1/p).is_negative
|
| 462 |
+
p = Dummy(nonpositive=True)
|
| 463 |
+
assert F(p/(-p + 1)).is_nonpositive
|
| 464 |
+
|
| 465 |
+
p = Dummy(positive=True, integer=True)
|
| 466 |
+
q = Dummy(positive=True, integer=True)
|
| 467 |
+
assert F(-2/p/q).is_negative
|
| 468 |
+
assert F(-2/(p - 1)/q) is None
|
| 469 |
+
|
| 470 |
+
assert F((p - 1)*q + 1).is_positive
|
| 471 |
+
assert F(-(p - 1)*q - 1).is_negative
|
| 472 |
+
|
| 473 |
+
def test_issue_17256():
|
| 474 |
+
from sympy.sets.fancysets import Range
|
| 475 |
+
x = Symbol('x')
|
| 476 |
+
s1 = Sum(x + 1, (x, 1, 9))
|
| 477 |
+
s2 = Sum(x + 1, (x, Range(1, 10)))
|
| 478 |
+
a = Symbol('a')
|
| 479 |
+
r1 = s1.xreplace({x:a})
|
| 480 |
+
r2 = s2.xreplace({x:a})
|
| 481 |
+
|
| 482 |
+
assert r1.doit() == r2.doit()
|
| 483 |
+
s1 = Sum(x + 1, (x, 0, 9))
|
| 484 |
+
s2 = Sum(x + 1, (x, Range(10)))
|
| 485 |
+
a = Symbol('a')
|
| 486 |
+
r1 = s1.xreplace({x:a})
|
| 487 |
+
r2 = s2.xreplace({x:a})
|
| 488 |
+
assert r1 == r2
|
| 489 |
+
|
| 490 |
+
def test_issue_21623():
|
| 491 |
+
from sympy.matrices.expressions.matexpr import MatrixSymbol
|
| 492 |
+
M = MatrixSymbol('X', 2, 2)
|
| 493 |
+
assert gcd_terms(M[0,0], 1) == M[0,0]
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_facts.py
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.facts import (deduce_alpha_implications,
|
| 2 |
+
apply_beta_to_alpha_route, rules_2prereq, FactRules, FactKB)
|
| 3 |
+
from sympy.core.logic import And, Not
|
| 4 |
+
from sympy.testing.pytest import raises
|
| 5 |
+
|
| 6 |
+
T = True
|
| 7 |
+
F = False
|
| 8 |
+
U = None
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def test_deduce_alpha_implications():
|
| 12 |
+
def D(i):
|
| 13 |
+
I = deduce_alpha_implications(i)
|
| 14 |
+
P = rules_2prereq({
|
| 15 |
+
(k, True): {(v, True) for v in S} for k, S in I.items()})
|
| 16 |
+
return I, P
|
| 17 |
+
|
| 18 |
+
# transitivity
|
| 19 |
+
I, P = D([('a', 'b'), ('b', 'c')])
|
| 20 |
+
assert I == {'a': {'b', 'c'}, 'b': {'c'}, Not('b'):
|
| 21 |
+
{Not('a')}, Not('c'): {Not('a'), Not('b')}}
|
| 22 |
+
assert P == {'a': {'b', 'c'}, 'b': {'a', 'c'}, 'c': {'a', 'b'}}
|
| 23 |
+
|
| 24 |
+
# Duplicate entry
|
| 25 |
+
I, P = D([('a', 'b'), ('b', 'c'), ('b', 'c')])
|
| 26 |
+
assert I == {'a': {'b', 'c'}, 'b': {'c'}, Not('b'): {Not('a')}, Not('c'): {Not('a'), Not('b')}}
|
| 27 |
+
assert P == {'a': {'b', 'c'}, 'b': {'a', 'c'}, 'c': {'a', 'b'}}
|
| 28 |
+
|
| 29 |
+
# see if it is tolerant to cycles
|
| 30 |
+
assert D([('a', 'a'), ('a', 'a')]) == ({}, {})
|
| 31 |
+
assert D([('a', 'b'), ('b', 'a')]) == (
|
| 32 |
+
{'a': {'b'}, 'b': {'a'}, Not('a'): {Not('b')}, Not('b'): {Not('a')}},
|
| 33 |
+
{'a': {'b'}, 'b': {'a'}})
|
| 34 |
+
|
| 35 |
+
# see if it catches inconsistency
|
| 36 |
+
raises(ValueError, lambda: D([('a', Not('a'))]))
|
| 37 |
+
raises(ValueError, lambda: D([('a', 'b'), ('b', Not('a'))]))
|
| 38 |
+
raises(ValueError, lambda: D([('a', 'b'), ('b', 'c'), ('b', 'na'),
|
| 39 |
+
('na', Not('a'))]))
|
| 40 |
+
|
| 41 |
+
# see if it handles implications with negations
|
| 42 |
+
I, P = D([('a', Not('b')), ('c', 'b')])
|
| 43 |
+
assert I == {'a': {Not('b'), Not('c')}, 'b': {Not('a')}, 'c': {'b', Not('a')}, Not('b'): {Not('c')}}
|
| 44 |
+
assert P == {'a': {'b', 'c'}, 'b': {'a', 'c'}, 'c': {'a', 'b'}}
|
| 45 |
+
I, P = D([(Not('a'), 'b'), ('a', 'c')])
|
| 46 |
+
assert I == {'a': {'c'}, Not('a'): {'b'}, Not('b'): {'a',
|
| 47 |
+
'c'}, Not('c'): {Not('a'), 'b'},}
|
| 48 |
+
assert P == {'a': {'b', 'c'}, 'b': {'a', 'c'}, 'c': {'a', 'b'}}
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
# Long deductions
|
| 52 |
+
I, P = D([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e')])
|
| 53 |
+
assert I == {'a': {'b', 'c', 'd', 'e'}, 'b': {'c', 'd', 'e'},
|
| 54 |
+
'c': {'d', 'e'}, 'd': {'e'}, Not('b'): {Not('a')},
|
| 55 |
+
Not('c'): {Not('a'), Not('b')}, Not('d'): {Not('a'), Not('b'),
|
| 56 |
+
Not('c')}, Not('e'): {Not('a'), Not('b'), Not('c'), Not('d')}}
|
| 57 |
+
assert P == {'a': {'b', 'c', 'd', 'e'}, 'b': {'a', 'c', 'd',
|
| 58 |
+
'e'}, 'c': {'a', 'b', 'd', 'e'}, 'd': {'a', 'b', 'c', 'e'},
|
| 59 |
+
'e': {'a', 'b', 'c', 'd'}}
|
| 60 |
+
|
| 61 |
+
# something related to real-world
|
| 62 |
+
I, P = D([('rat', 'real'), ('int', 'rat')])
|
| 63 |
+
|
| 64 |
+
assert I == {'int': {'rat', 'real'}, 'rat': {'real'},
|
| 65 |
+
Not('real'): {Not('rat'), Not('int')}, Not('rat'): {Not('int')}}
|
| 66 |
+
assert P == {'rat': {'int', 'real'}, 'real': {'int', 'rat'},
|
| 67 |
+
'int': {'rat', 'real'}}
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
# TODO move me to appropriate place
|
| 71 |
+
def test_apply_beta_to_alpha_route():
|
| 72 |
+
APPLY = apply_beta_to_alpha_route
|
| 73 |
+
|
| 74 |
+
# indicates empty alpha-chain with attached beta-rule #bidx
|
| 75 |
+
def Q(bidx):
|
| 76 |
+
return (set(), [bidx])
|
| 77 |
+
|
| 78 |
+
# x -> a &(a,b) -> x -- x -> a
|
| 79 |
+
A = {'x': {'a'}}
|
| 80 |
+
B = [(And('a', 'b'), 'x')]
|
| 81 |
+
assert APPLY(A, B) == {'x': ({'a'}, []), 'a': Q(0), 'b': Q(0)}
|
| 82 |
+
|
| 83 |
+
# x -> a &(a,!x) -> b -- x -> a
|
| 84 |
+
A = {'x': {'a'}}
|
| 85 |
+
B = [(And('a', Not('x')), 'b')]
|
| 86 |
+
assert APPLY(A, B) == {'x': ({'a'}, []), Not('x'): Q(0), 'a': Q(0)}
|
| 87 |
+
|
| 88 |
+
# x -> a b &(a,b) -> c -- x -> a b c
|
| 89 |
+
A = {'x': {'a', 'b'}}
|
| 90 |
+
B = [(And('a', 'b'), 'c')]
|
| 91 |
+
assert APPLY(A, B) == \
|
| 92 |
+
{'x': ({'a', 'b', 'c'}, []), 'a': Q(0), 'b': Q(0)}
|
| 93 |
+
|
| 94 |
+
# x -> a &(a,b) -> y -- x -> a [#0]
|
| 95 |
+
A = {'x': {'a'}}
|
| 96 |
+
B = [(And('a', 'b'), 'y')]
|
| 97 |
+
assert APPLY(A, B) == {'x': ({'a'}, [0]), 'a': Q(0), 'b': Q(0)}
|
| 98 |
+
|
| 99 |
+
# x -> a b c &(a,b) -> c -- x -> a b c
|
| 100 |
+
A = {'x': {'a', 'b', 'c'}}
|
| 101 |
+
B = [(And('a', 'b'), 'c')]
|
| 102 |
+
assert APPLY(A, B) == \
|
| 103 |
+
{'x': ({'a', 'b', 'c'}, []), 'a': Q(0), 'b': Q(0)}
|
| 104 |
+
|
| 105 |
+
# x -> a b &(a,b,c) -> y -- x -> a b [#0]
|
| 106 |
+
A = {'x': {'a', 'b'}}
|
| 107 |
+
B = [(And('a', 'b', 'c'), 'y')]
|
| 108 |
+
assert APPLY(A, B) == \
|
| 109 |
+
{'x': ({'a', 'b'}, [0]), 'a': Q(0), 'b': Q(0), 'c': Q(0)}
|
| 110 |
+
|
| 111 |
+
# x -> a b &(a,b) -> c -- x -> a b c d
|
| 112 |
+
# c -> d c -> d
|
| 113 |
+
A = {'x': {'a', 'b'}, 'c': {'d'}}
|
| 114 |
+
B = [(And('a', 'b'), 'c')]
|
| 115 |
+
assert APPLY(A, B) == {'x': ({'a', 'b', 'c', 'd'}, []),
|
| 116 |
+
'c': ({'d'}, []), 'a': Q(0), 'b': Q(0)}
|
| 117 |
+
|
| 118 |
+
# x -> a b &(a,b) -> c -- x -> a b c d e
|
| 119 |
+
# c -> d &(c,d) -> e c -> d e
|
| 120 |
+
A = {'x': {'a', 'b'}, 'c': {'d'}}
|
| 121 |
+
B = [(And('a', 'b'), 'c'), (And('c', 'd'), 'e')]
|
| 122 |
+
assert APPLY(A, B) == {'x': ({'a', 'b', 'c', 'd', 'e'}, []),
|
| 123 |
+
'c': ({'d', 'e'}, []), 'a': Q(0), 'b': Q(0), 'd': Q(1)}
|
| 124 |
+
|
| 125 |
+
# x -> a b &(a,y) -> z -- x -> a b y z
|
| 126 |
+
# &(a,b) -> y
|
| 127 |
+
A = {'x': {'a', 'b'}}
|
| 128 |
+
B = [(And('a', 'y'), 'z'), (And('a', 'b'), 'y')]
|
| 129 |
+
assert APPLY(A, B) == {'x': ({'a', 'b', 'y', 'z'}, []),
|
| 130 |
+
'a': (set(), [0, 1]), 'y': Q(0), 'b': Q(1)}
|
| 131 |
+
|
| 132 |
+
# x -> a b &(a,!b) -> c -- x -> a b
|
| 133 |
+
A = {'x': {'a', 'b'}}
|
| 134 |
+
B = [(And('a', Not('b')), 'c')]
|
| 135 |
+
assert APPLY(A, B) == \
|
| 136 |
+
{'x': ({'a', 'b'}, []), 'a': Q(0), Not('b'): Q(0)}
|
| 137 |
+
|
| 138 |
+
# !x -> !a !b &(!a,b) -> c -- !x -> !a !b
|
| 139 |
+
A = {Not('x'): {Not('a'), Not('b')}}
|
| 140 |
+
B = [(And(Not('a'), 'b'), 'c')]
|
| 141 |
+
assert APPLY(A, B) == \
|
| 142 |
+
{Not('x'): ({Not('a'), Not('b')}, []), Not('a'): Q(0), 'b': Q(0)}
|
| 143 |
+
|
| 144 |
+
# x -> a b &(b,c) -> !a -- x -> a b
|
| 145 |
+
A = {'x': {'a', 'b'}}
|
| 146 |
+
B = [(And('b', 'c'), Not('a'))]
|
| 147 |
+
assert APPLY(A, B) == {'x': ({'a', 'b'}, []), 'b': Q(0), 'c': Q(0)}
|
| 148 |
+
|
| 149 |
+
# x -> a b &(a, b) -> c -- x -> a b c p
|
| 150 |
+
# c -> p a
|
| 151 |
+
A = {'x': {'a', 'b'}, 'c': {'p', 'a'}}
|
| 152 |
+
B = [(And('a', 'b'), 'c')]
|
| 153 |
+
assert APPLY(A, B) == {'x': ({'a', 'b', 'c', 'p'}, []),
|
| 154 |
+
'c': ({'p', 'a'}, []), 'a': Q(0), 'b': Q(0)}
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def test_FactRules_parse():
|
| 158 |
+
f = FactRules('a -> b')
|
| 159 |
+
assert f.prereq == {'b': {'a'}, 'a': {'b'}}
|
| 160 |
+
|
| 161 |
+
f = FactRules('a -> !b')
|
| 162 |
+
assert f.prereq == {'b': {'a'}, 'a': {'b'}}
|
| 163 |
+
|
| 164 |
+
f = FactRules('!a -> b')
|
| 165 |
+
assert f.prereq == {'b': {'a'}, 'a': {'b'}}
|
| 166 |
+
|
| 167 |
+
f = FactRules('!a -> !b')
|
| 168 |
+
assert f.prereq == {'b': {'a'}, 'a': {'b'}}
|
| 169 |
+
|
| 170 |
+
f = FactRules('!z == nz')
|
| 171 |
+
assert f.prereq == {'z': {'nz'}, 'nz': {'z'}}
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
def test_FactRules_parse2():
|
| 175 |
+
raises(ValueError, lambda: FactRules('a -> !a'))
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
def test_FactRules_deduce():
|
| 179 |
+
f = FactRules(['a -> b', 'b -> c', 'b -> d', 'c -> e'])
|
| 180 |
+
|
| 181 |
+
def D(facts):
|
| 182 |
+
kb = FactKB(f)
|
| 183 |
+
kb.deduce_all_facts(facts)
|
| 184 |
+
return kb
|
| 185 |
+
|
| 186 |
+
assert D({'a': T}) == {'a': T, 'b': T, 'c': T, 'd': T, 'e': T}
|
| 187 |
+
assert D({'b': T}) == { 'b': T, 'c': T, 'd': T, 'e': T}
|
| 188 |
+
assert D({'c': T}) == { 'c': T, 'e': T}
|
| 189 |
+
assert D({'d': T}) == { 'd': T }
|
| 190 |
+
assert D({'e': T}) == { 'e': T}
|
| 191 |
+
|
| 192 |
+
assert D({'a': F}) == {'a': F }
|
| 193 |
+
assert D({'b': F}) == {'a': F, 'b': F }
|
| 194 |
+
assert D({'c': F}) == {'a': F, 'b': F, 'c': F }
|
| 195 |
+
assert D({'d': F}) == {'a': F, 'b': F, 'd': F }
|
| 196 |
+
|
| 197 |
+
assert D({'a': U}) == {'a': U} # XXX ok?
|
| 198 |
+
|
| 199 |
+
|
| 200 |
+
def test_FactRules_deduce2():
|
| 201 |
+
# pos/neg/zero, but the rules are not sufficient to derive all relations
|
| 202 |
+
f = FactRules(['pos -> !neg', 'pos -> !z'])
|
| 203 |
+
|
| 204 |
+
def D(facts):
|
| 205 |
+
kb = FactKB(f)
|
| 206 |
+
kb.deduce_all_facts(facts)
|
| 207 |
+
return kb
|
| 208 |
+
|
| 209 |
+
assert D({'pos': T}) == {'pos': T, 'neg': F, 'z': F}
|
| 210 |
+
assert D({'pos': F}) == {'pos': F }
|
| 211 |
+
assert D({'neg': T}) == {'pos': F, 'neg': T }
|
| 212 |
+
assert D({'neg': F}) == { 'neg': F }
|
| 213 |
+
assert D({'z': T}) == {'pos': F, 'z': T}
|
| 214 |
+
assert D({'z': F}) == { 'z': F}
|
| 215 |
+
|
| 216 |
+
# pos/neg/zero. rules are sufficient to derive all relations
|
| 217 |
+
f = FactRules(['pos -> !neg', 'neg -> !pos', 'pos -> !z', 'neg -> !z'])
|
| 218 |
+
|
| 219 |
+
assert D({'pos': T}) == {'pos': T, 'neg': F, 'z': F}
|
| 220 |
+
assert D({'pos': F}) == {'pos': F }
|
| 221 |
+
assert D({'neg': T}) == {'pos': F, 'neg': T, 'z': F}
|
| 222 |
+
assert D({'neg': F}) == { 'neg': F }
|
| 223 |
+
assert D({'z': T}) == {'pos': F, 'neg': F, 'z': T}
|
| 224 |
+
assert D({'z': F}) == { 'z': F}
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
def test_FactRules_deduce_multiple():
|
| 228 |
+
# deduction that involves _several_ starting points
|
| 229 |
+
f = FactRules(['real == pos | npos'])
|
| 230 |
+
|
| 231 |
+
def D(facts):
|
| 232 |
+
kb = FactKB(f)
|
| 233 |
+
kb.deduce_all_facts(facts)
|
| 234 |
+
return kb
|
| 235 |
+
|
| 236 |
+
assert D({'real': T}) == {'real': T}
|
| 237 |
+
assert D({'real': F}) == {'real': F, 'pos': F, 'npos': F}
|
| 238 |
+
assert D({'pos': T}) == {'real': T, 'pos': T}
|
| 239 |
+
assert D({'npos': T}) == {'real': T, 'npos': T}
|
| 240 |
+
|
| 241 |
+
# --- key tests below ---
|
| 242 |
+
assert D({'pos': F, 'npos': F}) == {'real': F, 'pos': F, 'npos': F}
|
| 243 |
+
assert D({'real': T, 'pos': F}) == {'real': T, 'pos': F, 'npos': T}
|
| 244 |
+
assert D({'real': T, 'npos': F}) == {'real': T, 'pos': T, 'npos': F}
|
| 245 |
+
|
| 246 |
+
assert D({'pos': T, 'npos': F}) == {'real': T, 'pos': T, 'npos': F}
|
| 247 |
+
assert D({'pos': F, 'npos': T}) == {'real': T, 'pos': F, 'npos': T}
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
def test_FactRules_deduce_multiple2():
|
| 251 |
+
f = FactRules(['real == neg | zero | pos'])
|
| 252 |
+
|
| 253 |
+
def D(facts):
|
| 254 |
+
kb = FactKB(f)
|
| 255 |
+
kb.deduce_all_facts(facts)
|
| 256 |
+
return kb
|
| 257 |
+
|
| 258 |
+
assert D({'real': T}) == {'real': T}
|
| 259 |
+
assert D({'real': F}) == {'real': F, 'neg': F, 'zero': F, 'pos': F}
|
| 260 |
+
assert D({'neg': T}) == {'real': T, 'neg': T}
|
| 261 |
+
assert D({'zero': T}) == {'real': T, 'zero': T}
|
| 262 |
+
assert D({'pos': T}) == {'real': T, 'pos': T}
|
| 263 |
+
|
| 264 |
+
# --- key tests below ---
|
| 265 |
+
assert D({'neg': F, 'zero': F, 'pos': F}) == {'real': F, 'neg': F,
|
| 266 |
+
'zero': F, 'pos': F}
|
| 267 |
+
assert D({'real': T, 'neg': F}) == {'real': T, 'neg': F}
|
| 268 |
+
assert D({'real': T, 'zero': F}) == {'real': T, 'zero': F}
|
| 269 |
+
assert D({'real': T, 'pos': F}) == {'real': T, 'pos': F}
|
| 270 |
+
|
| 271 |
+
assert D({'real': T, 'zero': F, 'pos': F}) == {'real': T,
|
| 272 |
+
'neg': T, 'zero': F, 'pos': F}
|
| 273 |
+
assert D({'real': T, 'neg': F, 'pos': F}) == {'real': T,
|
| 274 |
+
'neg': F, 'zero': T, 'pos': F}
|
| 275 |
+
assert D({'real': T, 'neg': F, 'zero': F }) == {'real': T,
|
| 276 |
+
'neg': F, 'zero': F, 'pos': T}
|
| 277 |
+
|
| 278 |
+
assert D({'neg': T, 'zero': F, 'pos': F}) == {'real': T, 'neg': T,
|
| 279 |
+
'zero': F, 'pos': F}
|
| 280 |
+
assert D({'neg': F, 'zero': T, 'pos': F}) == {'real': T, 'neg': F,
|
| 281 |
+
'zero': T, 'pos': F}
|
| 282 |
+
assert D({'neg': F, 'zero': F, 'pos': T}) == {'real': T, 'neg': F,
|
| 283 |
+
'zero': F, 'pos': T}
|
| 284 |
+
|
| 285 |
+
|
| 286 |
+
def test_FactRules_deduce_base():
|
| 287 |
+
# deduction that starts from base
|
| 288 |
+
|
| 289 |
+
f = FactRules(['real == neg | zero | pos',
|
| 290 |
+
'neg -> real & !zero & !pos',
|
| 291 |
+
'pos -> real & !zero & !neg'])
|
| 292 |
+
base = FactKB(f)
|
| 293 |
+
|
| 294 |
+
base.deduce_all_facts({'real': T, 'neg': F})
|
| 295 |
+
assert base == {'real': T, 'neg': F}
|
| 296 |
+
|
| 297 |
+
base.deduce_all_facts({'zero': F})
|
| 298 |
+
assert base == {'real': T, 'neg': F, 'zero': F, 'pos': T}
|
| 299 |
+
|
| 300 |
+
|
| 301 |
+
def test_FactRules_deduce_staticext():
|
| 302 |
+
# verify that static beta-extensions deduction takes place
|
| 303 |
+
f = FactRules(['real == neg | zero | pos',
|
| 304 |
+
'neg -> real & !zero & !pos',
|
| 305 |
+
'pos -> real & !zero & !neg',
|
| 306 |
+
'nneg == real & !neg',
|
| 307 |
+
'npos == real & !pos'])
|
| 308 |
+
|
| 309 |
+
assert ('npos', True) in f.full_implications[('neg', True)]
|
| 310 |
+
assert ('nneg', True) in f.full_implications[('pos', True)]
|
| 311 |
+
assert ('nneg', True) in f.full_implications[('zero', True)]
|
| 312 |
+
assert ('npos', True) in f.full_implications[('zero', True)]
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_function.py
ADDED
|
@@ -0,0 +1,1459 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.concrete.summations import Sum
|
| 2 |
+
from sympy.core.basic import Basic, _aresame
|
| 3 |
+
from sympy.core.cache import clear_cache
|
| 4 |
+
from sympy.core.containers import Dict, Tuple
|
| 5 |
+
from sympy.core.expr import Expr, unchanged
|
| 6 |
+
from sympy.core.function import (Subs, Function, diff, Lambda, expand,
|
| 7 |
+
nfloat, Derivative)
|
| 8 |
+
from sympy.core.numbers import E, Float, zoo, Rational, pi, I, oo, nan
|
| 9 |
+
from sympy.core.power import Pow
|
| 10 |
+
from sympy.core.relational import Eq
|
| 11 |
+
from sympy.core.singleton import S
|
| 12 |
+
from sympy.core.symbol import symbols, Dummy, Symbol
|
| 13 |
+
from sympy.functions.elementary.complexes import im, re
|
| 14 |
+
from sympy.functions.elementary.exponential import log, exp
|
| 15 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 16 |
+
from sympy.functions.elementary.piecewise import Piecewise
|
| 17 |
+
from sympy.functions.elementary.trigonometric import sin, cos, acos
|
| 18 |
+
from sympy.functions.special.error_functions import expint
|
| 19 |
+
from sympy.functions.special.gamma_functions import loggamma, polygamma
|
| 20 |
+
from sympy.matrices.dense import Matrix
|
| 21 |
+
from sympy.printing.str import sstr
|
| 22 |
+
from sympy.series.order import O
|
| 23 |
+
from sympy.tensor.indexed import Indexed
|
| 24 |
+
from sympy.core.function import (PoleError, _mexpand, arity,
|
| 25 |
+
BadSignatureError, BadArgumentsError)
|
| 26 |
+
from sympy.core.parameters import _exp_is_pow
|
| 27 |
+
from sympy.core.sympify import sympify, SympifyError
|
| 28 |
+
from sympy.matrices import MutableMatrix, ImmutableMatrix
|
| 29 |
+
from sympy.sets.sets import FiniteSet
|
| 30 |
+
from sympy.solvers.solveset import solveset
|
| 31 |
+
from sympy.tensor.array import NDimArray
|
| 32 |
+
from sympy.utilities.iterables import subsets, variations
|
| 33 |
+
from sympy.testing.pytest import XFAIL, raises, warns_deprecated_sympy, _both_exp_pow
|
| 34 |
+
|
| 35 |
+
from sympy.abc import t, w, x, y, z
|
| 36 |
+
f, g, h = symbols('f g h', cls=Function)
|
| 37 |
+
_xi_1, _xi_2, _xi_3 = [Dummy() for i in range(3)]
|
| 38 |
+
|
| 39 |
+
def test_f_expand_complex():
|
| 40 |
+
x = Symbol('x', real=True)
|
| 41 |
+
|
| 42 |
+
assert f(x).expand(complex=True) == I*im(f(x)) + re(f(x))
|
| 43 |
+
assert exp(x).expand(complex=True) == exp(x)
|
| 44 |
+
assert exp(I*x).expand(complex=True) == cos(x) + I*sin(x)
|
| 45 |
+
assert exp(z).expand(complex=True) == cos(im(z))*exp(re(z)) + \
|
| 46 |
+
I*sin(im(z))*exp(re(z))
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def test_bug1():
|
| 50 |
+
e = sqrt(-log(w))
|
| 51 |
+
assert e.subs(log(w), -x) == sqrt(x)
|
| 52 |
+
|
| 53 |
+
e = sqrt(-5*log(w))
|
| 54 |
+
assert e.subs(log(w), -x) == sqrt(5*x)
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
def test_general_function():
|
| 58 |
+
nu = Function('nu')
|
| 59 |
+
|
| 60 |
+
e = nu(x)
|
| 61 |
+
edx = e.diff(x)
|
| 62 |
+
edy = e.diff(y)
|
| 63 |
+
edxdx = e.diff(x).diff(x)
|
| 64 |
+
edxdy = e.diff(x).diff(y)
|
| 65 |
+
assert e == nu(x)
|
| 66 |
+
assert edx != nu(x)
|
| 67 |
+
assert edx == diff(nu(x), x)
|
| 68 |
+
assert edy == 0
|
| 69 |
+
assert edxdx == diff(diff(nu(x), x), x)
|
| 70 |
+
assert edxdy == 0
|
| 71 |
+
|
| 72 |
+
def test_general_function_nullary():
|
| 73 |
+
nu = Function('nu')
|
| 74 |
+
|
| 75 |
+
e = nu()
|
| 76 |
+
edx = e.diff(x)
|
| 77 |
+
edxdx = e.diff(x).diff(x)
|
| 78 |
+
assert e == nu()
|
| 79 |
+
assert edx != nu()
|
| 80 |
+
assert edx == 0
|
| 81 |
+
assert edxdx == 0
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def test_derivative_subs_bug():
|
| 85 |
+
e = diff(g(x), x)
|
| 86 |
+
assert e.subs(g(x), f(x)) != e
|
| 87 |
+
assert e.subs(g(x), f(x)) == Derivative(f(x), x)
|
| 88 |
+
assert e.subs(g(x), -f(x)) == Derivative(-f(x), x)
|
| 89 |
+
|
| 90 |
+
assert e.subs(x, y) == Derivative(g(y), y)
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def test_derivative_subs_self_bug():
|
| 94 |
+
d = diff(f(x), x)
|
| 95 |
+
|
| 96 |
+
assert d.subs(d, y) == y
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def test_derivative_linearity():
|
| 100 |
+
assert diff(-f(x), x) == -diff(f(x), x)
|
| 101 |
+
assert diff(8*f(x), x) == 8*diff(f(x), x)
|
| 102 |
+
assert diff(8*f(x), x) != 7*diff(f(x), x)
|
| 103 |
+
assert diff(8*f(x)*x, x) == 8*f(x) + 8*x*diff(f(x), x)
|
| 104 |
+
assert diff(8*f(x)*y*x, x).expand() == 8*y*f(x) + 8*y*x*diff(f(x), x)
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def test_derivative_evaluate():
|
| 108 |
+
assert Derivative(sin(x), x) != diff(sin(x), x)
|
| 109 |
+
assert Derivative(sin(x), x).doit() == diff(sin(x), x)
|
| 110 |
+
|
| 111 |
+
assert Derivative(Derivative(f(x), x), x) == diff(f(x), x, x)
|
| 112 |
+
assert Derivative(sin(x), x, 0) == sin(x)
|
| 113 |
+
assert Derivative(sin(x), (x, y), (x, -y)) == sin(x)
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
def test_diff_symbols():
|
| 117 |
+
assert diff(f(x, y, z), x, y, z) == Derivative(f(x, y, z), x, y, z)
|
| 118 |
+
assert diff(f(x, y, z), x, x, x) == Derivative(f(x, y, z), x, x, x) == Derivative(f(x, y, z), (x, 3))
|
| 119 |
+
assert diff(f(x, y, z), x, 3) == Derivative(f(x, y, z), x, 3)
|
| 120 |
+
|
| 121 |
+
# issue 5028
|
| 122 |
+
assert [diff(-z + x/y, sym) for sym in (z, x, y)] == [-1, 1/y, -x/y**2]
|
| 123 |
+
assert diff(f(x, y, z), x, y, z, 2) == Derivative(f(x, y, z), x, y, z, z)
|
| 124 |
+
assert diff(f(x, y, z), x, y, z, 2, evaluate=False) == \
|
| 125 |
+
Derivative(f(x, y, z), x, y, z, z)
|
| 126 |
+
assert Derivative(f(x, y, z), x, y, z)._eval_derivative(z) == \
|
| 127 |
+
Derivative(f(x, y, z), x, y, z, z)
|
| 128 |
+
assert Derivative(Derivative(f(x, y, z), x), y)._eval_derivative(z) == \
|
| 129 |
+
Derivative(f(x, y, z), x, y, z)
|
| 130 |
+
|
| 131 |
+
raises(TypeError, lambda: cos(x).diff((x, y)).variables)
|
| 132 |
+
assert cos(x).diff((x, y))._wrt_variables == [x]
|
| 133 |
+
|
| 134 |
+
# issue 23222
|
| 135 |
+
assert sympify("a*x+b").diff("x") == sympify("a")
|
| 136 |
+
|
| 137 |
+
def test_Function():
|
| 138 |
+
class myfunc(Function):
|
| 139 |
+
@classmethod
|
| 140 |
+
def eval(cls): # zero args
|
| 141 |
+
return
|
| 142 |
+
|
| 143 |
+
assert myfunc.nargs == FiniteSet(0)
|
| 144 |
+
assert myfunc().nargs == FiniteSet(0)
|
| 145 |
+
raises(TypeError, lambda: myfunc(x).nargs)
|
| 146 |
+
|
| 147 |
+
class myfunc(Function):
|
| 148 |
+
@classmethod
|
| 149 |
+
def eval(cls, x): # one arg
|
| 150 |
+
return
|
| 151 |
+
|
| 152 |
+
assert myfunc.nargs == FiniteSet(1)
|
| 153 |
+
assert myfunc(x).nargs == FiniteSet(1)
|
| 154 |
+
raises(TypeError, lambda: myfunc(x, y).nargs)
|
| 155 |
+
|
| 156 |
+
class myfunc(Function):
|
| 157 |
+
@classmethod
|
| 158 |
+
def eval(cls, *x): # star args
|
| 159 |
+
return
|
| 160 |
+
|
| 161 |
+
assert myfunc.nargs == S.Naturals0
|
| 162 |
+
assert myfunc(x).nargs == S.Naturals0
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
def test_nargs():
|
| 166 |
+
f = Function('f')
|
| 167 |
+
assert f.nargs == S.Naturals0
|
| 168 |
+
assert f(1).nargs == S.Naturals0
|
| 169 |
+
assert Function('f', nargs=2)(1, 2).nargs == FiniteSet(2)
|
| 170 |
+
assert sin.nargs == FiniteSet(1)
|
| 171 |
+
assert sin(2).nargs == FiniteSet(1)
|
| 172 |
+
assert log.nargs == FiniteSet(1, 2)
|
| 173 |
+
assert log(2).nargs == FiniteSet(1, 2)
|
| 174 |
+
assert Function('f', nargs=2).nargs == FiniteSet(2)
|
| 175 |
+
assert Function('f', nargs=0).nargs == FiniteSet(0)
|
| 176 |
+
assert Function('f', nargs=(0, 1)).nargs == FiniteSet(0, 1)
|
| 177 |
+
assert Function('f', nargs=None).nargs == S.Naturals0
|
| 178 |
+
raises(ValueError, lambda: Function('f', nargs=()))
|
| 179 |
+
|
| 180 |
+
def test_nargs_inheritance():
|
| 181 |
+
class f1(Function):
|
| 182 |
+
nargs = 2
|
| 183 |
+
class f2(f1):
|
| 184 |
+
pass
|
| 185 |
+
class f3(f2):
|
| 186 |
+
pass
|
| 187 |
+
class f4(f3):
|
| 188 |
+
nargs = 1,2
|
| 189 |
+
class f5(f4):
|
| 190 |
+
pass
|
| 191 |
+
class f6(f5):
|
| 192 |
+
pass
|
| 193 |
+
class f7(f6):
|
| 194 |
+
nargs=None
|
| 195 |
+
class f8(f7):
|
| 196 |
+
pass
|
| 197 |
+
class f9(f8):
|
| 198 |
+
pass
|
| 199 |
+
class f10(f9):
|
| 200 |
+
nargs = 1
|
| 201 |
+
class f11(f10):
|
| 202 |
+
pass
|
| 203 |
+
assert f1.nargs == FiniteSet(2)
|
| 204 |
+
assert f2.nargs == FiniteSet(2)
|
| 205 |
+
assert f3.nargs == FiniteSet(2)
|
| 206 |
+
assert f4.nargs == FiniteSet(1, 2)
|
| 207 |
+
assert f5.nargs == FiniteSet(1, 2)
|
| 208 |
+
assert f6.nargs == FiniteSet(1, 2)
|
| 209 |
+
assert f7.nargs == S.Naturals0
|
| 210 |
+
assert f8.nargs == S.Naturals0
|
| 211 |
+
assert f9.nargs == S.Naturals0
|
| 212 |
+
assert f10.nargs == FiniteSet(1)
|
| 213 |
+
assert f11.nargs == FiniteSet(1)
|
| 214 |
+
|
| 215 |
+
def test_arity():
|
| 216 |
+
f = lambda x, y: 1
|
| 217 |
+
assert arity(f) == 2
|
| 218 |
+
def f(x, y, z=None):
|
| 219 |
+
pass
|
| 220 |
+
assert arity(f) == (2, 3)
|
| 221 |
+
assert arity(lambda *x: x) is None
|
| 222 |
+
assert arity(log) == (1, 2)
|
| 223 |
+
|
| 224 |
+
|
| 225 |
+
def test_Lambda():
|
| 226 |
+
e = Lambda(x, x**2)
|
| 227 |
+
assert e(4) == 16
|
| 228 |
+
assert e(x) == x**2
|
| 229 |
+
assert e(y) == y**2
|
| 230 |
+
|
| 231 |
+
assert Lambda((), 42)() == 42
|
| 232 |
+
assert unchanged(Lambda, (), 42)
|
| 233 |
+
assert Lambda((), 42) != Lambda((), 43)
|
| 234 |
+
assert Lambda((), f(x))() == f(x)
|
| 235 |
+
assert Lambda((), 42).nargs == FiniteSet(0)
|
| 236 |
+
|
| 237 |
+
assert unchanged(Lambda, (x,), x**2)
|
| 238 |
+
assert Lambda(x, x**2) == Lambda((x,), x**2)
|
| 239 |
+
assert Lambda(x, x**2) != Lambda(x, x**2 + 1)
|
| 240 |
+
assert Lambda((x, y), x**y) != Lambda((y, x), y**x)
|
| 241 |
+
assert Lambda((x, y), x**y) != Lambda((x, y), y**x)
|
| 242 |
+
|
| 243 |
+
assert Lambda((x, y), x**y)(x, y) == x**y
|
| 244 |
+
assert Lambda((x, y), x**y)(3, 3) == 3**3
|
| 245 |
+
assert Lambda((x, y), x**y)(x, 3) == x**3
|
| 246 |
+
assert Lambda((x, y), x**y)(3, y) == 3**y
|
| 247 |
+
assert Lambda(x, f(x))(x) == f(x)
|
| 248 |
+
assert Lambda(x, x**2)(e(x)) == x**4
|
| 249 |
+
assert e(e(x)) == x**4
|
| 250 |
+
|
| 251 |
+
x1, x2 = (Indexed('x', i) for i in (1, 2))
|
| 252 |
+
assert Lambda((x1, x2), x1 + x2)(x, y) == x + y
|
| 253 |
+
|
| 254 |
+
assert Lambda((x, y), x + y).nargs == FiniteSet(2)
|
| 255 |
+
|
| 256 |
+
p = x, y, z, t
|
| 257 |
+
assert Lambda(p, t*(x + y + z))(*p) == t * (x + y + z)
|
| 258 |
+
|
| 259 |
+
eq = Lambda(x, 2*x) + Lambda(y, 2*y)
|
| 260 |
+
assert eq != 2*Lambda(x, 2*x)
|
| 261 |
+
assert eq.as_dummy() == 2*Lambda(x, 2*x).as_dummy()
|
| 262 |
+
assert Lambda(x, 2*x) not in [ Lambda(x, x) ]
|
| 263 |
+
raises(BadSignatureError, lambda: Lambda(1, x))
|
| 264 |
+
assert Lambda(x, 1)(1) is S.One
|
| 265 |
+
|
| 266 |
+
raises(BadSignatureError, lambda: Lambda((x, x), x + 2))
|
| 267 |
+
raises(BadSignatureError, lambda: Lambda(((x, x), y), x))
|
| 268 |
+
raises(BadSignatureError, lambda: Lambda(((y, x), x), x))
|
| 269 |
+
raises(BadSignatureError, lambda: Lambda(((y, 1), 2), x))
|
| 270 |
+
|
| 271 |
+
with warns_deprecated_sympy():
|
| 272 |
+
assert Lambda([x, y], x+y) == Lambda((x, y), x+y)
|
| 273 |
+
|
| 274 |
+
flam = Lambda(((x, y),), x + y)
|
| 275 |
+
assert flam((2, 3)) == 5
|
| 276 |
+
flam = Lambda(((x, y), z), x + y + z)
|
| 277 |
+
assert flam((2, 3), 1) == 6
|
| 278 |
+
flam = Lambda((((x, y), z),), x + y + z)
|
| 279 |
+
assert flam(((2, 3), 1)) == 6
|
| 280 |
+
raises(BadArgumentsError, lambda: flam(1, 2, 3))
|
| 281 |
+
flam = Lambda( (x,), (x, x))
|
| 282 |
+
assert flam(1,) == (1, 1)
|
| 283 |
+
assert flam((1,)) == ((1,), (1,))
|
| 284 |
+
flam = Lambda( ((x,),), (x, x))
|
| 285 |
+
raises(BadArgumentsError, lambda: flam(1))
|
| 286 |
+
assert flam((1,)) == (1, 1)
|
| 287 |
+
|
| 288 |
+
# Previously TypeError was raised so this is potentially needed for
|
| 289 |
+
# backwards compatibility.
|
| 290 |
+
assert issubclass(BadSignatureError, TypeError)
|
| 291 |
+
assert issubclass(BadArgumentsError, TypeError)
|
| 292 |
+
|
| 293 |
+
# These are tested to see they don't raise:
|
| 294 |
+
hash(Lambda(x, 2*x))
|
| 295 |
+
hash(Lambda(x, x)) # IdentityFunction subclass
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
def test_IdentityFunction():
|
| 299 |
+
assert Lambda(x, x) is Lambda(y, y) is S.IdentityFunction
|
| 300 |
+
assert Lambda(x, 2*x) is not S.IdentityFunction
|
| 301 |
+
assert Lambda((x, y), x) is not S.IdentityFunction
|
| 302 |
+
|
| 303 |
+
|
| 304 |
+
def test_Lambda_symbols():
|
| 305 |
+
assert Lambda(x, 2*x).free_symbols == set()
|
| 306 |
+
assert Lambda(x, x*y).free_symbols == {y}
|
| 307 |
+
assert Lambda((), 42).free_symbols == set()
|
| 308 |
+
assert Lambda((), x*y).free_symbols == {x,y}
|
| 309 |
+
|
| 310 |
+
|
| 311 |
+
def test_functionclas_symbols():
|
| 312 |
+
assert f.free_symbols == set()
|
| 313 |
+
|
| 314 |
+
|
| 315 |
+
def test_Lambda_arguments():
|
| 316 |
+
raises(TypeError, lambda: Lambda(x, 2*x)(x, y))
|
| 317 |
+
raises(TypeError, lambda: Lambda((x, y), x + y)(x))
|
| 318 |
+
raises(TypeError, lambda: Lambda((), 42)(x))
|
| 319 |
+
|
| 320 |
+
|
| 321 |
+
def test_Lambda_equality():
|
| 322 |
+
assert Lambda((x, y), 2*x) == Lambda((x, y), 2*x)
|
| 323 |
+
# these, of course, should never be equal
|
| 324 |
+
assert Lambda(x, 2*x) != Lambda((x, y), 2*x)
|
| 325 |
+
assert Lambda(x, 2*x) != 2*x
|
| 326 |
+
# But it is tempting to want expressions that differ only
|
| 327 |
+
# in bound symbols to compare the same. But this is not what
|
| 328 |
+
# Python's `==` is intended to do; two objects that compare
|
| 329 |
+
# as equal means that they are indistibguishable and cache to the
|
| 330 |
+
# same value. We wouldn't want to expression that are
|
| 331 |
+
# mathematically the same but written in different variables to be
|
| 332 |
+
# interchanged else what is the point of allowing for different
|
| 333 |
+
# variable names?
|
| 334 |
+
assert Lambda(x, 2*x) != Lambda(y, 2*y)
|
| 335 |
+
|
| 336 |
+
|
| 337 |
+
def test_Subs():
|
| 338 |
+
assert Subs(1, (), ()) is S.One
|
| 339 |
+
# check null subs influence on hashing
|
| 340 |
+
assert Subs(x, y, z) != Subs(x, y, 1)
|
| 341 |
+
# neutral subs works
|
| 342 |
+
assert Subs(x, x, 1).subs(x, y).has(y)
|
| 343 |
+
# self mapping var/point
|
| 344 |
+
assert Subs(Derivative(f(x), (x, 2)), x, x).doit() == f(x).diff(x, x)
|
| 345 |
+
assert Subs(x, x, 0).has(x) # it's a structural answer
|
| 346 |
+
assert not Subs(x, x, 0).free_symbols
|
| 347 |
+
assert Subs(Subs(x + y, x, 2), y, 1) == Subs(x + y, (x, y), (2, 1))
|
| 348 |
+
assert Subs(x, (x,), (0,)) == Subs(x, x, 0)
|
| 349 |
+
assert Subs(x, x, 0) == Subs(y, y, 0)
|
| 350 |
+
assert Subs(x, x, 0).subs(x, 1) == Subs(x, x, 0)
|
| 351 |
+
assert Subs(y, x, 0).subs(y, 1) == Subs(1, x, 0)
|
| 352 |
+
assert Subs(f(x), x, 0).doit() == f(0)
|
| 353 |
+
assert Subs(f(x**2), x**2, 0).doit() == f(0)
|
| 354 |
+
assert Subs(f(x, y, z), (x, y, z), (0, 1, 1)) != \
|
| 355 |
+
Subs(f(x, y, z), (x, y, z), (0, 0, 1))
|
| 356 |
+
assert Subs(x, y, 2).subs(x, y).doit() == 2
|
| 357 |
+
assert Subs(f(x, y), (x, y, z), (0, 1, 1)) != \
|
| 358 |
+
Subs(f(x, y) + z, (x, y, z), (0, 1, 0))
|
| 359 |
+
assert Subs(f(x, y), (x, y), (0, 1)).doit() == f(0, 1)
|
| 360 |
+
assert Subs(Subs(f(x, y), x, 0), y, 1).doit() == f(0, 1)
|
| 361 |
+
raises(ValueError, lambda: Subs(f(x, y), (x, y), (0, 0, 1)))
|
| 362 |
+
raises(ValueError, lambda: Subs(f(x, y), (x, x, y), (0, 0, 1)))
|
| 363 |
+
|
| 364 |
+
assert len(Subs(f(x, y), (x, y), (0, 1)).variables) == 2
|
| 365 |
+
assert Subs(f(x, y), (x, y), (0, 1)).point == Tuple(0, 1)
|
| 366 |
+
|
| 367 |
+
assert Subs(f(x), x, 0) == Subs(f(y), y, 0)
|
| 368 |
+
assert Subs(f(x, y), (x, y), (0, 1)) == Subs(f(x, y), (y, x), (1, 0))
|
| 369 |
+
assert Subs(f(x)*y, (x, y), (0, 1)) == Subs(f(y)*x, (y, x), (0, 1))
|
| 370 |
+
assert Subs(f(x)*y, (x, y), (1, 1)) == Subs(f(y)*x, (x, y), (1, 1))
|
| 371 |
+
|
| 372 |
+
assert Subs(f(x), x, 0).subs(x, 1).doit() == f(0)
|
| 373 |
+
assert Subs(f(x), x, y).subs(y, 0) == Subs(f(x), x, 0)
|
| 374 |
+
assert Subs(y*f(x), x, y).subs(y, 2) == Subs(2*f(x), x, 2)
|
| 375 |
+
assert (2 * Subs(f(x), x, 0)).subs(Subs(f(x), x, 0), y) == 2*y
|
| 376 |
+
|
| 377 |
+
assert Subs(f(x), x, 0).free_symbols == set()
|
| 378 |
+
assert Subs(f(x, y), x, z).free_symbols == {y, z}
|
| 379 |
+
|
| 380 |
+
assert Subs(f(x).diff(x), x, 0).doit(), Subs(f(x).diff(x), x, 0)
|
| 381 |
+
assert Subs(1 + f(x).diff(x), x, 0).doit(), 1 + Subs(f(x).diff(x), x, 0)
|
| 382 |
+
assert Subs(y*f(x, y).diff(x), (x, y), (0, 2)).doit() == \
|
| 383 |
+
2*Subs(Derivative(f(x, 2), x), x, 0)
|
| 384 |
+
assert Subs(y**2*f(x), x, 0).diff(y) == 2*y*f(0)
|
| 385 |
+
|
| 386 |
+
e = Subs(y**2*f(x), x, y)
|
| 387 |
+
assert e.diff(y) == e.doit().diff(y) == y**2*Derivative(f(y), y) + 2*y*f(y)
|
| 388 |
+
|
| 389 |
+
assert Subs(f(x), x, 0) + Subs(f(x), x, 0) == 2*Subs(f(x), x, 0)
|
| 390 |
+
e1 = Subs(z*f(x), x, 1)
|
| 391 |
+
e2 = Subs(z*f(y), y, 1)
|
| 392 |
+
assert e1 + e2 == 2*e1
|
| 393 |
+
assert e1.__hash__() == e2.__hash__()
|
| 394 |
+
assert Subs(z*f(x + 1), x, 1) not in [ e1, e2 ]
|
| 395 |
+
assert Derivative(f(x), x).subs(x, g(x)) == Derivative(f(g(x)), g(x))
|
| 396 |
+
assert Derivative(f(x), x).subs(x, x + y) == Subs(Derivative(f(x), x),
|
| 397 |
+
x, x + y)
|
| 398 |
+
assert Subs(f(x)*cos(y) + z, (x, y), (0, pi/3)).n(2) == \
|
| 399 |
+
Subs(f(x)*cos(y) + z, (x, y), (0, pi/3)).evalf(2) == \
|
| 400 |
+
z + Rational('1/2').n(2)*f(0)
|
| 401 |
+
|
| 402 |
+
assert f(x).diff(x).subs(x, 0).subs(x, y) == f(x).diff(x).subs(x, 0)
|
| 403 |
+
assert (x*f(x).diff(x).subs(x, 0)).subs(x, y) == y*f(x).diff(x).subs(x, 0)
|
| 404 |
+
assert Subs(Derivative(g(x)**2, g(x), x), g(x), exp(x)
|
| 405 |
+
).doit() == 2*exp(x)
|
| 406 |
+
assert Subs(Derivative(g(x)**2, g(x), x), g(x), exp(x)
|
| 407 |
+
).doit(deep=False) == 2*Derivative(exp(x), x)
|
| 408 |
+
assert Derivative(f(x, g(x)), x).doit() == Derivative(
|
| 409 |
+
f(x, g(x)), g(x))*Derivative(g(x), x) + Subs(Derivative(
|
| 410 |
+
f(y, g(x)), y), y, x)
|
| 411 |
+
|
| 412 |
+
def test_doitdoit():
|
| 413 |
+
done = Derivative(f(x, g(x)), x, g(x)).doit()
|
| 414 |
+
assert done == done.doit()
|
| 415 |
+
|
| 416 |
+
|
| 417 |
+
@XFAIL
|
| 418 |
+
def test_Subs2():
|
| 419 |
+
# this reflects a limitation of subs(), probably won't fix
|
| 420 |
+
assert Subs(f(x), x**2, x).doit() == f(sqrt(x))
|
| 421 |
+
|
| 422 |
+
|
| 423 |
+
def test_expand_function():
|
| 424 |
+
assert expand(x + y) == x + y
|
| 425 |
+
assert expand(x + y, complex=True) == I*im(x) + I*im(y) + re(x) + re(y)
|
| 426 |
+
assert expand((x + y)**11, modulus=11) == x**11 + y**11
|
| 427 |
+
|
| 428 |
+
|
| 429 |
+
def test_function_comparable():
|
| 430 |
+
assert sin(x).is_comparable is False
|
| 431 |
+
assert cos(x).is_comparable is False
|
| 432 |
+
|
| 433 |
+
assert sin(Float('0.1')).is_comparable is True
|
| 434 |
+
assert cos(Float('0.1')).is_comparable is True
|
| 435 |
+
|
| 436 |
+
assert sin(E).is_comparable is True
|
| 437 |
+
assert cos(E).is_comparable is True
|
| 438 |
+
|
| 439 |
+
assert sin(Rational(1, 3)).is_comparable is True
|
| 440 |
+
assert cos(Rational(1, 3)).is_comparable is True
|
| 441 |
+
|
| 442 |
+
|
| 443 |
+
def test_function_comparable_infinities():
|
| 444 |
+
assert sin(oo).is_comparable is False
|
| 445 |
+
assert sin(-oo).is_comparable is False
|
| 446 |
+
assert sin(zoo).is_comparable is False
|
| 447 |
+
assert sin(nan).is_comparable is False
|
| 448 |
+
|
| 449 |
+
|
| 450 |
+
def test_deriv1():
|
| 451 |
+
# These all require derivatives evaluated at a point (issue 4719) to work.
|
| 452 |
+
# See issue 4624
|
| 453 |
+
assert f(2*x).diff(x) == 2*Subs(Derivative(f(x), x), x, 2*x)
|
| 454 |
+
assert (f(x)**3).diff(x) == 3*f(x)**2*f(x).diff(x)
|
| 455 |
+
assert (f(2*x)**3).diff(x) == 6*f(2*x)**2*Subs(
|
| 456 |
+
Derivative(f(x), x), x, 2*x)
|
| 457 |
+
|
| 458 |
+
assert f(2 + x).diff(x) == Subs(Derivative(f(x), x), x, x + 2)
|
| 459 |
+
assert f(2 + 3*x).diff(x) == 3*Subs(
|
| 460 |
+
Derivative(f(x), x), x, 3*x + 2)
|
| 461 |
+
assert f(3*sin(x)).diff(x) == 3*cos(x)*Subs(
|
| 462 |
+
Derivative(f(x), x), x, 3*sin(x))
|
| 463 |
+
|
| 464 |
+
# See issue 8510
|
| 465 |
+
assert f(x, x + z).diff(x) == (
|
| 466 |
+
Subs(Derivative(f(y, x + z), y), y, x) +
|
| 467 |
+
Subs(Derivative(f(x, y), y), y, x + z))
|
| 468 |
+
assert f(x, x**2).diff(x) == (
|
| 469 |
+
2*x*Subs(Derivative(f(x, y), y), y, x**2) +
|
| 470 |
+
Subs(Derivative(f(y, x**2), y), y, x))
|
| 471 |
+
# but Subs is not always necessary
|
| 472 |
+
assert f(x, g(y)).diff(g(y)) == Derivative(f(x, g(y)), g(y))
|
| 473 |
+
|
| 474 |
+
|
| 475 |
+
def test_deriv2():
|
| 476 |
+
assert (x**3).diff(x) == 3*x**2
|
| 477 |
+
assert (x**3).diff(x, evaluate=False) != 3*x**2
|
| 478 |
+
assert (x**3).diff(x, evaluate=False) == Derivative(x**3, x)
|
| 479 |
+
|
| 480 |
+
assert diff(x**3, x) == 3*x**2
|
| 481 |
+
assert diff(x**3, x, evaluate=False) != 3*x**2
|
| 482 |
+
assert diff(x**3, x, evaluate=False) == Derivative(x**3, x)
|
| 483 |
+
|
| 484 |
+
|
| 485 |
+
def test_func_deriv():
|
| 486 |
+
assert f(x).diff(x) == Derivative(f(x), x)
|
| 487 |
+
# issue 4534
|
| 488 |
+
assert f(x, y).diff(x, y) - f(x, y).diff(y, x) == 0
|
| 489 |
+
assert Derivative(f(x, y), x, y).args[1:] == ((x, 1), (y, 1))
|
| 490 |
+
assert Derivative(f(x, y), y, x).args[1:] == ((y, 1), (x, 1))
|
| 491 |
+
assert (Derivative(f(x, y), x, y) - Derivative(f(x, y), y, x)).doit() == 0
|
| 492 |
+
|
| 493 |
+
|
| 494 |
+
def test_suppressed_evaluation():
|
| 495 |
+
a = sin(0, evaluate=False)
|
| 496 |
+
assert a != 0
|
| 497 |
+
assert a.func is sin
|
| 498 |
+
assert a.args == (0,)
|
| 499 |
+
|
| 500 |
+
|
| 501 |
+
def test_function_evalf():
|
| 502 |
+
def eq(a, b, eps):
|
| 503 |
+
return abs(a - b) < eps
|
| 504 |
+
assert eq(sin(1).evalf(15), Float("0.841470984807897"), 1e-13)
|
| 505 |
+
assert eq(
|
| 506 |
+
sin(2).evalf(25), Float("0.9092974268256816953960199", 25), 1e-23)
|
| 507 |
+
assert eq(sin(1 + I).evalf(
|
| 508 |
+
15), Float("1.29845758141598") + Float("0.634963914784736")*I, 1e-13)
|
| 509 |
+
assert eq(exp(1 + I).evalf(15), Float(
|
| 510 |
+
"1.46869393991588") + Float("2.28735528717884239")*I, 1e-13)
|
| 511 |
+
assert eq(exp(-0.5 + 1.5*I).evalf(15), Float(
|
| 512 |
+
"0.0429042815937374") + Float("0.605011292285002")*I, 1e-13)
|
| 513 |
+
assert eq(log(pi + sqrt(2)*I).evalf(
|
| 514 |
+
15), Float("1.23699044022052") + Float("0.422985442737893")*I, 1e-13)
|
| 515 |
+
assert eq(cos(100).evalf(15), Float("0.86231887228768"), 1e-13)
|
| 516 |
+
|
| 517 |
+
|
| 518 |
+
def test_extensibility_eval():
|
| 519 |
+
class MyFunc(Function):
|
| 520 |
+
@classmethod
|
| 521 |
+
def eval(cls, *args):
|
| 522 |
+
return (0, 0, 0)
|
| 523 |
+
assert MyFunc(0) == (0, 0, 0)
|
| 524 |
+
|
| 525 |
+
|
| 526 |
+
@_both_exp_pow
|
| 527 |
+
def test_function_non_commutative():
|
| 528 |
+
x = Symbol('x', commutative=False)
|
| 529 |
+
assert f(x).is_commutative is False
|
| 530 |
+
assert sin(x).is_commutative is False
|
| 531 |
+
assert exp(x).is_commutative is False
|
| 532 |
+
assert log(x).is_commutative is False
|
| 533 |
+
assert f(x).is_complex is False
|
| 534 |
+
assert sin(x).is_complex is False
|
| 535 |
+
assert exp(x).is_complex is False
|
| 536 |
+
assert log(x).is_complex is False
|
| 537 |
+
|
| 538 |
+
|
| 539 |
+
def test_function_complex():
|
| 540 |
+
x = Symbol('x', complex=True)
|
| 541 |
+
xzf = Symbol('x', complex=True, zero=False)
|
| 542 |
+
assert f(x).is_commutative is True
|
| 543 |
+
assert sin(x).is_commutative is True
|
| 544 |
+
assert exp(x).is_commutative is True
|
| 545 |
+
assert log(x).is_commutative is True
|
| 546 |
+
assert f(x).is_complex is None
|
| 547 |
+
assert sin(x).is_complex is True
|
| 548 |
+
assert exp(x).is_complex is True
|
| 549 |
+
assert log(x).is_complex is None
|
| 550 |
+
assert log(xzf).is_complex is True
|
| 551 |
+
|
| 552 |
+
|
| 553 |
+
def test_function__eval_nseries():
|
| 554 |
+
n = Symbol('n')
|
| 555 |
+
|
| 556 |
+
assert sin(x)._eval_nseries(x, 2, None) == x + O(x**2)
|
| 557 |
+
assert sin(x + 1)._eval_nseries(x, 2, None) == x*cos(1) + sin(1) + O(x**2)
|
| 558 |
+
assert sin(pi*(1 - x))._eval_nseries(x, 2, None) == pi*x + O(x**2)
|
| 559 |
+
assert acos(1 - x**2)._eval_nseries(x, 2, None) == sqrt(2)*sqrt(x**2) + O(x**2)
|
| 560 |
+
assert polygamma(n, x + 1)._eval_nseries(x, 2, None) == \
|
| 561 |
+
polygamma(n, 1) + polygamma(n + 1, 1)*x + O(x**2)
|
| 562 |
+
raises(PoleError, lambda: sin(1/x)._eval_nseries(x, 2, None))
|
| 563 |
+
assert acos(1 - x)._eval_nseries(x, 2, None) == sqrt(2)*sqrt(x) + sqrt(2)*x**(S(3)/2)/12 + O(x**2)
|
| 564 |
+
assert acos(1 + x)._eval_nseries(x, 2, None) == sqrt(2)*sqrt(-x) + sqrt(2)*(-x)**(S(3)/2)/12 + O(x**2)
|
| 565 |
+
assert loggamma(1/x)._eval_nseries(x, 0, None) == \
|
| 566 |
+
log(x)/2 - log(x)/x - 1/x + O(1, x)
|
| 567 |
+
assert loggamma(log(1/x)).nseries(x, n=1, logx=y) == loggamma(-y)
|
| 568 |
+
|
| 569 |
+
# issue 6725:
|
| 570 |
+
assert expint(Rational(3, 2), -x)._eval_nseries(x, 5, None) == \
|
| 571 |
+
2 - 2*x - x**2/3 - x**3/15 - x**4/84 - 2*I*sqrt(pi)*sqrt(x) + O(x**5)
|
| 572 |
+
assert sin(sqrt(x))._eval_nseries(x, 3, None) == \
|
| 573 |
+
sqrt(x) - x**Rational(3, 2)/6 + x**Rational(5, 2)/120 + O(x**3)
|
| 574 |
+
|
| 575 |
+
# issue 19065:
|
| 576 |
+
s1 = f(x,y).series(y, n=2)
|
| 577 |
+
assert {i.name for i in s1.atoms(Symbol)} == {'x', 'xi', 'y'}
|
| 578 |
+
xi = Symbol('xi')
|
| 579 |
+
s2 = f(xi, y).series(y, n=2)
|
| 580 |
+
assert {i.name for i in s2.atoms(Symbol)} == {'xi', 'xi0', 'y'}
|
| 581 |
+
|
| 582 |
+
def test_doit():
|
| 583 |
+
n = Symbol('n', integer=True)
|
| 584 |
+
f = Sum(2 * n * x, (n, 1, 3))
|
| 585 |
+
d = Derivative(f, x)
|
| 586 |
+
assert d.doit() == 12
|
| 587 |
+
assert d.doit(deep=False) == Sum(2*n, (n, 1, 3))
|
| 588 |
+
|
| 589 |
+
|
| 590 |
+
def test_evalf_default():
|
| 591 |
+
from sympy.functions.special.gamma_functions import polygamma
|
| 592 |
+
assert type(sin(4.0)) == Float
|
| 593 |
+
assert type(re(sin(I + 1.0))) == Float
|
| 594 |
+
assert type(im(sin(I + 1.0))) == Float
|
| 595 |
+
assert type(sin(4)) == sin
|
| 596 |
+
assert type(polygamma(2.0, 4.0)) == Float
|
| 597 |
+
assert type(sin(Rational(1, 4))) == sin
|
| 598 |
+
|
| 599 |
+
|
| 600 |
+
def test_issue_5399():
|
| 601 |
+
args = [x, y, S(2), S.Half]
|
| 602 |
+
|
| 603 |
+
def ok(a):
|
| 604 |
+
"""Return True if the input args for diff are ok"""
|
| 605 |
+
if not a:
|
| 606 |
+
return False
|
| 607 |
+
if a[0].is_Symbol is False:
|
| 608 |
+
return False
|
| 609 |
+
s_at = [i for i in range(len(a)) if a[i].is_Symbol]
|
| 610 |
+
n_at = [i for i in range(len(a)) if not a[i].is_Symbol]
|
| 611 |
+
# every symbol is followed by symbol or int
|
| 612 |
+
# every number is followed by a symbol
|
| 613 |
+
return (all(a[i + 1].is_Symbol or a[i + 1].is_Integer
|
| 614 |
+
for i in s_at if i + 1 < len(a)) and
|
| 615 |
+
all(a[i + 1].is_Symbol
|
| 616 |
+
for i in n_at if i + 1 < len(a)))
|
| 617 |
+
eq = x**10*y**8
|
| 618 |
+
for a in subsets(args):
|
| 619 |
+
for v in variations(a, len(a)):
|
| 620 |
+
if ok(v):
|
| 621 |
+
eq.diff(*v) # does not raise
|
| 622 |
+
else:
|
| 623 |
+
raises(ValueError, lambda: eq.diff(*v))
|
| 624 |
+
|
| 625 |
+
|
| 626 |
+
def test_derivative_numerically():
|
| 627 |
+
z0 = x._random()
|
| 628 |
+
assert abs(Derivative(sin(x), x).doit_numerically(z0) - cos(z0)) < 1e-15
|
| 629 |
+
|
| 630 |
+
|
| 631 |
+
def test_fdiff_argument_index_error():
|
| 632 |
+
from sympy.core.function import ArgumentIndexError
|
| 633 |
+
|
| 634 |
+
class myfunc(Function):
|
| 635 |
+
nargs = 1 # define since there is no eval routine
|
| 636 |
+
|
| 637 |
+
def fdiff(self, idx):
|
| 638 |
+
raise ArgumentIndexError
|
| 639 |
+
mf = myfunc(x)
|
| 640 |
+
assert mf.diff(x) == Derivative(mf, x)
|
| 641 |
+
raises(TypeError, lambda: myfunc(x, x))
|
| 642 |
+
|
| 643 |
+
|
| 644 |
+
def test_deriv_wrt_function():
|
| 645 |
+
x = f(t)
|
| 646 |
+
xd = diff(x, t)
|
| 647 |
+
xdd = diff(xd, t)
|
| 648 |
+
y = g(t)
|
| 649 |
+
yd = diff(y, t)
|
| 650 |
+
|
| 651 |
+
assert diff(x, t) == xd
|
| 652 |
+
assert diff(2 * x + 4, t) == 2 * xd
|
| 653 |
+
assert diff(2 * x + 4 + y, t) == 2 * xd + yd
|
| 654 |
+
assert diff(2 * x + 4 + y * x, t) == 2 * xd + x * yd + xd * y
|
| 655 |
+
assert diff(2 * x + 4 + y * x, x) == 2 + y
|
| 656 |
+
assert (diff(4 * x**2 + 3 * x + x * y, t) == 3 * xd + x * yd + xd * y +
|
| 657 |
+
8 * x * xd)
|
| 658 |
+
assert (diff(4 * x**2 + 3 * xd + x * y, t) == 3 * xdd + x * yd + xd * y +
|
| 659 |
+
8 * x * xd)
|
| 660 |
+
assert diff(4 * x**2 + 3 * xd + x * y, xd) == 3
|
| 661 |
+
assert diff(4 * x**2 + 3 * xd + x * y, xdd) == 0
|
| 662 |
+
assert diff(sin(x), t) == xd * cos(x)
|
| 663 |
+
assert diff(exp(x), t) == xd * exp(x)
|
| 664 |
+
assert diff(sqrt(x), t) == xd / (2 * sqrt(x))
|
| 665 |
+
|
| 666 |
+
|
| 667 |
+
def test_diff_wrt_value():
|
| 668 |
+
assert Expr()._diff_wrt is False
|
| 669 |
+
assert x._diff_wrt is True
|
| 670 |
+
assert f(x)._diff_wrt is True
|
| 671 |
+
assert Derivative(f(x), x)._diff_wrt is True
|
| 672 |
+
assert Derivative(x**2, x)._diff_wrt is False
|
| 673 |
+
|
| 674 |
+
|
| 675 |
+
def test_diff_wrt():
|
| 676 |
+
fx = f(x)
|
| 677 |
+
dfx = diff(f(x), x)
|
| 678 |
+
ddfx = diff(f(x), x, x)
|
| 679 |
+
|
| 680 |
+
assert diff(sin(fx) + fx**2, fx) == cos(fx) + 2*fx
|
| 681 |
+
assert diff(sin(dfx) + dfx**2, dfx) == cos(dfx) + 2*dfx
|
| 682 |
+
assert diff(sin(ddfx) + ddfx**2, ddfx) == cos(ddfx) + 2*ddfx
|
| 683 |
+
assert diff(fx**2, dfx) == 0
|
| 684 |
+
assert diff(fx**2, ddfx) == 0
|
| 685 |
+
assert diff(dfx**2, fx) == 0
|
| 686 |
+
assert diff(dfx**2, ddfx) == 0
|
| 687 |
+
assert diff(ddfx**2, dfx) == 0
|
| 688 |
+
|
| 689 |
+
assert diff(fx*dfx*ddfx, fx) == dfx*ddfx
|
| 690 |
+
assert diff(fx*dfx*ddfx, dfx) == fx*ddfx
|
| 691 |
+
assert diff(fx*dfx*ddfx, ddfx) == fx*dfx
|
| 692 |
+
|
| 693 |
+
assert diff(f(x), x).diff(f(x)) == 0
|
| 694 |
+
assert (sin(f(x)) - cos(diff(f(x), x))).diff(f(x)) == cos(f(x))
|
| 695 |
+
|
| 696 |
+
assert diff(sin(fx), fx, x) == diff(sin(fx), x, fx)
|
| 697 |
+
|
| 698 |
+
# Chain rule cases
|
| 699 |
+
assert f(g(x)).diff(x) == \
|
| 700 |
+
Derivative(g(x), x)*Derivative(f(g(x)), g(x))
|
| 701 |
+
assert diff(f(g(x), h(y)), x) == \
|
| 702 |
+
Derivative(g(x), x)*Derivative(f(g(x), h(y)), g(x))
|
| 703 |
+
assert diff(f(g(x), h(x)), x) == (
|
| 704 |
+
Derivative(f(g(x), h(x)), g(x))*Derivative(g(x), x) +
|
| 705 |
+
Derivative(f(g(x), h(x)), h(x))*Derivative(h(x), x))
|
| 706 |
+
assert f(
|
| 707 |
+
sin(x)).diff(x) == cos(x)*Subs(Derivative(f(x), x), x, sin(x))
|
| 708 |
+
|
| 709 |
+
assert diff(f(g(x)), g(x)) == Derivative(f(g(x)), g(x))
|
| 710 |
+
|
| 711 |
+
|
| 712 |
+
def test_diff_wrt_func_subs():
|
| 713 |
+
assert f(g(x)).diff(x).subs(g, Lambda(x, 2*x)).doit() == f(2*x).diff(x)
|
| 714 |
+
|
| 715 |
+
|
| 716 |
+
def test_subs_in_derivative():
|
| 717 |
+
expr = sin(x*exp(y))
|
| 718 |
+
u = Function('u')
|
| 719 |
+
v = Function('v')
|
| 720 |
+
assert Derivative(expr, y).subs(expr, y) == Derivative(y, y)
|
| 721 |
+
assert Derivative(expr, y).subs(y, x).doit() == \
|
| 722 |
+
Derivative(expr, y).doit().subs(y, x)
|
| 723 |
+
assert Derivative(f(x, y), y).subs(y, x) == Subs(Derivative(f(x, y), y), y, x)
|
| 724 |
+
assert Derivative(f(x, y), y).subs(x, y) == Subs(Derivative(f(x, y), y), x, y)
|
| 725 |
+
assert Derivative(f(x, y), y).subs(y, g(x, y)) == Subs(Derivative(f(x, y), y), y, g(x, y)).doit()
|
| 726 |
+
assert Derivative(f(x, y), y).subs(x, g(x, y)) == Subs(Derivative(f(x, y), y), x, g(x, y))
|
| 727 |
+
assert Derivative(f(x, y), g(y)).subs(x, g(x, y)) == Derivative(f(g(x, y), y), g(y))
|
| 728 |
+
assert Derivative(f(u(x), h(y)), h(y)).subs(h(y), g(x, y)) == \
|
| 729 |
+
Subs(Derivative(f(u(x), h(y)), h(y)), h(y), g(x, y)).doit()
|
| 730 |
+
assert Derivative(f(x, y), y).subs(y, z) == Derivative(f(x, z), z)
|
| 731 |
+
assert Derivative(f(x, y), y).subs(y, g(y)) == Derivative(f(x, g(y)), g(y))
|
| 732 |
+
assert Derivative(f(g(x), h(y)), h(y)).subs(h(y), u(y)) == \
|
| 733 |
+
Derivative(f(g(x), u(y)), u(y))
|
| 734 |
+
assert Derivative(f(x, f(x, x)), f(x, x)).subs(
|
| 735 |
+
f, Lambda((x, y), x + y)) == Subs(
|
| 736 |
+
Derivative(z + x, z), z, 2*x)
|
| 737 |
+
assert Subs(Derivative(f(f(x)), x), f, cos).doit() == sin(x)*sin(cos(x))
|
| 738 |
+
assert Subs(Derivative(f(f(x)), f(x)), f, cos).doit() == -sin(cos(x))
|
| 739 |
+
# Issue 13791. No comparison (it's a long formula) but this used to raise an exception.
|
| 740 |
+
assert isinstance(v(x, y, u(x, y)).diff(y).diff(x).diff(y), Expr)
|
| 741 |
+
# This is also related to issues 13791 and 13795; issue 15190
|
| 742 |
+
F = Lambda((x, y), exp(2*x + 3*y))
|
| 743 |
+
abstract = f(x, f(x, x)).diff(x, 2)
|
| 744 |
+
concrete = F(x, F(x, x)).diff(x, 2)
|
| 745 |
+
assert (abstract.subs(f, F).doit() - concrete).simplify() == 0
|
| 746 |
+
# don't introduce a new symbol if not necessary
|
| 747 |
+
assert x in f(x).diff(x).subs(x, 0).atoms()
|
| 748 |
+
# case (4)
|
| 749 |
+
assert Derivative(f(x,f(x,y)), x, y).subs(x, g(y)
|
| 750 |
+
) == Subs(Derivative(f(x, f(x, y)), x, y), x, g(y))
|
| 751 |
+
|
| 752 |
+
assert Derivative(f(x, x), x).subs(x, 0
|
| 753 |
+
) == Subs(Derivative(f(x, x), x), x, 0)
|
| 754 |
+
# issue 15194
|
| 755 |
+
assert Derivative(f(y, g(x)), (x, z)).subs(z, x
|
| 756 |
+
) == Derivative(f(y, g(x)), (x, x))
|
| 757 |
+
|
| 758 |
+
df = f(x).diff(x)
|
| 759 |
+
assert df.subs(df, 1) is S.One
|
| 760 |
+
assert df.diff(df) is S.One
|
| 761 |
+
dxy = Derivative(f(x, y), x, y)
|
| 762 |
+
dyx = Derivative(f(x, y), y, x)
|
| 763 |
+
assert dxy.subs(Derivative(f(x, y), y, x), 1) is S.One
|
| 764 |
+
assert dxy.diff(dyx) is S.One
|
| 765 |
+
assert Derivative(f(x, y), x, 2, y, 3).subs(
|
| 766 |
+
dyx, g(x, y)) == Derivative(g(x, y), x, 1, y, 2)
|
| 767 |
+
assert Derivative(f(x, x - y), y).subs(x, x + y) == Subs(
|
| 768 |
+
Derivative(f(x, x - y), y), x, x + y)
|
| 769 |
+
|
| 770 |
+
|
| 771 |
+
def test_diff_wrt_not_allowed():
|
| 772 |
+
# issue 7027 included
|
| 773 |
+
for wrt in (
|
| 774 |
+
cos(x), re(x), x**2, x*y, 1 + x,
|
| 775 |
+
Derivative(cos(x), x), Derivative(f(f(x)), x)):
|
| 776 |
+
raises(ValueError, lambda: diff(f(x), wrt))
|
| 777 |
+
# if we don't differentiate wrt then don't raise error
|
| 778 |
+
assert diff(exp(x*y), x*y, 0) == exp(x*y)
|
| 779 |
+
|
| 780 |
+
|
| 781 |
+
def test_diff_wrt_intlike():
|
| 782 |
+
class Two:
|
| 783 |
+
def __int__(self):
|
| 784 |
+
return 2
|
| 785 |
+
|
| 786 |
+
assert cos(x).diff(x, Two()) == -cos(x)
|
| 787 |
+
|
| 788 |
+
|
| 789 |
+
def test_klein_gordon_lagrangian():
|
| 790 |
+
m = Symbol('m')
|
| 791 |
+
phi = f(x, t)
|
| 792 |
+
|
| 793 |
+
L = -(diff(phi, t)**2 - diff(phi, x)**2 - m**2*phi**2)/2
|
| 794 |
+
eqna = Eq(
|
| 795 |
+
diff(L, phi) - diff(L, diff(phi, x), x) - diff(L, diff(phi, t), t), 0)
|
| 796 |
+
eqnb = Eq(diff(phi, t, t) - diff(phi, x, x) + m**2*phi, 0)
|
| 797 |
+
assert eqna == eqnb
|
| 798 |
+
|
| 799 |
+
|
| 800 |
+
def test_sho_lagrangian():
|
| 801 |
+
m = Symbol('m')
|
| 802 |
+
k = Symbol('k')
|
| 803 |
+
x = f(t)
|
| 804 |
+
|
| 805 |
+
L = m*diff(x, t)**2/2 - k*x**2/2
|
| 806 |
+
eqna = Eq(diff(L, x), diff(L, diff(x, t), t))
|
| 807 |
+
eqnb = Eq(-k*x, m*diff(x, t, t))
|
| 808 |
+
assert eqna == eqnb
|
| 809 |
+
|
| 810 |
+
assert diff(L, x, t) == diff(L, t, x)
|
| 811 |
+
assert diff(L, diff(x, t), t) == m*diff(x, t, 2)
|
| 812 |
+
assert diff(L, t, diff(x, t)) == -k*x + m*diff(x, t, 2)
|
| 813 |
+
|
| 814 |
+
|
| 815 |
+
def test_straight_line():
|
| 816 |
+
F = f(x)
|
| 817 |
+
Fd = F.diff(x)
|
| 818 |
+
L = sqrt(1 + Fd**2)
|
| 819 |
+
assert diff(L, F) == 0
|
| 820 |
+
assert diff(L, Fd) == Fd/sqrt(1 + Fd**2)
|
| 821 |
+
|
| 822 |
+
|
| 823 |
+
def test_sort_variable():
|
| 824 |
+
vsort = Derivative._sort_variable_count
|
| 825 |
+
def vsort0(*v, reverse=False):
|
| 826 |
+
return [i[0] for i in vsort([(i, 0) for i in (
|
| 827 |
+
reversed(v) if reverse else v)])]
|
| 828 |
+
|
| 829 |
+
for R in range(2):
|
| 830 |
+
assert vsort0(y, x, reverse=R) == [x, y]
|
| 831 |
+
assert vsort0(f(x), x, reverse=R) == [x, f(x)]
|
| 832 |
+
assert vsort0(f(y), f(x), reverse=R) == [f(x), f(y)]
|
| 833 |
+
assert vsort0(g(x), f(y), reverse=R) == [f(y), g(x)]
|
| 834 |
+
assert vsort0(f(x, y), f(x), reverse=R) == [f(x), f(x, y)]
|
| 835 |
+
fx = f(x).diff(x)
|
| 836 |
+
assert vsort0(fx, y, reverse=R) == [y, fx]
|
| 837 |
+
fy = f(y).diff(y)
|
| 838 |
+
assert vsort0(fy, fx, reverse=R) == [fx, fy]
|
| 839 |
+
fxx = fx.diff(x)
|
| 840 |
+
assert vsort0(fxx, fx, reverse=R) == [fx, fxx]
|
| 841 |
+
assert vsort0(Basic(x), f(x), reverse=R) == [f(x), Basic(x)]
|
| 842 |
+
assert vsort0(Basic(y), Basic(x), reverse=R) == [Basic(x), Basic(y)]
|
| 843 |
+
assert vsort0(Basic(y, z), Basic(x), reverse=R) == [
|
| 844 |
+
Basic(x), Basic(y, z)]
|
| 845 |
+
assert vsort0(fx, x, reverse=R) == [
|
| 846 |
+
x, fx] if R else [fx, x]
|
| 847 |
+
assert vsort0(Basic(x), x, reverse=R) == [
|
| 848 |
+
x, Basic(x)] if R else [Basic(x), x]
|
| 849 |
+
assert vsort0(Basic(f(x)), f(x), reverse=R) == [
|
| 850 |
+
f(x), Basic(f(x))] if R else [Basic(f(x)), f(x)]
|
| 851 |
+
assert vsort0(Basic(x, z), Basic(x), reverse=R) == [
|
| 852 |
+
Basic(x), Basic(x, z)] if R else [Basic(x, z), Basic(x)]
|
| 853 |
+
assert vsort([]) == []
|
| 854 |
+
assert _aresame(vsort([(x, 1)]), [Tuple(x, 1)])
|
| 855 |
+
assert vsort([(x, y), (x, z)]) == [(x, y + z)]
|
| 856 |
+
assert vsort([(y, 1), (x, 1 + y)]) == [(x, 1 + y), (y, 1)]
|
| 857 |
+
# coverage complete; legacy tests below
|
| 858 |
+
assert vsort([(x, 3), (y, 2), (z, 1)]) == [(x, 3), (y, 2), (z, 1)]
|
| 859 |
+
assert vsort([(h(x), 1), (g(x), 1), (f(x), 1)]) == [
|
| 860 |
+
(f(x), 1), (g(x), 1), (h(x), 1)]
|
| 861 |
+
assert vsort([(z, 1), (y, 2), (x, 3), (h(x), 1), (g(x), 1),
|
| 862 |
+
(f(x), 1)]) == [(x, 3), (y, 2), (z, 1), (f(x), 1), (g(x), 1),
|
| 863 |
+
(h(x), 1)]
|
| 864 |
+
assert vsort([(x, 1), (f(x), 1), (y, 1), (f(y), 1)]) == [(x, 1),
|
| 865 |
+
(y, 1), (f(x), 1), (f(y), 1)]
|
| 866 |
+
assert vsort([(y, 1), (x, 2), (g(x), 1), (f(x), 1), (z, 1),
|
| 867 |
+
(h(x), 1), (y, 2), (x, 1)]) == [(x, 3), (y, 3), (z, 1),
|
| 868 |
+
(f(x), 1), (g(x), 1), (h(x), 1)]
|
| 869 |
+
assert vsort([(z, 1), (y, 1), (f(x), 1), (x, 1), (f(x), 1),
|
| 870 |
+
(g(x), 1)]) == [(x, 1), (y, 1), (z, 1), (f(x), 2), (g(x), 1)]
|
| 871 |
+
assert vsort([(z, 1), (y, 2), (f(x), 1), (x, 2), (f(x), 2),
|
| 872 |
+
(g(x), 1), (z, 2), (z, 1), (y, 1), (x, 1)]) == [(x, 3), (y, 3),
|
| 873 |
+
(z, 4), (f(x), 3), (g(x), 1)]
|
| 874 |
+
assert vsort(((y, 2), (x, 1), (y, 1), (x, 1))) == [(x, 2), (y, 3)]
|
| 875 |
+
assert isinstance(vsort([(x, 3), (y, 2), (z, 1)])[0], Tuple)
|
| 876 |
+
assert vsort([(x, 1), (f(x), 1), (x, 1)]) == [(x, 2), (f(x), 1)]
|
| 877 |
+
assert vsort([(y, 2), (x, 3), (z, 1)]) == [(x, 3), (y, 2), (z, 1)]
|
| 878 |
+
assert vsort([(h(y), 1), (g(x), 1), (f(x), 1)]) == [
|
| 879 |
+
(f(x), 1), (g(x), 1), (h(y), 1)]
|
| 880 |
+
assert vsort([(x, 1), (y, 1), (x, 1)]) == [(x, 2), (y, 1)]
|
| 881 |
+
assert vsort([(f(x), 1), (f(y), 1), (f(x), 1)]) == [
|
| 882 |
+
(f(x), 2), (f(y), 1)]
|
| 883 |
+
dfx = f(x).diff(x)
|
| 884 |
+
self = [(dfx, 1), (x, 1)]
|
| 885 |
+
assert vsort(self) == self
|
| 886 |
+
assert vsort([
|
| 887 |
+
(dfx, 1), (y, 1), (f(x), 1), (x, 1), (f(y), 1), (x, 1)]) == [
|
| 888 |
+
(y, 1), (f(x), 1), (f(y), 1), (dfx, 1), (x, 2)]
|
| 889 |
+
dfy = f(y).diff(y)
|
| 890 |
+
assert vsort([(dfy, 1), (dfx, 1)]) == [(dfx, 1), (dfy, 1)]
|
| 891 |
+
d2fx = dfx.diff(x)
|
| 892 |
+
assert vsort([(d2fx, 1), (dfx, 1)]) == [(dfx, 1), (d2fx, 1)]
|
| 893 |
+
|
| 894 |
+
|
| 895 |
+
def test_multiple_derivative():
|
| 896 |
+
# Issue #15007
|
| 897 |
+
assert f(x, y).diff(y, y, x, y, x
|
| 898 |
+
) == Derivative(f(x, y), (x, 2), (y, 3))
|
| 899 |
+
|
| 900 |
+
|
| 901 |
+
def test_unhandled():
|
| 902 |
+
class MyExpr(Expr):
|
| 903 |
+
def _eval_derivative(self, s):
|
| 904 |
+
if not s.name.startswith('xi'):
|
| 905 |
+
return self
|
| 906 |
+
else:
|
| 907 |
+
return None
|
| 908 |
+
|
| 909 |
+
eq = MyExpr(f(x), y, z)
|
| 910 |
+
assert diff(eq, x, y, f(x), z) == Derivative(eq, f(x))
|
| 911 |
+
assert diff(eq, f(x), x) == Derivative(eq, f(x))
|
| 912 |
+
assert f(x, y).diff(x,(y, z)) == Derivative(f(x, y), x, (y, z))
|
| 913 |
+
assert f(x, y).diff(x,(y, 0)) == Derivative(f(x, y), x)
|
| 914 |
+
|
| 915 |
+
|
| 916 |
+
def test_nfloat():
|
| 917 |
+
from sympy.core.basic import _aresame
|
| 918 |
+
from sympy.polys.rootoftools import rootof
|
| 919 |
+
|
| 920 |
+
x = Symbol("x")
|
| 921 |
+
eq = x**Rational(4, 3) + 4*x**(S.One/3)/3
|
| 922 |
+
assert _aresame(nfloat(eq), x**Rational(4, 3) + (4.0/3)*x**(S.One/3))
|
| 923 |
+
assert _aresame(nfloat(eq, exponent=True), x**(4.0/3) + (4.0/3)*x**(1.0/3))
|
| 924 |
+
eq = x**Rational(4, 3) + 4*x**(x/3)/3
|
| 925 |
+
assert _aresame(nfloat(eq), x**Rational(4, 3) + (4.0/3)*x**(x/3))
|
| 926 |
+
big = 12345678901234567890
|
| 927 |
+
# specify precision to match value used in nfloat
|
| 928 |
+
Float_big = Float(big, 15)
|
| 929 |
+
assert _aresame(nfloat(big), Float_big)
|
| 930 |
+
assert _aresame(nfloat(big*x), Float_big*x)
|
| 931 |
+
assert _aresame(nfloat(x**big, exponent=True), x**Float_big)
|
| 932 |
+
assert nfloat(cos(x + sqrt(2))) == cos(x + nfloat(sqrt(2)))
|
| 933 |
+
|
| 934 |
+
# issue 6342
|
| 935 |
+
f = S('x*lamda + lamda**3*(x/2 + 1/2) + lamda**2 + 1/4')
|
| 936 |
+
assert not any(a.free_symbols for a in solveset(f.subs(x, -0.139)))
|
| 937 |
+
|
| 938 |
+
# issue 6632
|
| 939 |
+
assert nfloat(-100000*sqrt(2500000001) + 5000000001) == \
|
| 940 |
+
9.99999999800000e-11
|
| 941 |
+
|
| 942 |
+
# issue 7122
|
| 943 |
+
eq = cos(3*x**4 + y)*rootof(x**5 + 3*x**3 + 1, 0)
|
| 944 |
+
assert str(nfloat(eq, exponent=False, n=1)) == '-0.7*cos(3.0*x**4 + y)'
|
| 945 |
+
|
| 946 |
+
# issue 10933
|
| 947 |
+
for ti in (dict, Dict):
|
| 948 |
+
d = ti({S.Half: S.Half})
|
| 949 |
+
n = nfloat(d)
|
| 950 |
+
assert isinstance(n, ti)
|
| 951 |
+
assert _aresame(list(n.items()).pop(), (S.Half, Float(.5)))
|
| 952 |
+
for ti in (dict, Dict):
|
| 953 |
+
d = ti({S.Half: S.Half})
|
| 954 |
+
n = nfloat(d, dkeys=True)
|
| 955 |
+
assert isinstance(n, ti)
|
| 956 |
+
assert _aresame(list(n.items()).pop(), (Float(.5), Float(.5)))
|
| 957 |
+
d = [S.Half]
|
| 958 |
+
n = nfloat(d)
|
| 959 |
+
assert type(n) is list
|
| 960 |
+
assert _aresame(n[0], Float(.5))
|
| 961 |
+
assert _aresame(nfloat(Eq(x, S.Half)).rhs, Float(.5))
|
| 962 |
+
assert _aresame(nfloat(S(True)), S(True))
|
| 963 |
+
assert _aresame(nfloat(Tuple(S.Half))[0], Float(.5))
|
| 964 |
+
assert nfloat(Eq((3 - I)**2/2 + I, 0)) == S.false
|
| 965 |
+
# pass along kwargs
|
| 966 |
+
assert nfloat([{S.Half: x}], dkeys=True) == [{Float(0.5): x}]
|
| 967 |
+
|
| 968 |
+
# Issue 17706
|
| 969 |
+
A = MutableMatrix([[1, 2], [3, 4]])
|
| 970 |
+
B = MutableMatrix(
|
| 971 |
+
[[Float('1.0', precision=53), Float('2.0', precision=53)],
|
| 972 |
+
[Float('3.0', precision=53), Float('4.0', precision=53)]])
|
| 973 |
+
assert _aresame(nfloat(A), B)
|
| 974 |
+
A = ImmutableMatrix([[1, 2], [3, 4]])
|
| 975 |
+
B = ImmutableMatrix(
|
| 976 |
+
[[Float('1.0', precision=53), Float('2.0', precision=53)],
|
| 977 |
+
[Float('3.0', precision=53), Float('4.0', precision=53)]])
|
| 978 |
+
assert _aresame(nfloat(A), B)
|
| 979 |
+
|
| 980 |
+
# issue 22524
|
| 981 |
+
f = Function('f')
|
| 982 |
+
assert not nfloat(f(2)).atoms(Float)
|
| 983 |
+
|
| 984 |
+
|
| 985 |
+
def test_issue_7068():
|
| 986 |
+
from sympy.abc import a, b
|
| 987 |
+
f = Function('f')
|
| 988 |
+
y1 = Dummy('y')
|
| 989 |
+
y2 = Dummy('y')
|
| 990 |
+
func1 = f(a + y1 * b)
|
| 991 |
+
func2 = f(a + y2 * b)
|
| 992 |
+
func1_y = func1.diff(y1)
|
| 993 |
+
func2_y = func2.diff(y2)
|
| 994 |
+
assert func1_y != func2_y
|
| 995 |
+
z1 = Subs(f(a), a, y1)
|
| 996 |
+
z2 = Subs(f(a), a, y2)
|
| 997 |
+
assert z1 != z2
|
| 998 |
+
|
| 999 |
+
|
| 1000 |
+
def test_issue_7231():
|
| 1001 |
+
from sympy.abc import a
|
| 1002 |
+
ans1 = f(x).series(x, a)
|
| 1003 |
+
res = (f(a) + (-a + x)*Subs(Derivative(f(y), y), y, a) +
|
| 1004 |
+
(-a + x)**2*Subs(Derivative(f(y), y, y), y, a)/2 +
|
| 1005 |
+
(-a + x)**3*Subs(Derivative(f(y), y, y, y),
|
| 1006 |
+
y, a)/6 +
|
| 1007 |
+
(-a + x)**4*Subs(Derivative(f(y), y, y, y, y),
|
| 1008 |
+
y, a)/24 +
|
| 1009 |
+
(-a + x)**5*Subs(Derivative(f(y), y, y, y, y, y),
|
| 1010 |
+
y, a)/120 + O((-a + x)**6, (x, a)))
|
| 1011 |
+
assert res == ans1
|
| 1012 |
+
ans2 = f(x).series(x, a)
|
| 1013 |
+
assert res == ans2
|
| 1014 |
+
|
| 1015 |
+
|
| 1016 |
+
def test_issue_7687():
|
| 1017 |
+
from sympy.core.function import Function
|
| 1018 |
+
from sympy.abc import x
|
| 1019 |
+
f = Function('f')(x)
|
| 1020 |
+
ff = Function('f')(x)
|
| 1021 |
+
match_with_cache = ff.matches(f)
|
| 1022 |
+
assert isinstance(f, type(ff))
|
| 1023 |
+
clear_cache()
|
| 1024 |
+
ff = Function('f')(x)
|
| 1025 |
+
assert isinstance(f, type(ff))
|
| 1026 |
+
assert match_with_cache == ff.matches(f)
|
| 1027 |
+
|
| 1028 |
+
|
| 1029 |
+
def test_issue_7688():
|
| 1030 |
+
from sympy.core.function import Function, UndefinedFunction
|
| 1031 |
+
|
| 1032 |
+
f = Function('f') # actually an UndefinedFunction
|
| 1033 |
+
clear_cache()
|
| 1034 |
+
class A(UndefinedFunction):
|
| 1035 |
+
pass
|
| 1036 |
+
a = A('f')
|
| 1037 |
+
assert isinstance(a, type(f))
|
| 1038 |
+
|
| 1039 |
+
|
| 1040 |
+
def test_mexpand():
|
| 1041 |
+
from sympy.abc import x
|
| 1042 |
+
assert _mexpand(None) is None
|
| 1043 |
+
assert _mexpand(1) is S.One
|
| 1044 |
+
assert _mexpand(x*(x + 1)**2) == (x*(x + 1)**2).expand()
|
| 1045 |
+
|
| 1046 |
+
|
| 1047 |
+
def test_issue_8469():
|
| 1048 |
+
# This should not take forever to run
|
| 1049 |
+
N = 40
|
| 1050 |
+
def g(w, theta):
|
| 1051 |
+
return 1/(1+exp(w-theta))
|
| 1052 |
+
|
| 1053 |
+
ws = symbols(['w%i'%i for i in range(N)])
|
| 1054 |
+
import functools
|
| 1055 |
+
expr = functools.reduce(g, ws)
|
| 1056 |
+
assert isinstance(expr, Pow)
|
| 1057 |
+
|
| 1058 |
+
|
| 1059 |
+
def test_issue_12996():
|
| 1060 |
+
# foo=True imitates the sort of arguments that Derivative can get
|
| 1061 |
+
# from Integral when it passes doit to the expression
|
| 1062 |
+
assert Derivative(im(x), x).doit(foo=True) == Derivative(im(x), x)
|
| 1063 |
+
|
| 1064 |
+
|
| 1065 |
+
def test_should_evalf():
|
| 1066 |
+
# This should not take forever to run (see #8506)
|
| 1067 |
+
assert isinstance(sin((1.0 + 1.0*I)**10000 + 1), sin)
|
| 1068 |
+
|
| 1069 |
+
|
| 1070 |
+
def test_Derivative_as_finite_difference():
|
| 1071 |
+
# Central 1st derivative at gridpoint
|
| 1072 |
+
x, h = symbols('x h', real=True)
|
| 1073 |
+
dfdx = f(x).diff(x)
|
| 1074 |
+
assert (dfdx.as_finite_difference([x-2, x-1, x, x+1, x+2]) -
|
| 1075 |
+
(S.One/12*(f(x-2)-f(x+2)) + Rational(2, 3)*(f(x+1)-f(x-1)))).simplify() == 0
|
| 1076 |
+
|
| 1077 |
+
# Central 1st derivative "half-way"
|
| 1078 |
+
assert (dfdx.as_finite_difference() -
|
| 1079 |
+
(f(x + S.Half)-f(x - S.Half))).simplify() == 0
|
| 1080 |
+
assert (dfdx.as_finite_difference(h) -
|
| 1081 |
+
(f(x + h/S(2))-f(x - h/S(2)))/h).simplify() == 0
|
| 1082 |
+
assert (dfdx.as_finite_difference([x - 3*h, x-h, x+h, x + 3*h]) -
|
| 1083 |
+
(S(9)/(8*2*h)*(f(x+h) - f(x-h)) +
|
| 1084 |
+
S.One/(24*2*h)*(f(x - 3*h) - f(x + 3*h)))).simplify() == 0
|
| 1085 |
+
|
| 1086 |
+
# One sided 1st derivative at gridpoint
|
| 1087 |
+
assert (dfdx.as_finite_difference([0, 1, 2], 0) -
|
| 1088 |
+
(Rational(-3, 2)*f(0) + 2*f(1) - f(2)/2)).simplify() == 0
|
| 1089 |
+
assert (dfdx.as_finite_difference([x, x+h], x) -
|
| 1090 |
+
(f(x+h) - f(x))/h).simplify() == 0
|
| 1091 |
+
assert (dfdx.as_finite_difference([x-h, x, x+h], x-h) -
|
| 1092 |
+
(-S(3)/(2*h)*f(x-h) + 2/h*f(x) -
|
| 1093 |
+
S.One/(2*h)*f(x+h))).simplify() == 0
|
| 1094 |
+
|
| 1095 |
+
# One sided 1st derivative "half-way"
|
| 1096 |
+
assert (dfdx.as_finite_difference([x-h, x+h, x + 3*h, x + 5*h, x + 7*h])
|
| 1097 |
+
- 1/(2*h)*(-S(11)/(12)*f(x-h) + S(17)/(24)*f(x+h)
|
| 1098 |
+
+ Rational(3, 8)*f(x + 3*h) - Rational(5, 24)*f(x + 5*h)
|
| 1099 |
+
+ S.One/24*f(x + 7*h))).simplify() == 0
|
| 1100 |
+
|
| 1101 |
+
d2fdx2 = f(x).diff(x, 2)
|
| 1102 |
+
# Central 2nd derivative at gridpoint
|
| 1103 |
+
assert (d2fdx2.as_finite_difference([x-h, x, x+h]) -
|
| 1104 |
+
h**-2 * (f(x-h) + f(x+h) - 2*f(x))).simplify() == 0
|
| 1105 |
+
|
| 1106 |
+
assert (d2fdx2.as_finite_difference([x - 2*h, x-h, x, x+h, x + 2*h]) -
|
| 1107 |
+
h**-2 * (Rational(-1, 12)*(f(x - 2*h) + f(x + 2*h)) +
|
| 1108 |
+
Rational(4, 3)*(f(x+h) + f(x-h)) - Rational(5, 2)*f(x))).simplify() == 0
|
| 1109 |
+
|
| 1110 |
+
# Central 2nd derivative "half-way"
|
| 1111 |
+
assert (d2fdx2.as_finite_difference([x - 3*h, x-h, x+h, x + 3*h]) -
|
| 1112 |
+
(2*h)**-2 * (S.Half*(f(x - 3*h) + f(x + 3*h)) -
|
| 1113 |
+
S.Half*(f(x+h) + f(x-h)))).simplify() == 0
|
| 1114 |
+
|
| 1115 |
+
# One sided 2nd derivative at gridpoint
|
| 1116 |
+
assert (d2fdx2.as_finite_difference([x, x+h, x + 2*h, x + 3*h]) -
|
| 1117 |
+
h**-2 * (2*f(x) - 5*f(x+h) +
|
| 1118 |
+
4*f(x+2*h) - f(x+3*h))).simplify() == 0
|
| 1119 |
+
|
| 1120 |
+
# One sided 2nd derivative at "half-way"
|
| 1121 |
+
assert (d2fdx2.as_finite_difference([x-h, x+h, x + 3*h, x + 5*h]) -
|
| 1122 |
+
(2*h)**-2 * (Rational(3, 2)*f(x-h) - Rational(7, 2)*f(x+h) + Rational(5, 2)*f(x + 3*h) -
|
| 1123 |
+
S.Half*f(x + 5*h))).simplify() == 0
|
| 1124 |
+
|
| 1125 |
+
d3fdx3 = f(x).diff(x, 3)
|
| 1126 |
+
# Central 3rd derivative at gridpoint
|
| 1127 |
+
assert (d3fdx3.as_finite_difference() -
|
| 1128 |
+
(-f(x - Rational(3, 2)) + 3*f(x - S.Half) -
|
| 1129 |
+
3*f(x + S.Half) + f(x + Rational(3, 2)))).simplify() == 0
|
| 1130 |
+
|
| 1131 |
+
assert (d3fdx3.as_finite_difference(
|
| 1132 |
+
[x - 3*h, x - 2*h, x-h, x, x+h, x + 2*h, x + 3*h]) -
|
| 1133 |
+
h**-3 * (S.One/8*(f(x - 3*h) - f(x + 3*h)) - f(x - 2*h) +
|
| 1134 |
+
f(x + 2*h) + Rational(13, 8)*(f(x-h) - f(x+h)))).simplify() == 0
|
| 1135 |
+
|
| 1136 |
+
# Central 3rd derivative at "half-way"
|
| 1137 |
+
assert (d3fdx3.as_finite_difference([x - 3*h, x-h, x+h, x + 3*h]) -
|
| 1138 |
+
(2*h)**-3 * (f(x + 3*h)-f(x - 3*h) +
|
| 1139 |
+
3*(f(x-h)-f(x+h)))).simplify() == 0
|
| 1140 |
+
|
| 1141 |
+
# One sided 3rd derivative at gridpoint
|
| 1142 |
+
assert (d3fdx3.as_finite_difference([x, x+h, x + 2*h, x + 3*h]) -
|
| 1143 |
+
h**-3 * (f(x + 3*h)-f(x) + 3*(f(x+h)-f(x + 2*h)))).simplify() == 0
|
| 1144 |
+
|
| 1145 |
+
# One sided 3rd derivative at "half-way"
|
| 1146 |
+
assert (d3fdx3.as_finite_difference([x-h, x+h, x + 3*h, x + 5*h]) -
|
| 1147 |
+
(2*h)**-3 * (f(x + 5*h)-f(x-h) +
|
| 1148 |
+
3*(f(x+h)-f(x + 3*h)))).simplify() == 0
|
| 1149 |
+
|
| 1150 |
+
# issue 11007
|
| 1151 |
+
y = Symbol('y', real=True)
|
| 1152 |
+
d2fdxdy = f(x, y).diff(x, y)
|
| 1153 |
+
|
| 1154 |
+
ref0 = Derivative(f(x + S.Half, y), y) - Derivative(f(x - S.Half, y), y)
|
| 1155 |
+
assert (d2fdxdy.as_finite_difference(wrt=x) - ref0).simplify() == 0
|
| 1156 |
+
|
| 1157 |
+
half = S.Half
|
| 1158 |
+
xm, xp, ym, yp = x-half, x+half, y-half, y+half
|
| 1159 |
+
ref2 = f(xm, ym) + f(xp, yp) - f(xp, ym) - f(xm, yp)
|
| 1160 |
+
assert (d2fdxdy.as_finite_difference() - ref2).simplify() == 0
|
| 1161 |
+
|
| 1162 |
+
|
| 1163 |
+
def test_issue_11159():
|
| 1164 |
+
# Tests Application._eval_subs
|
| 1165 |
+
with _exp_is_pow(False):
|
| 1166 |
+
expr1 = E
|
| 1167 |
+
expr0 = expr1 * expr1
|
| 1168 |
+
expr1 = expr0.subs(expr1,expr0)
|
| 1169 |
+
assert expr0 == expr1
|
| 1170 |
+
with _exp_is_pow(True):
|
| 1171 |
+
expr1 = E
|
| 1172 |
+
expr0 = expr1 * expr1
|
| 1173 |
+
expr2 = expr0.subs(expr1, expr0)
|
| 1174 |
+
assert expr2 == E ** 4
|
| 1175 |
+
|
| 1176 |
+
|
| 1177 |
+
def test_issue_12005():
|
| 1178 |
+
e1 = Subs(Derivative(f(x), x), x, x)
|
| 1179 |
+
assert e1.diff(x) == Derivative(f(x), x, x)
|
| 1180 |
+
e2 = Subs(Derivative(f(x), x), x, x**2 + 1)
|
| 1181 |
+
assert e2.diff(x) == 2*x*Subs(Derivative(f(x), x, x), x, x**2 + 1)
|
| 1182 |
+
e3 = Subs(Derivative(f(x) + y**2 - y, y), y, y**2)
|
| 1183 |
+
assert e3.diff(y) == 4*y
|
| 1184 |
+
e4 = Subs(Derivative(f(x + y), y), y, (x**2))
|
| 1185 |
+
assert e4.diff(y) is S.Zero
|
| 1186 |
+
e5 = Subs(Derivative(f(x), x), (y, z), (y, z))
|
| 1187 |
+
assert e5.diff(x) == Derivative(f(x), x, x)
|
| 1188 |
+
assert f(g(x)).diff(g(x), g(x)) == Derivative(f(g(x)), g(x), g(x))
|
| 1189 |
+
|
| 1190 |
+
|
| 1191 |
+
def test_issue_13843():
|
| 1192 |
+
x = symbols('x')
|
| 1193 |
+
f = Function('f')
|
| 1194 |
+
m, n = symbols('m n', integer=True)
|
| 1195 |
+
assert Derivative(Derivative(f(x), (x, m)), (x, n)) == Derivative(f(x), (x, m + n))
|
| 1196 |
+
assert Derivative(Derivative(f(x), (x, m+5)), (x, n+3)) == Derivative(f(x), (x, m + n + 8))
|
| 1197 |
+
|
| 1198 |
+
assert Derivative(f(x), (x, n)).doit() == Derivative(f(x), (x, n))
|
| 1199 |
+
|
| 1200 |
+
|
| 1201 |
+
def test_order_could_be_zero():
|
| 1202 |
+
x, y = symbols('x, y')
|
| 1203 |
+
n = symbols('n', integer=True, nonnegative=True)
|
| 1204 |
+
m = symbols('m', integer=True, positive=True)
|
| 1205 |
+
assert diff(y, (x, n)) == Piecewise((y, Eq(n, 0)), (0, True))
|
| 1206 |
+
assert diff(y, (x, n + 1)) is S.Zero
|
| 1207 |
+
assert diff(y, (x, m)) is S.Zero
|
| 1208 |
+
|
| 1209 |
+
|
| 1210 |
+
def test_undefined_function_eq():
|
| 1211 |
+
f = Function('f')
|
| 1212 |
+
f2 = Function('f')
|
| 1213 |
+
g = Function('g')
|
| 1214 |
+
f_real = Function('f', is_real=True)
|
| 1215 |
+
|
| 1216 |
+
# This test may only be meaningful if the cache is turned off
|
| 1217 |
+
assert f == f2
|
| 1218 |
+
assert hash(f) == hash(f2)
|
| 1219 |
+
assert f == f
|
| 1220 |
+
|
| 1221 |
+
assert f != g
|
| 1222 |
+
|
| 1223 |
+
assert f != f_real
|
| 1224 |
+
|
| 1225 |
+
|
| 1226 |
+
def test_function_assumptions():
|
| 1227 |
+
x = Symbol('x')
|
| 1228 |
+
f = Function('f')
|
| 1229 |
+
f_real = Function('f', real=True)
|
| 1230 |
+
f_real1 = Function('f', real=1)
|
| 1231 |
+
f_real_inherit = Function(Symbol('f', real=True))
|
| 1232 |
+
|
| 1233 |
+
assert f_real == f_real1 # assumptions are sanitized
|
| 1234 |
+
assert f != f_real
|
| 1235 |
+
assert f(x) != f_real(x)
|
| 1236 |
+
|
| 1237 |
+
assert f(x).is_real is None
|
| 1238 |
+
assert f_real(x).is_real is True
|
| 1239 |
+
assert f_real_inherit(x).is_real is True and f_real_inherit.name == 'f'
|
| 1240 |
+
|
| 1241 |
+
# Can also do it this way, but it won't be equal to f_real because of the
|
| 1242 |
+
# way UndefinedFunction.__new__ works. Any non-recognized assumptions
|
| 1243 |
+
# are just added literally as something which is used in the hash
|
| 1244 |
+
f_real2 = Function('f', is_real=True)
|
| 1245 |
+
assert f_real2(x).is_real is True
|
| 1246 |
+
|
| 1247 |
+
|
| 1248 |
+
def test_undef_fcn_float_issue_6938():
|
| 1249 |
+
f = Function('ceil')
|
| 1250 |
+
assert not f(0.3).is_number
|
| 1251 |
+
f = Function('sin')
|
| 1252 |
+
assert not f(0.3).is_number
|
| 1253 |
+
assert not f(pi).evalf().is_number
|
| 1254 |
+
x = Symbol('x')
|
| 1255 |
+
assert not f(x).evalf(subs={x:1.2}).is_number
|
| 1256 |
+
|
| 1257 |
+
|
| 1258 |
+
def test_undefined_function_eval():
|
| 1259 |
+
# Issue 15170. Make sure UndefinedFunction with eval defined works
|
| 1260 |
+
# properly.
|
| 1261 |
+
|
| 1262 |
+
fdiff = lambda self, argindex=1: cos(self.args[argindex - 1])
|
| 1263 |
+
eval = classmethod(lambda cls, t: None)
|
| 1264 |
+
_imp_ = classmethod(lambda cls, t: sin(t))
|
| 1265 |
+
|
| 1266 |
+
temp = Function('temp', fdiff=fdiff, eval=eval, _imp_=_imp_)
|
| 1267 |
+
|
| 1268 |
+
expr = temp(t)
|
| 1269 |
+
assert sympify(expr) == expr
|
| 1270 |
+
assert type(sympify(expr)).fdiff.__name__ == "<lambda>"
|
| 1271 |
+
assert expr.diff(t) == cos(t)
|
| 1272 |
+
|
| 1273 |
+
|
| 1274 |
+
def test_issue_15241():
|
| 1275 |
+
F = f(x)
|
| 1276 |
+
Fx = F.diff(x)
|
| 1277 |
+
assert (F + x*Fx).diff(x, Fx) == 2
|
| 1278 |
+
assert (F + x*Fx).diff(Fx, x) == 1
|
| 1279 |
+
assert (x*F + x*Fx*F).diff(F, x) == x*Fx.diff(x) + Fx + 1
|
| 1280 |
+
assert (x*F + x*Fx*F).diff(x, F) == x*Fx.diff(x) + Fx + 1
|
| 1281 |
+
y = f(x)
|
| 1282 |
+
G = f(y)
|
| 1283 |
+
Gy = G.diff(y)
|
| 1284 |
+
assert (G + y*Gy).diff(y, Gy) == 2
|
| 1285 |
+
assert (G + y*Gy).diff(Gy, y) == 1
|
| 1286 |
+
assert (y*G + y*Gy*G).diff(G, y) == y*Gy.diff(y) + Gy + 1
|
| 1287 |
+
assert (y*G + y*Gy*G).diff(y, G) == y*Gy.diff(y) + Gy + 1
|
| 1288 |
+
|
| 1289 |
+
|
| 1290 |
+
def test_issue_15226():
|
| 1291 |
+
assert Subs(Derivative(f(y), x, y), y, g(x)).doit() != 0
|
| 1292 |
+
|
| 1293 |
+
|
| 1294 |
+
def test_issue_7027():
|
| 1295 |
+
for wrt in (cos(x), re(x), Derivative(cos(x), x)):
|
| 1296 |
+
raises(ValueError, lambda: diff(f(x), wrt))
|
| 1297 |
+
|
| 1298 |
+
|
| 1299 |
+
def test_derivative_quick_exit():
|
| 1300 |
+
assert f(x).diff(y) == 0
|
| 1301 |
+
assert f(x).diff(y, f(x)) == 0
|
| 1302 |
+
assert f(x).diff(x, f(y)) == 0
|
| 1303 |
+
assert f(f(x)).diff(x, f(x), f(y)) == 0
|
| 1304 |
+
assert f(f(x)).diff(x, f(x), y) == 0
|
| 1305 |
+
assert f(x).diff(g(x)) == 0
|
| 1306 |
+
assert f(x).diff(x, f(x).diff(x)) == 1
|
| 1307 |
+
df = f(x).diff(x)
|
| 1308 |
+
assert f(x).diff(df) == 0
|
| 1309 |
+
dg = g(x).diff(x)
|
| 1310 |
+
assert dg.diff(df).doit() == 0
|
| 1311 |
+
|
| 1312 |
+
|
| 1313 |
+
def test_issue_15084_13166():
|
| 1314 |
+
eq = f(x, g(x))
|
| 1315 |
+
assert eq.diff((g(x), y)) == Derivative(f(x, g(x)), (g(x), y))
|
| 1316 |
+
# issue 13166
|
| 1317 |
+
assert eq.diff(x, 2).doit() == (
|
| 1318 |
+
(Derivative(f(x, g(x)), (g(x), 2))*Derivative(g(x), x) +
|
| 1319 |
+
Subs(Derivative(f(x, _xi_2), _xi_2, x), _xi_2, g(x)))*Derivative(g(x),
|
| 1320 |
+
x) + Derivative(f(x, g(x)), g(x))*Derivative(g(x), (x, 2)) +
|
| 1321 |
+
Derivative(g(x), x)*Subs(Derivative(f(_xi_1, g(x)), _xi_1, g(x)),
|
| 1322 |
+
_xi_1, x) + Subs(Derivative(f(_xi_1, g(x)), (_xi_1, 2)), _xi_1, x))
|
| 1323 |
+
# issue 6681
|
| 1324 |
+
assert diff(f(x, t, g(x, t)), x).doit() == (
|
| 1325 |
+
Derivative(f(x, t, g(x, t)), g(x, t))*Derivative(g(x, t), x) +
|
| 1326 |
+
Subs(Derivative(f(_xi_1, t, g(x, t)), _xi_1), _xi_1, x))
|
| 1327 |
+
# make sure the order doesn't matter when using diff
|
| 1328 |
+
assert eq.diff(x, g(x)) == eq.diff(g(x), x)
|
| 1329 |
+
|
| 1330 |
+
|
| 1331 |
+
def test_negative_counts():
|
| 1332 |
+
# issue 13873
|
| 1333 |
+
raises(ValueError, lambda: sin(x).diff(x, -1))
|
| 1334 |
+
|
| 1335 |
+
|
| 1336 |
+
def test_Derivative__new__():
|
| 1337 |
+
raises(TypeError, lambda: f(x).diff((x, 2), 0))
|
| 1338 |
+
assert f(x, y).diff([(x, y), 0]) == f(x, y)
|
| 1339 |
+
assert f(x, y).diff([(x, y), 1]) == NDimArray([
|
| 1340 |
+
Derivative(f(x, y), x), Derivative(f(x, y), y)])
|
| 1341 |
+
assert f(x,y).diff(y, (x, z), y, x) == Derivative(
|
| 1342 |
+
f(x, y), (x, z + 1), (y, 2))
|
| 1343 |
+
assert Matrix([x]).diff(x, 2) == Matrix([0]) # is_zero exit
|
| 1344 |
+
|
| 1345 |
+
|
| 1346 |
+
def test_issue_14719_10150():
|
| 1347 |
+
class V(Expr):
|
| 1348 |
+
_diff_wrt = True
|
| 1349 |
+
is_scalar = False
|
| 1350 |
+
assert V().diff(V()) == Derivative(V(), V())
|
| 1351 |
+
assert (2*V()).diff(V()) == 2*Derivative(V(), V())
|
| 1352 |
+
class X(Expr):
|
| 1353 |
+
_diff_wrt = True
|
| 1354 |
+
assert X().diff(X()) == 1
|
| 1355 |
+
assert (2*X()).diff(X()) == 2
|
| 1356 |
+
|
| 1357 |
+
|
| 1358 |
+
def test_noncommutative_issue_15131():
|
| 1359 |
+
x = Symbol('x', commutative=False)
|
| 1360 |
+
t = Symbol('t', commutative=False)
|
| 1361 |
+
fx = Function('Fx', commutative=False)(x)
|
| 1362 |
+
ft = Function('Ft', commutative=False)(t)
|
| 1363 |
+
A = Symbol('A', commutative=False)
|
| 1364 |
+
eq = fx * A * ft
|
| 1365 |
+
eqdt = eq.diff(t)
|
| 1366 |
+
assert eqdt.args[-1] == ft.diff(t)
|
| 1367 |
+
|
| 1368 |
+
|
| 1369 |
+
def test_Subs_Derivative():
|
| 1370 |
+
a = Derivative(f(g(x), h(x)), g(x), h(x),x)
|
| 1371 |
+
b = Derivative(Derivative(f(g(x), h(x)), g(x), h(x)),x)
|
| 1372 |
+
c = f(g(x), h(x)).diff(g(x), h(x), x)
|
| 1373 |
+
d = f(g(x), h(x)).diff(g(x), h(x)).diff(x)
|
| 1374 |
+
e = Derivative(f(g(x), h(x)), x)
|
| 1375 |
+
eqs = (a, b, c, d, e)
|
| 1376 |
+
subs = lambda arg: arg.subs(f, Lambda((x, y), exp(x + y))
|
| 1377 |
+
).subs(g(x), 1/x).subs(h(x), x**3)
|
| 1378 |
+
ans = 3*x**2*exp(1/x)*exp(x**3) - exp(1/x)*exp(x**3)/x**2
|
| 1379 |
+
assert all(subs(i).doit().expand() == ans for i in eqs)
|
| 1380 |
+
assert all(subs(i.doit()).doit().expand() == ans for i in eqs)
|
| 1381 |
+
|
| 1382 |
+
def test_issue_15360():
|
| 1383 |
+
f = Function('f')
|
| 1384 |
+
assert f.name == 'f'
|
| 1385 |
+
|
| 1386 |
+
|
| 1387 |
+
def test_issue_15947():
|
| 1388 |
+
assert f._diff_wrt is False
|
| 1389 |
+
raises(TypeError, lambda: f(f))
|
| 1390 |
+
raises(TypeError, lambda: f(x).diff(f))
|
| 1391 |
+
|
| 1392 |
+
|
| 1393 |
+
def test_Derivative_free_symbols():
|
| 1394 |
+
f = Function('f')
|
| 1395 |
+
n = Symbol('n', integer=True, positive=True)
|
| 1396 |
+
assert diff(f(x), (x, n)).free_symbols == {n, x}
|
| 1397 |
+
|
| 1398 |
+
|
| 1399 |
+
def test_issue_20683():
|
| 1400 |
+
x = Symbol('x')
|
| 1401 |
+
y = Symbol('y')
|
| 1402 |
+
z = Symbol('z')
|
| 1403 |
+
y = Derivative(z, x).subs(x,0)
|
| 1404 |
+
assert y.doit() == 0
|
| 1405 |
+
y = Derivative(8, x).subs(x,0)
|
| 1406 |
+
assert y.doit() == 0
|
| 1407 |
+
|
| 1408 |
+
|
| 1409 |
+
def test_issue_10503():
|
| 1410 |
+
f = exp(x**3)*cos(x**6)
|
| 1411 |
+
assert f.series(x, 0, 14) == 1 + x**3 + x**6/2 + x**9/6 - 11*x**12/24 + O(x**14)
|
| 1412 |
+
|
| 1413 |
+
|
| 1414 |
+
def test_issue_17382():
|
| 1415 |
+
# copied from sympy/core/tests/test_evalf.py
|
| 1416 |
+
def NS(e, n=15, **options):
|
| 1417 |
+
return sstr(sympify(e).evalf(n, **options), full_prec=True)
|
| 1418 |
+
|
| 1419 |
+
x = Symbol('x')
|
| 1420 |
+
expr = solveset(2 * cos(x) * cos(2 * x) - 1, x, S.Reals)
|
| 1421 |
+
expected = "Union(" \
|
| 1422 |
+
"ImageSet(Lambda(_n, 6.28318530717959*_n + 5.79812359592087), Integers), " \
|
| 1423 |
+
"ImageSet(Lambda(_n, 6.28318530717959*_n + 0.485061711258717), Integers))"
|
| 1424 |
+
assert NS(expr) == expected
|
| 1425 |
+
|
| 1426 |
+
def test_eval_sympified():
|
| 1427 |
+
# Check both arguments and return types from eval are sympified
|
| 1428 |
+
|
| 1429 |
+
class F(Function):
|
| 1430 |
+
@classmethod
|
| 1431 |
+
def eval(cls, x):
|
| 1432 |
+
assert x is S.One
|
| 1433 |
+
return 1
|
| 1434 |
+
|
| 1435 |
+
assert F(1) is S.One
|
| 1436 |
+
|
| 1437 |
+
# String arguments are not allowed
|
| 1438 |
+
class F2(Function):
|
| 1439 |
+
@classmethod
|
| 1440 |
+
def eval(cls, x):
|
| 1441 |
+
if x == 0:
|
| 1442 |
+
return '1'
|
| 1443 |
+
|
| 1444 |
+
raises(SympifyError, lambda: F2(0))
|
| 1445 |
+
F2(1) # Doesn't raise
|
| 1446 |
+
|
| 1447 |
+
# TODO: Disable string inputs (https://github.com/sympy/sympy/issues/11003)
|
| 1448 |
+
# raises(SympifyError, lambda: F2('2'))
|
| 1449 |
+
|
| 1450 |
+
def test_eval_classmethod_check():
|
| 1451 |
+
with raises(TypeError):
|
| 1452 |
+
class F(Function):
|
| 1453 |
+
def eval(self, x):
|
| 1454 |
+
pass
|
| 1455 |
+
|
| 1456 |
+
|
| 1457 |
+
def test_issue_27163():
|
| 1458 |
+
# https://github.com/sympy/sympy/issues/27163
|
| 1459 |
+
raises(TypeError, lambda: Derivative(f, t))
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_logic.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.logic import (fuzzy_not, Logic, And, Or, Not, fuzzy_and,
|
| 2 |
+
fuzzy_or, _fuzzy_group, _torf, fuzzy_nand, fuzzy_xor)
|
| 3 |
+
from sympy.testing.pytest import raises
|
| 4 |
+
|
| 5 |
+
from itertools import product
|
| 6 |
+
|
| 7 |
+
T = True
|
| 8 |
+
F = False
|
| 9 |
+
U = None
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def test_torf():
|
| 14 |
+
v = [T, F, U]
|
| 15 |
+
for i in product(*[v]*3):
|
| 16 |
+
assert _torf(i) is (True if all(j for j in i) else
|
| 17 |
+
(False if all(j is False for j in i) else None))
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def test_fuzzy_group():
|
| 21 |
+
v = [T, F, U]
|
| 22 |
+
for i in product(*[v]*3):
|
| 23 |
+
assert _fuzzy_group(i) is (None if None in i else
|
| 24 |
+
(True if all(j for j in i) else False))
|
| 25 |
+
assert _fuzzy_group(i, quick_exit=True) is \
|
| 26 |
+
(None if (i.count(False) > 1) else
|
| 27 |
+
(None if None in i else (True if all(j for j in i) else False)))
|
| 28 |
+
it = (True if (i == 0) else None for i in range(2))
|
| 29 |
+
assert _torf(it) is None
|
| 30 |
+
it = (True if (i == 1) else None for i in range(2))
|
| 31 |
+
assert _torf(it) is None
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def test_fuzzy_not():
|
| 35 |
+
assert fuzzy_not(T) == F
|
| 36 |
+
assert fuzzy_not(F) == T
|
| 37 |
+
assert fuzzy_not(U) == U
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def test_fuzzy_and():
|
| 41 |
+
assert fuzzy_and([T, T]) == T
|
| 42 |
+
assert fuzzy_and([T, F]) == F
|
| 43 |
+
assert fuzzy_and([T, U]) == U
|
| 44 |
+
assert fuzzy_and([F, F]) == F
|
| 45 |
+
assert fuzzy_and([F, U]) == F
|
| 46 |
+
assert fuzzy_and([U, U]) == U
|
| 47 |
+
assert [fuzzy_and([w]) for w in [U, T, F]] == [U, T, F]
|
| 48 |
+
assert fuzzy_and([T, F, U]) == F
|
| 49 |
+
assert fuzzy_and([]) == T
|
| 50 |
+
raises(TypeError, lambda: fuzzy_and())
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def test_fuzzy_or():
|
| 54 |
+
assert fuzzy_or([T, T]) == T
|
| 55 |
+
assert fuzzy_or([T, F]) == T
|
| 56 |
+
assert fuzzy_or([T, U]) == T
|
| 57 |
+
assert fuzzy_or([F, F]) == F
|
| 58 |
+
assert fuzzy_or([F, U]) == U
|
| 59 |
+
assert fuzzy_or([U, U]) == U
|
| 60 |
+
assert [fuzzy_or([w]) for w in [U, T, F]] == [U, T, F]
|
| 61 |
+
assert fuzzy_or([T, F, U]) == T
|
| 62 |
+
assert fuzzy_or([]) == F
|
| 63 |
+
raises(TypeError, lambda: fuzzy_or())
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def test_logic_cmp():
|
| 67 |
+
l1 = And('a', Not('b'))
|
| 68 |
+
l2 = And('a', Not('b'))
|
| 69 |
+
|
| 70 |
+
assert hash(l1) == hash(l2)
|
| 71 |
+
assert (l1 == l2) == T
|
| 72 |
+
assert (l1 != l2) == F
|
| 73 |
+
|
| 74 |
+
assert And('a', 'b', 'c') == And('b', 'a', 'c')
|
| 75 |
+
assert And('a', 'b', 'c') == And('c', 'b', 'a')
|
| 76 |
+
assert And('a', 'b', 'c') == And('c', 'a', 'b')
|
| 77 |
+
|
| 78 |
+
assert Not('a') < Not('b')
|
| 79 |
+
assert (Not('b') < Not('a')) is False
|
| 80 |
+
assert (Not('a') < 2) is False
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def test_logic_onearg():
|
| 84 |
+
assert And() is True
|
| 85 |
+
assert Or() is False
|
| 86 |
+
|
| 87 |
+
assert And(T) == T
|
| 88 |
+
assert And(F) == F
|
| 89 |
+
assert Or(T) == T
|
| 90 |
+
assert Or(F) == F
|
| 91 |
+
|
| 92 |
+
assert And('a') == 'a'
|
| 93 |
+
assert Or('a') == 'a'
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def test_logic_xnotx():
|
| 97 |
+
assert And('a', Not('a')) == F
|
| 98 |
+
assert Or('a', Not('a')) == T
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def test_logic_eval_TF():
|
| 102 |
+
assert And(F, F) == F
|
| 103 |
+
assert And(F, T) == F
|
| 104 |
+
assert And(T, F) == F
|
| 105 |
+
assert And(T, T) == T
|
| 106 |
+
|
| 107 |
+
assert Or(F, F) == F
|
| 108 |
+
assert Or(F, T) == T
|
| 109 |
+
assert Or(T, F) == T
|
| 110 |
+
assert Or(T, T) == T
|
| 111 |
+
|
| 112 |
+
assert And('a', T) == 'a'
|
| 113 |
+
assert And('a', F) == F
|
| 114 |
+
assert Or('a', T) == T
|
| 115 |
+
assert Or('a', F) == 'a'
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def test_logic_combine_args():
|
| 119 |
+
assert And('a', 'b', 'a') == And('a', 'b')
|
| 120 |
+
assert Or('a', 'b', 'a') == Or('a', 'b')
|
| 121 |
+
|
| 122 |
+
assert And(And('a', 'b'), And('c', 'd')) == And('a', 'b', 'c', 'd')
|
| 123 |
+
assert Or(Or('a', 'b'), Or('c', 'd')) == Or('a', 'b', 'c', 'd')
|
| 124 |
+
|
| 125 |
+
assert Or('t', And('n', 'p', 'r'), And('n', 'r'), And('n', 'p', 'r'), 't',
|
| 126 |
+
And('n', 'r')) == Or('t', And('n', 'p', 'r'), And('n', 'r'))
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
def test_logic_expand():
|
| 130 |
+
t = And(Or('a', 'b'), 'c')
|
| 131 |
+
assert t.expand() == Or(And('a', 'c'), And('b', 'c'))
|
| 132 |
+
|
| 133 |
+
t = And(Or('a', Not('b')), 'b')
|
| 134 |
+
assert t.expand() == And('a', 'b')
|
| 135 |
+
|
| 136 |
+
t = And(Or('a', 'b'), Or('c', 'd'))
|
| 137 |
+
assert t.expand() == \
|
| 138 |
+
Or(And('a', 'c'), And('a', 'd'), And('b', 'c'), And('b', 'd'))
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def test_logic_fromstring():
|
| 142 |
+
S = Logic.fromstring
|
| 143 |
+
|
| 144 |
+
assert S('a') == 'a'
|
| 145 |
+
assert S('!a') == Not('a')
|
| 146 |
+
assert S('a & b') == And('a', 'b')
|
| 147 |
+
assert S('a | b') == Or('a', 'b')
|
| 148 |
+
assert S('a | b & c') == And(Or('a', 'b'), 'c')
|
| 149 |
+
assert S('a & b | c') == Or(And('a', 'b'), 'c')
|
| 150 |
+
assert S('a & b & c') == And('a', 'b', 'c')
|
| 151 |
+
assert S('a | b | c') == Or('a', 'b', 'c')
|
| 152 |
+
|
| 153 |
+
raises(ValueError, lambda: S('| a'))
|
| 154 |
+
raises(ValueError, lambda: S('& a'))
|
| 155 |
+
raises(ValueError, lambda: S('a | | b'))
|
| 156 |
+
raises(ValueError, lambda: S('a | & b'))
|
| 157 |
+
raises(ValueError, lambda: S('a & & b'))
|
| 158 |
+
raises(ValueError, lambda: S('a |'))
|
| 159 |
+
raises(ValueError, lambda: S('a|b'))
|
| 160 |
+
raises(ValueError, lambda: S('!'))
|
| 161 |
+
raises(ValueError, lambda: S('! a'))
|
| 162 |
+
raises(ValueError, lambda: S('!(a + 1)'))
|
| 163 |
+
raises(ValueError, lambda: S(''))
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
def test_logic_not():
|
| 167 |
+
assert Not('a') != '!a'
|
| 168 |
+
assert Not('!a') != 'a'
|
| 169 |
+
assert Not(True) == False
|
| 170 |
+
assert Not(False) == True
|
| 171 |
+
|
| 172 |
+
# NOTE: we may want to change default Not behaviour and put this
|
| 173 |
+
# functionality into some method.
|
| 174 |
+
assert Not(And('a', 'b')) == Or(Not('a'), Not('b'))
|
| 175 |
+
assert Not(Or('a', 'b')) == And(Not('a'), Not('b'))
|
| 176 |
+
|
| 177 |
+
raises(ValueError, lambda: Not(1))
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
def test_formatting():
|
| 181 |
+
S = Logic.fromstring
|
| 182 |
+
raises(ValueError, lambda: S('a&b'))
|
| 183 |
+
raises(ValueError, lambda: S('a|b'))
|
| 184 |
+
raises(ValueError, lambda: S('! a'))
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
def test_fuzzy_xor():
|
| 188 |
+
assert fuzzy_xor((None,)) is None
|
| 189 |
+
assert fuzzy_xor((None, True)) is None
|
| 190 |
+
assert fuzzy_xor((None, False)) is None
|
| 191 |
+
assert fuzzy_xor((True, False)) is True
|
| 192 |
+
assert fuzzy_xor((True, True)) is False
|
| 193 |
+
assert fuzzy_xor((True, True, False)) is False
|
| 194 |
+
assert fuzzy_xor((True, True, False, True)) is True
|
| 195 |
+
|
| 196 |
+
def test_fuzzy_nand():
|
| 197 |
+
for args in [(1, 0), (1, 1), (0, 0)]:
|
| 198 |
+
assert fuzzy_nand(args) == fuzzy_not(fuzzy_and(args))
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_match.py
ADDED
|
@@ -0,0 +1,766 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy import abc
|
| 2 |
+
from sympy.concrete.summations import Sum
|
| 3 |
+
from sympy.core.add import Add
|
| 4 |
+
from sympy.core.function import (Derivative, Function, diff)
|
| 5 |
+
from sympy.core.mul import Mul
|
| 6 |
+
from sympy.core.numbers import (Float, I, Integer, Rational, oo, pi)
|
| 7 |
+
from sympy.core.singleton import S
|
| 8 |
+
from sympy.core.symbol import (Symbol, Wild, symbols)
|
| 9 |
+
from sympy.functions.elementary.exponential import (exp, log)
|
| 10 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 11 |
+
from sympy.functions.elementary.trigonometric import (cos, sin)
|
| 12 |
+
from sympy.functions.special.hyper import meijerg
|
| 13 |
+
from sympy.polys.polytools import Poly
|
| 14 |
+
from sympy.simplify.radsimp import collect
|
| 15 |
+
from sympy.simplify.simplify import signsimp
|
| 16 |
+
|
| 17 |
+
from sympy.testing.pytest import XFAIL
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def test_symbol():
|
| 21 |
+
x = Symbol('x')
|
| 22 |
+
a, b, c, p, q = map(Wild, 'abcpq')
|
| 23 |
+
|
| 24 |
+
e = x
|
| 25 |
+
assert e.match(x) == {}
|
| 26 |
+
assert e.matches(x) == {}
|
| 27 |
+
assert e.match(a) == {a: x}
|
| 28 |
+
|
| 29 |
+
e = Rational(5)
|
| 30 |
+
assert e.match(c) == {c: 5}
|
| 31 |
+
assert e.match(e) == {}
|
| 32 |
+
assert e.match(e + 1) is None
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def test_add():
|
| 36 |
+
x, y, a, b, c = map(Symbol, 'xyabc')
|
| 37 |
+
p, q, r = map(Wild, 'pqr')
|
| 38 |
+
|
| 39 |
+
e = a + b
|
| 40 |
+
assert e.match(p + b) == {p: a}
|
| 41 |
+
assert e.match(p + a) == {p: b}
|
| 42 |
+
|
| 43 |
+
e = 1 + b
|
| 44 |
+
assert e.match(p + b) == {p: 1}
|
| 45 |
+
|
| 46 |
+
e = a + b + c
|
| 47 |
+
assert e.match(a + p + c) == {p: b}
|
| 48 |
+
assert e.match(b + p + c) == {p: a}
|
| 49 |
+
|
| 50 |
+
e = a + b + c + x
|
| 51 |
+
assert e.match(a + p + x + c) == {p: b}
|
| 52 |
+
assert e.match(b + p + c + x) == {p: a}
|
| 53 |
+
assert e.match(b) is None
|
| 54 |
+
assert e.match(b + p) == {p: a + c + x}
|
| 55 |
+
assert e.match(a + p + c) == {p: b + x}
|
| 56 |
+
assert e.match(b + p + c) == {p: a + x}
|
| 57 |
+
|
| 58 |
+
e = 4*x + 5
|
| 59 |
+
assert e.match(4*x + p) == {p: 5}
|
| 60 |
+
assert e.match(3*x + p) == {p: x + 5}
|
| 61 |
+
assert e.match(p*x + 5) == {p: 4}
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
def test_power():
|
| 65 |
+
x, y, a, b, c = map(Symbol, 'xyabc')
|
| 66 |
+
p, q, r = map(Wild, 'pqr')
|
| 67 |
+
|
| 68 |
+
e = (x + y)**a
|
| 69 |
+
assert e.match(p**q) == {p: x + y, q: a}
|
| 70 |
+
assert e.match(p**p) is None
|
| 71 |
+
|
| 72 |
+
e = (x + y)**(x + y)
|
| 73 |
+
assert e.match(p**p) == {p: x + y}
|
| 74 |
+
assert e.match(p**q) == {p: x + y, q: x + y}
|
| 75 |
+
|
| 76 |
+
e = (2*x)**2
|
| 77 |
+
assert e.match(p*q**r) == {p: 4, q: x, r: 2}
|
| 78 |
+
|
| 79 |
+
e = Integer(1)
|
| 80 |
+
assert e.match(x**p) == {p: 0}
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def test_match_exclude():
|
| 84 |
+
x = Symbol('x')
|
| 85 |
+
y = Symbol('y')
|
| 86 |
+
p = Wild("p")
|
| 87 |
+
q = Wild("q")
|
| 88 |
+
r = Wild("r")
|
| 89 |
+
|
| 90 |
+
e = Rational(6)
|
| 91 |
+
assert e.match(2*p) == {p: 3}
|
| 92 |
+
|
| 93 |
+
e = 3/(4*x + 5)
|
| 94 |
+
assert e.match(3/(p*x + q)) == {p: 4, q: 5}
|
| 95 |
+
|
| 96 |
+
e = 3/(4*x + 5)
|
| 97 |
+
assert e.match(p/(q*x + r)) == {p: 3, q: 4, r: 5}
|
| 98 |
+
|
| 99 |
+
e = 2/(x + 1)
|
| 100 |
+
assert e.match(p/(q*x + r)) == {p: 2, q: 1, r: 1}
|
| 101 |
+
|
| 102 |
+
e = 1/(x + 1)
|
| 103 |
+
assert e.match(p/(q*x + r)) == {p: 1, q: 1, r: 1}
|
| 104 |
+
|
| 105 |
+
e = 4*x + 5
|
| 106 |
+
assert e.match(p*x + q) == {p: 4, q: 5}
|
| 107 |
+
|
| 108 |
+
e = 4*x + 5*y + 6
|
| 109 |
+
assert e.match(p*x + q*y + r) == {p: 4, q: 5, r: 6}
|
| 110 |
+
|
| 111 |
+
a = Wild('a', exclude=[x])
|
| 112 |
+
|
| 113 |
+
e = 3*x
|
| 114 |
+
assert e.match(p*x) == {p: 3}
|
| 115 |
+
assert e.match(a*x) == {a: 3}
|
| 116 |
+
|
| 117 |
+
e = 3*x**2
|
| 118 |
+
assert e.match(p*x) == {p: 3*x}
|
| 119 |
+
assert e.match(a*x) is None
|
| 120 |
+
|
| 121 |
+
e = 3*x + 3 + 6/x
|
| 122 |
+
assert e.match(p*x**2 + p*x + 2*p) == {p: 3/x}
|
| 123 |
+
assert e.match(a*x**2 + a*x + 2*a) is None
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
def test_mul():
|
| 127 |
+
x, y, a, b, c = map(Symbol, 'xyabc')
|
| 128 |
+
p, q = map(Wild, 'pq')
|
| 129 |
+
|
| 130 |
+
e = 4*x
|
| 131 |
+
assert e.match(p*x) == {p: 4}
|
| 132 |
+
assert e.match(p*y) is None
|
| 133 |
+
assert e.match(e + p*y) == {p: 0}
|
| 134 |
+
|
| 135 |
+
e = a*x*b*c
|
| 136 |
+
assert e.match(p*x) == {p: a*b*c}
|
| 137 |
+
assert e.match(c*p*x) == {p: a*b}
|
| 138 |
+
|
| 139 |
+
e = (a + b)*(a + c)
|
| 140 |
+
assert e.match((p + b)*(p + c)) == {p: a}
|
| 141 |
+
|
| 142 |
+
e = x
|
| 143 |
+
assert e.match(p*x) == {p: 1}
|
| 144 |
+
|
| 145 |
+
e = exp(x)
|
| 146 |
+
assert e.match(x**p*exp(x*q)) == {p: 0, q: 1}
|
| 147 |
+
|
| 148 |
+
e = I*Poly(x, x)
|
| 149 |
+
assert e.match(I*p) == {p: x}
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
def test_mul_noncommutative():
|
| 153 |
+
x, y = symbols('x y')
|
| 154 |
+
A, B, C = symbols('A B C', commutative=False)
|
| 155 |
+
u, v = symbols('u v', cls=Wild)
|
| 156 |
+
w, z = symbols('w z', cls=Wild, commutative=False)
|
| 157 |
+
|
| 158 |
+
assert (u*v).matches(x) in ({v: x, u: 1}, {u: x, v: 1})
|
| 159 |
+
assert (u*v).matches(x*y) in ({v: y, u: x}, {u: y, v: x})
|
| 160 |
+
assert (u*v).matches(A) is None
|
| 161 |
+
assert (u*v).matches(A*B) is None
|
| 162 |
+
assert (u*v).matches(x*A) is None
|
| 163 |
+
assert (u*v).matches(x*y*A) is None
|
| 164 |
+
assert (u*v).matches(x*A*B) is None
|
| 165 |
+
assert (u*v).matches(x*y*A*B) is None
|
| 166 |
+
|
| 167 |
+
assert (v*w).matches(x) is None
|
| 168 |
+
assert (v*w).matches(x*y) is None
|
| 169 |
+
assert (v*w).matches(A) == {w: A, v: 1}
|
| 170 |
+
assert (v*w).matches(A*B) == {w: A*B, v: 1}
|
| 171 |
+
assert (v*w).matches(x*A) == {w: A, v: x}
|
| 172 |
+
assert (v*w).matches(x*y*A) == {w: A, v: x*y}
|
| 173 |
+
assert (v*w).matches(x*A*B) == {w: A*B, v: x}
|
| 174 |
+
assert (v*w).matches(x*y*A*B) == {w: A*B, v: x*y}
|
| 175 |
+
|
| 176 |
+
assert (v*w).matches(-x) is None
|
| 177 |
+
assert (v*w).matches(-x*y) is None
|
| 178 |
+
assert (v*w).matches(-A) == {w: A, v: -1}
|
| 179 |
+
assert (v*w).matches(-A*B) == {w: A*B, v: -1}
|
| 180 |
+
assert (v*w).matches(-x*A) == {w: A, v: -x}
|
| 181 |
+
assert (v*w).matches(-x*y*A) == {w: A, v: -x*y}
|
| 182 |
+
assert (v*w).matches(-x*A*B) == {w: A*B, v: -x}
|
| 183 |
+
assert (v*w).matches(-x*y*A*B) == {w: A*B, v: -x*y}
|
| 184 |
+
|
| 185 |
+
assert (w*z).matches(x) is None
|
| 186 |
+
assert (w*z).matches(x*y) is None
|
| 187 |
+
assert (w*z).matches(A) is None
|
| 188 |
+
assert (w*z).matches(A*B) == {w: A, z: B}
|
| 189 |
+
assert (w*z).matches(B*A) == {w: B, z: A}
|
| 190 |
+
assert (w*z).matches(A*B*C) in [{w: A, z: B*C}, {w: A*B, z: C}]
|
| 191 |
+
assert (w*z).matches(x*A) is None
|
| 192 |
+
assert (w*z).matches(x*y*A) is None
|
| 193 |
+
assert (w*z).matches(x*A*B) is None
|
| 194 |
+
assert (w*z).matches(x*y*A*B) is None
|
| 195 |
+
|
| 196 |
+
assert (w*A).matches(A) is None
|
| 197 |
+
assert (A*w*B).matches(A*B) is None
|
| 198 |
+
|
| 199 |
+
assert (u*w*z).matches(x) is None
|
| 200 |
+
assert (u*w*z).matches(x*y) is None
|
| 201 |
+
assert (u*w*z).matches(A) is None
|
| 202 |
+
assert (u*w*z).matches(A*B) == {u: 1, w: A, z: B}
|
| 203 |
+
assert (u*w*z).matches(B*A) == {u: 1, w: B, z: A}
|
| 204 |
+
assert (u*w*z).matches(x*A) is None
|
| 205 |
+
assert (u*w*z).matches(x*y*A) is None
|
| 206 |
+
assert (u*w*z).matches(x*A*B) == {u: x, w: A, z: B}
|
| 207 |
+
assert (u*w*z).matches(x*B*A) == {u: x, w: B, z: A}
|
| 208 |
+
assert (u*w*z).matches(x*y*A*B) == {u: x*y, w: A, z: B}
|
| 209 |
+
assert (u*w*z).matches(x*y*B*A) == {u: x*y, w: B, z: A}
|
| 210 |
+
|
| 211 |
+
assert (u*A).matches(x*A) == {u: x}
|
| 212 |
+
assert (u*A).matches(x*A*B) is None
|
| 213 |
+
assert (u*B).matches(x*A) is None
|
| 214 |
+
assert (u*A*B).matches(x*A*B) == {u: x}
|
| 215 |
+
assert (u*A*B).matches(x*B*A) is None
|
| 216 |
+
assert (u*A*B).matches(x*A) is None
|
| 217 |
+
|
| 218 |
+
assert (u*w*A).matches(x*A*B) is None
|
| 219 |
+
assert (u*w*B).matches(x*A*B) == {u: x, w: A}
|
| 220 |
+
|
| 221 |
+
assert (u*v*A*B).matches(x*A*B) in [{u: x, v: 1}, {v: x, u: 1}]
|
| 222 |
+
assert (u*v*A*B).matches(x*B*A) is None
|
| 223 |
+
assert (u*v*A*B).matches(u*v*A*C) is None
|
| 224 |
+
|
| 225 |
+
|
| 226 |
+
def test_mul_noncommutative_mismatch():
|
| 227 |
+
A, B, C = symbols('A B C', commutative=False)
|
| 228 |
+
w = symbols('w', cls=Wild, commutative=False)
|
| 229 |
+
|
| 230 |
+
assert (w*B*w).matches(A*B*A) == {w: A}
|
| 231 |
+
assert (w*B*w).matches(A*C*B*A*C) == {w: A*C}
|
| 232 |
+
assert (w*B*w).matches(A*C*B*A*B) is None
|
| 233 |
+
assert (w*B*w).matches(A*B*C) is None
|
| 234 |
+
assert (w*w*C).matches(A*B*C) is None
|
| 235 |
+
|
| 236 |
+
|
| 237 |
+
def test_mul_noncommutative_pow():
|
| 238 |
+
A, B, C = symbols('A B C', commutative=False)
|
| 239 |
+
w = symbols('w', cls=Wild, commutative=False)
|
| 240 |
+
|
| 241 |
+
assert (A*B*w).matches(A*B**2) == {w: B}
|
| 242 |
+
assert (A*(B**2)*w*(B**3)).matches(A*B**8) == {w: B**3}
|
| 243 |
+
assert (A*B*w*C).matches(A*(B**4)*C) == {w: B**3}
|
| 244 |
+
|
| 245 |
+
assert (A*B*(w**(-1))).matches(A*B*(C**(-1))) == {w: C}
|
| 246 |
+
assert (A*(B*w)**(-1)*C).matches(A*(B*C)**(-1)*C) == {w: C}
|
| 247 |
+
|
| 248 |
+
assert ((w**2)*B*C).matches((A**2)*B*C) == {w: A}
|
| 249 |
+
assert ((w**2)*B*(w**3)).matches((A**2)*B*(A**3)) == {w: A}
|
| 250 |
+
assert ((w**2)*B*(w**4)).matches((A**2)*B*(A**2)) is None
|
| 251 |
+
|
| 252 |
+
def test_complex():
|
| 253 |
+
a, b, c = map(Symbol, 'abc')
|
| 254 |
+
x, y = map(Wild, 'xy')
|
| 255 |
+
|
| 256 |
+
assert (1 + I).match(x + I) == {x: 1}
|
| 257 |
+
assert (a + I).match(x + I) == {x: a}
|
| 258 |
+
assert (2*I).match(x*I) == {x: 2}
|
| 259 |
+
assert (a*I).match(x*I) == {x: a}
|
| 260 |
+
assert (a*I).match(x*y) == {x: I, y: a}
|
| 261 |
+
assert (2*I).match(x*y) == {x: 2, y: I}
|
| 262 |
+
assert (a + b*I).match(x + y*I) == {x: a, y: b}
|
| 263 |
+
|
| 264 |
+
|
| 265 |
+
def test_functions():
|
| 266 |
+
from sympy.core.function import WildFunction
|
| 267 |
+
x = Symbol('x')
|
| 268 |
+
g = WildFunction('g')
|
| 269 |
+
p = Wild('p')
|
| 270 |
+
q = Wild('q')
|
| 271 |
+
|
| 272 |
+
f = cos(5*x)
|
| 273 |
+
notf = x
|
| 274 |
+
assert f.match(p*cos(q*x)) == {p: 1, q: 5}
|
| 275 |
+
assert f.match(p*g) == {p: 1, g: cos(5*x)}
|
| 276 |
+
assert notf.match(g) is None
|
| 277 |
+
|
| 278 |
+
|
| 279 |
+
@XFAIL
|
| 280 |
+
def test_functions_X1():
|
| 281 |
+
from sympy.core.function import WildFunction
|
| 282 |
+
x = Symbol('x')
|
| 283 |
+
g = WildFunction('g')
|
| 284 |
+
p = Wild('p')
|
| 285 |
+
q = Wild('q')
|
| 286 |
+
|
| 287 |
+
f = cos(5*x)
|
| 288 |
+
assert f.match(p*g(q*x)) == {p: 1, g: cos, q: 5}
|
| 289 |
+
|
| 290 |
+
|
| 291 |
+
def test_interface():
|
| 292 |
+
x, y = map(Symbol, 'xy')
|
| 293 |
+
p, q = map(Wild, 'pq')
|
| 294 |
+
|
| 295 |
+
assert (x + 1).match(p + 1) == {p: x}
|
| 296 |
+
assert (x*3).match(p*3) == {p: x}
|
| 297 |
+
assert (x**3).match(p**3) == {p: x}
|
| 298 |
+
assert (x*cos(y)).match(p*cos(q)) == {p: x, q: y}
|
| 299 |
+
|
| 300 |
+
assert (x*y).match(p*q) in [{p:x, q:y}, {p:y, q:x}]
|
| 301 |
+
assert (x + y).match(p + q) in [{p:x, q:y}, {p:y, q:x}]
|
| 302 |
+
assert (x*y + 1).match(p*q) in [{p:1, q:1 + x*y}, {p:1 + x*y, q:1}]
|
| 303 |
+
|
| 304 |
+
|
| 305 |
+
def test_derivative1():
|
| 306 |
+
x, y = map(Symbol, 'xy')
|
| 307 |
+
p, q = map(Wild, 'pq')
|
| 308 |
+
|
| 309 |
+
f = Function('f', nargs=1)
|
| 310 |
+
fd = Derivative(f(x), x)
|
| 311 |
+
|
| 312 |
+
assert fd.match(p) == {p: fd}
|
| 313 |
+
assert (fd + 1).match(p + 1) == {p: fd}
|
| 314 |
+
assert (fd).match(fd) == {}
|
| 315 |
+
assert (3*fd).match(p*fd) is not None
|
| 316 |
+
assert (3*fd - 1).match(p*fd + q) == {p: 3, q: -1}
|
| 317 |
+
|
| 318 |
+
|
| 319 |
+
def test_derivative_bug1():
|
| 320 |
+
f = Function("f")
|
| 321 |
+
x = Symbol("x")
|
| 322 |
+
a = Wild("a", exclude=[f, x])
|
| 323 |
+
b = Wild("b", exclude=[f])
|
| 324 |
+
pattern = a * Derivative(f(x), x, x) + b
|
| 325 |
+
expr = Derivative(f(x), x) + x**2
|
| 326 |
+
d1 = {b: x**2}
|
| 327 |
+
d2 = pattern.xreplace(d1).matches(expr, d1)
|
| 328 |
+
assert d2 is None
|
| 329 |
+
|
| 330 |
+
|
| 331 |
+
def test_derivative2():
|
| 332 |
+
f = Function("f")
|
| 333 |
+
x = Symbol("x")
|
| 334 |
+
a = Wild("a", exclude=[f, x])
|
| 335 |
+
b = Wild("b", exclude=[f])
|
| 336 |
+
e = Derivative(f(x), x)
|
| 337 |
+
assert e.match(Derivative(f(x), x)) == {}
|
| 338 |
+
assert e.match(Derivative(f(x), x, x)) is None
|
| 339 |
+
e = Derivative(f(x), x, x)
|
| 340 |
+
assert e.match(Derivative(f(x), x)) is None
|
| 341 |
+
assert e.match(Derivative(f(x), x, x)) == {}
|
| 342 |
+
e = Derivative(f(x), x) + x**2
|
| 343 |
+
assert e.match(a*Derivative(f(x), x) + b) == {a: 1, b: x**2}
|
| 344 |
+
assert e.match(a*Derivative(f(x), x, x) + b) is None
|
| 345 |
+
e = Derivative(f(x), x, x) + x**2
|
| 346 |
+
assert e.match(a*Derivative(f(x), x) + b) is None
|
| 347 |
+
assert e.match(a*Derivative(f(x), x, x) + b) == {a: 1, b: x**2}
|
| 348 |
+
|
| 349 |
+
|
| 350 |
+
def test_match_deriv_bug1():
|
| 351 |
+
n = Function('n')
|
| 352 |
+
l = Function('l')
|
| 353 |
+
|
| 354 |
+
x = Symbol('x')
|
| 355 |
+
p = Wild('p')
|
| 356 |
+
|
| 357 |
+
e = diff(l(x), x)/x - diff(diff(n(x), x), x)/2 - \
|
| 358 |
+
diff(n(x), x)**2/4 + diff(n(x), x)*diff(l(x), x)/4
|
| 359 |
+
e = e.subs(n(x), -l(x)).doit()
|
| 360 |
+
t = x*exp(-l(x))
|
| 361 |
+
t2 = t.diff(x, x)/t
|
| 362 |
+
assert e.match( (p*t2).expand() ) == {p: Rational(-1, 2)}
|
| 363 |
+
|
| 364 |
+
|
| 365 |
+
def test_match_bug2():
|
| 366 |
+
x, y = map(Symbol, 'xy')
|
| 367 |
+
p, q, r = map(Wild, 'pqr')
|
| 368 |
+
res = (x + y).match(p + q + r)
|
| 369 |
+
assert (p + q + r).subs(res) == x + y
|
| 370 |
+
|
| 371 |
+
|
| 372 |
+
def test_match_bug3():
|
| 373 |
+
x, a, b = map(Symbol, 'xab')
|
| 374 |
+
p = Wild('p')
|
| 375 |
+
assert (b*x*exp(a*x)).match(x*exp(p*x)) is None
|
| 376 |
+
|
| 377 |
+
|
| 378 |
+
def test_match_bug4():
|
| 379 |
+
x = Symbol('x')
|
| 380 |
+
p = Wild('p')
|
| 381 |
+
e = x
|
| 382 |
+
assert e.match(-p*x) == {p: -1}
|
| 383 |
+
|
| 384 |
+
|
| 385 |
+
def test_match_bug5():
|
| 386 |
+
x = Symbol('x')
|
| 387 |
+
p = Wild('p')
|
| 388 |
+
e = -x
|
| 389 |
+
assert e.match(-p*x) == {p: 1}
|
| 390 |
+
|
| 391 |
+
|
| 392 |
+
def test_match_bug6():
|
| 393 |
+
x = Symbol('x')
|
| 394 |
+
p = Wild('p')
|
| 395 |
+
e = x
|
| 396 |
+
assert e.match(3*p*x) == {p: Rational(1)/3}
|
| 397 |
+
|
| 398 |
+
|
| 399 |
+
def test_match_polynomial():
|
| 400 |
+
x = Symbol('x')
|
| 401 |
+
a = Wild('a', exclude=[x])
|
| 402 |
+
b = Wild('b', exclude=[x])
|
| 403 |
+
c = Wild('c', exclude=[x])
|
| 404 |
+
d = Wild('d', exclude=[x])
|
| 405 |
+
|
| 406 |
+
eq = 4*x**3 + 3*x**2 + 2*x + 1
|
| 407 |
+
pattern = a*x**3 + b*x**2 + c*x + d
|
| 408 |
+
assert eq.match(pattern) == {a: 4, b: 3, c: 2, d: 1}
|
| 409 |
+
assert (eq - 3*x**2).match(pattern) == {a: 4, b: 0, c: 2, d: 1}
|
| 410 |
+
assert (x + sqrt(2) + 3).match(a + b*x + c*x**2) == \
|
| 411 |
+
{b: 1, a: sqrt(2) + 3, c: 0}
|
| 412 |
+
|
| 413 |
+
|
| 414 |
+
def test_exclude():
|
| 415 |
+
x, y, a = map(Symbol, 'xya')
|
| 416 |
+
p = Wild('p', exclude=[1, x])
|
| 417 |
+
q = Wild('q')
|
| 418 |
+
r = Wild('r', exclude=[sin, y])
|
| 419 |
+
|
| 420 |
+
assert sin(x).match(r) is None
|
| 421 |
+
assert cos(y).match(r) is None
|
| 422 |
+
|
| 423 |
+
e = 3*x**2 + y*x + a
|
| 424 |
+
assert e.match(p*x**2 + q*x + r) == {p: 3, q: y, r: a}
|
| 425 |
+
|
| 426 |
+
e = x + 1
|
| 427 |
+
assert e.match(x + p) is None
|
| 428 |
+
assert e.match(p + 1) is None
|
| 429 |
+
assert e.match(x + 1 + p) == {p: 0}
|
| 430 |
+
|
| 431 |
+
e = cos(x) + 5*sin(y)
|
| 432 |
+
assert e.match(r) is None
|
| 433 |
+
assert e.match(cos(y) + r) is None
|
| 434 |
+
assert e.match(r + p*sin(q)) == {r: cos(x), p: 5, q: y}
|
| 435 |
+
|
| 436 |
+
|
| 437 |
+
def test_floats():
|
| 438 |
+
a, b = map(Wild, 'ab')
|
| 439 |
+
|
| 440 |
+
e = cos(0.12345, evaluate=False)**2
|
| 441 |
+
r = e.match(a*cos(b)**2)
|
| 442 |
+
assert r == {a: 1, b: Float(0.12345)}
|
| 443 |
+
|
| 444 |
+
|
| 445 |
+
def test_Derivative_bug1():
|
| 446 |
+
f = Function("f")
|
| 447 |
+
x = abc.x
|
| 448 |
+
a = Wild("a", exclude=[f(x)])
|
| 449 |
+
b = Wild("b", exclude=[f(x)])
|
| 450 |
+
eq = f(x).diff(x)
|
| 451 |
+
assert eq.match(a*Derivative(f(x), x) + b) == {a: 1, b: 0}
|
| 452 |
+
|
| 453 |
+
|
| 454 |
+
def test_match_wild_wild():
|
| 455 |
+
p = Wild('p')
|
| 456 |
+
q = Wild('q')
|
| 457 |
+
r = Wild('r')
|
| 458 |
+
|
| 459 |
+
assert p.match(q + r) in [ {q: p, r: 0}, {q: 0, r: p} ]
|
| 460 |
+
assert p.match(q*r) in [ {q: p, r: 1}, {q: 1, r: p} ]
|
| 461 |
+
|
| 462 |
+
p = Wild('p')
|
| 463 |
+
q = Wild('q', exclude=[p])
|
| 464 |
+
r = Wild('r')
|
| 465 |
+
|
| 466 |
+
assert p.match(q + r) == {q: 0, r: p}
|
| 467 |
+
assert p.match(q*r) == {q: 1, r: p}
|
| 468 |
+
|
| 469 |
+
p = Wild('p')
|
| 470 |
+
q = Wild('q', exclude=[p])
|
| 471 |
+
r = Wild('r', exclude=[p])
|
| 472 |
+
|
| 473 |
+
assert p.match(q + r) is None
|
| 474 |
+
assert p.match(q*r) is None
|
| 475 |
+
|
| 476 |
+
|
| 477 |
+
def test__combine_inverse():
|
| 478 |
+
x, y = symbols("x y")
|
| 479 |
+
assert Mul._combine_inverse(x*I*y, x*I) == y
|
| 480 |
+
assert Mul._combine_inverse(x*x**(1 + y), x**(1 + y)) == x
|
| 481 |
+
assert Mul._combine_inverse(x*I*y, y*I) == x
|
| 482 |
+
assert Mul._combine_inverse(oo*I*y, y*I) is oo
|
| 483 |
+
assert Mul._combine_inverse(oo*I*y, oo*I) == y
|
| 484 |
+
assert Mul._combine_inverse(oo*I*y, oo*I) == y
|
| 485 |
+
assert Mul._combine_inverse(oo*y, -oo) == -y
|
| 486 |
+
assert Mul._combine_inverse(-oo*y, oo) == -y
|
| 487 |
+
assert Mul._combine_inverse((1-exp(x/y)),(exp(x/y)-1)) == -1
|
| 488 |
+
assert Add._combine_inverse(oo, oo) is S.Zero
|
| 489 |
+
assert Add._combine_inverse(oo*I, oo*I) is S.Zero
|
| 490 |
+
assert Add._combine_inverse(x*oo, x*oo) is S.Zero
|
| 491 |
+
assert Add._combine_inverse(-x*oo, -x*oo) is S.Zero
|
| 492 |
+
assert Add._combine_inverse((x - oo)*(x + oo), -oo)
|
| 493 |
+
|
| 494 |
+
|
| 495 |
+
def test_issue_3773():
|
| 496 |
+
x = symbols('x')
|
| 497 |
+
z, phi, r = symbols('z phi r')
|
| 498 |
+
c, A, B, N = symbols('c A B N', cls=Wild)
|
| 499 |
+
l = Wild('l', exclude=(0,))
|
| 500 |
+
|
| 501 |
+
eq = z * sin(2*phi) * r**7
|
| 502 |
+
matcher = c * sin(phi*N)**l * r**A * log(r)**B
|
| 503 |
+
|
| 504 |
+
assert eq.match(matcher) == {c: z, l: 1, N: 2, A: 7, B: 0}
|
| 505 |
+
assert (-eq).match(matcher) == {c: -z, l: 1, N: 2, A: 7, B: 0}
|
| 506 |
+
assert (x*eq).match(matcher) == {c: x*z, l: 1, N: 2, A: 7, B: 0}
|
| 507 |
+
assert (-7*x*eq).match(matcher) == {c: -7*x*z, l: 1, N: 2, A: 7, B: 0}
|
| 508 |
+
|
| 509 |
+
matcher = c*sin(phi*N)**l * r**A
|
| 510 |
+
|
| 511 |
+
assert eq.match(matcher) == {c: z, l: 1, N: 2, A: 7}
|
| 512 |
+
assert (-eq).match(matcher) == {c: -z, l: 1, N: 2, A: 7}
|
| 513 |
+
assert (x*eq).match(matcher) == {c: x*z, l: 1, N: 2, A: 7}
|
| 514 |
+
assert (-7*x*eq).match(matcher) == {c: -7*x*z, l: 1, N: 2, A: 7}
|
| 515 |
+
|
| 516 |
+
|
| 517 |
+
def test_issue_3883():
|
| 518 |
+
from sympy.abc import gamma, mu, x
|
| 519 |
+
f = (-gamma * (x - mu)**2 - log(gamma) + log(2*pi))/2
|
| 520 |
+
a, b, c = symbols('a b c', cls=Wild, exclude=(gamma,))
|
| 521 |
+
|
| 522 |
+
assert f.match(a * log(gamma) + b * gamma + c) == \
|
| 523 |
+
{a: Rational(-1, 2), b: -(-mu + x)**2/2, c: log(2*pi)/2}
|
| 524 |
+
assert f.expand().collect(gamma).match(a * log(gamma) + b * gamma + c) == \
|
| 525 |
+
{a: Rational(-1, 2), b: (-(x - mu)**2/2).expand(), c: (log(2*pi)/2).expand()}
|
| 526 |
+
g1 = Wild('g1', exclude=[gamma])
|
| 527 |
+
g2 = Wild('g2', exclude=[gamma])
|
| 528 |
+
g3 = Wild('g3', exclude=[gamma])
|
| 529 |
+
assert f.expand().match(g1 * log(gamma) + g2 * gamma + g3) == \
|
| 530 |
+
{g3: log(2)/2 + log(pi)/2, g1: Rational(-1, 2), g2: -mu**2/2 + mu*x - x**2/2}
|
| 531 |
+
|
| 532 |
+
|
| 533 |
+
def test_issue_4418():
|
| 534 |
+
x = Symbol('x')
|
| 535 |
+
a, b, c = symbols('a b c', cls=Wild, exclude=(x,))
|
| 536 |
+
f, g = symbols('f g', cls=Function)
|
| 537 |
+
|
| 538 |
+
eq = diff(g(x)*f(x).diff(x), x)
|
| 539 |
+
|
| 540 |
+
assert eq.match(
|
| 541 |
+
g(x).diff(x)*f(x).diff(x) + g(x)*f(x).diff(x, x) + c) == {c: 0}
|
| 542 |
+
assert eq.match(a*g(x).diff(
|
| 543 |
+
x)*f(x).diff(x) + b*g(x)*f(x).diff(x, x) + c) == {a: 1, b: 1, c: 0}
|
| 544 |
+
|
| 545 |
+
|
| 546 |
+
def test_issue_4700():
|
| 547 |
+
f = Function('f')
|
| 548 |
+
x = Symbol('x')
|
| 549 |
+
a, b = symbols('a b', cls=Wild, exclude=(f(x),))
|
| 550 |
+
|
| 551 |
+
p = a*f(x) + b
|
| 552 |
+
eq1 = sin(x)
|
| 553 |
+
eq2 = f(x) + sin(x)
|
| 554 |
+
eq3 = f(x) + x + sin(x)
|
| 555 |
+
eq4 = x + sin(x)
|
| 556 |
+
|
| 557 |
+
assert eq1.match(p) == {a: 0, b: sin(x)}
|
| 558 |
+
assert eq2.match(p) == {a: 1, b: sin(x)}
|
| 559 |
+
assert eq3.match(p) == {a: 1, b: x + sin(x)}
|
| 560 |
+
assert eq4.match(p) == {a: 0, b: x + sin(x)}
|
| 561 |
+
|
| 562 |
+
|
| 563 |
+
def test_issue_5168():
|
| 564 |
+
a, b, c = symbols('a b c', cls=Wild)
|
| 565 |
+
x = Symbol('x')
|
| 566 |
+
f = Function('f')
|
| 567 |
+
|
| 568 |
+
assert x.match(a) == {a: x}
|
| 569 |
+
assert x.match(a*f(x)**c) == {a: x, c: 0}
|
| 570 |
+
assert x.match(a*b) == {a: 1, b: x}
|
| 571 |
+
assert x.match(a*b*f(x)**c) == {a: 1, b: x, c: 0}
|
| 572 |
+
|
| 573 |
+
assert (-x).match(a) == {a: -x}
|
| 574 |
+
assert (-x).match(a*f(x)**c) == {a: -x, c: 0}
|
| 575 |
+
assert (-x).match(a*b) == {a: -1, b: x}
|
| 576 |
+
assert (-x).match(a*b*f(x)**c) == {a: -1, b: x, c: 0}
|
| 577 |
+
|
| 578 |
+
assert (2*x).match(a) == {a: 2*x}
|
| 579 |
+
assert (2*x).match(a*f(x)**c) == {a: 2*x, c: 0}
|
| 580 |
+
assert (2*x).match(a*b) == {a: 2, b: x}
|
| 581 |
+
assert (2*x).match(a*b*f(x)**c) == {a: 2, b: x, c: 0}
|
| 582 |
+
|
| 583 |
+
assert (-2*x).match(a) == {a: -2*x}
|
| 584 |
+
assert (-2*x).match(a*f(x)**c) == {a: -2*x, c: 0}
|
| 585 |
+
assert (-2*x).match(a*b) == {a: -2, b: x}
|
| 586 |
+
assert (-2*x).match(a*b*f(x)**c) == {a: -2, b: x, c: 0}
|
| 587 |
+
|
| 588 |
+
|
| 589 |
+
def test_issue_4559():
|
| 590 |
+
x = Symbol('x')
|
| 591 |
+
e = Symbol('e')
|
| 592 |
+
w = Wild('w', exclude=[x])
|
| 593 |
+
y = Wild('y')
|
| 594 |
+
|
| 595 |
+
# this is as it should be
|
| 596 |
+
|
| 597 |
+
assert (3/x).match(w/y) == {w: 3, y: x}
|
| 598 |
+
assert (3*x).match(w*y) == {w: 3, y: x}
|
| 599 |
+
assert (x/3).match(y/w) == {w: 3, y: x}
|
| 600 |
+
assert (3*x).match(y/w) == {w: S.One/3, y: x}
|
| 601 |
+
assert (3*x).match(y/w) == {w: Rational(1, 3), y: x}
|
| 602 |
+
|
| 603 |
+
# these could be allowed to fail
|
| 604 |
+
|
| 605 |
+
assert (x/3).match(w/y) == {w: S.One/3, y: 1/x}
|
| 606 |
+
assert (3*x).match(w/y) == {w: 3, y: 1/x}
|
| 607 |
+
assert (3/x).match(w*y) == {w: 3, y: 1/x}
|
| 608 |
+
|
| 609 |
+
# Note that solve will give
|
| 610 |
+
# multiple roots but match only gives one:
|
| 611 |
+
#
|
| 612 |
+
# >>> solve(x**r-y**2,y)
|
| 613 |
+
# [-x**(r/2), x**(r/2)]
|
| 614 |
+
|
| 615 |
+
r = Symbol('r', rational=True)
|
| 616 |
+
assert (x**r).match(y**2) == {y: x**(r/2)}
|
| 617 |
+
assert (x**e).match(y**2) == {y: sqrt(x**e)}
|
| 618 |
+
|
| 619 |
+
# since (x**i = y) -> x = y**(1/i) where i is an integer
|
| 620 |
+
# the following should also be valid as long as y is not
|
| 621 |
+
# zero when i is negative.
|
| 622 |
+
|
| 623 |
+
a = Wild('a')
|
| 624 |
+
|
| 625 |
+
e = S.Zero
|
| 626 |
+
assert e.match(a) == {a: e}
|
| 627 |
+
assert e.match(1/a) is None
|
| 628 |
+
assert e.match(a**.3) is None
|
| 629 |
+
|
| 630 |
+
e = S(3)
|
| 631 |
+
assert e.match(1/a) == {a: 1/e}
|
| 632 |
+
assert e.match(1/a**2) == {a: 1/sqrt(e)}
|
| 633 |
+
e = pi
|
| 634 |
+
assert e.match(1/a) == {a: 1/e}
|
| 635 |
+
assert e.match(1/a**2) == {a: 1/sqrt(e)}
|
| 636 |
+
assert (-e).match(sqrt(a)) is None
|
| 637 |
+
assert (-e).match(a**2) == {a: I*sqrt(pi)}
|
| 638 |
+
|
| 639 |
+
# The pattern matcher doesn't know how to handle (x - a)**2 == (a - x)**2. To
|
| 640 |
+
# avoid ambiguity in actual applications, don't put a coefficient (including a
|
| 641 |
+
# minus sign) in front of a wild.
|
| 642 |
+
@XFAIL
|
| 643 |
+
def test_issue_4883():
|
| 644 |
+
a = Wild('a')
|
| 645 |
+
x = Symbol('x')
|
| 646 |
+
|
| 647 |
+
e = [i**2 for i in (x - 2, 2 - x)]
|
| 648 |
+
p = [i**2 for i in (x - a, a- x)]
|
| 649 |
+
for eq in e:
|
| 650 |
+
for pat in p:
|
| 651 |
+
assert eq.match(pat) == {a: 2}
|
| 652 |
+
|
| 653 |
+
|
| 654 |
+
def test_issue_4319():
|
| 655 |
+
x, y = symbols('x y')
|
| 656 |
+
|
| 657 |
+
p = -x*(S.One/8 - y)
|
| 658 |
+
ans = {S.Zero, y - S.One/8}
|
| 659 |
+
|
| 660 |
+
def ok(pat):
|
| 661 |
+
assert set(p.match(pat).values()) == ans
|
| 662 |
+
|
| 663 |
+
ok(Wild("coeff", exclude=[x])*x + Wild("rest"))
|
| 664 |
+
ok(Wild("w", exclude=[x])*x + Wild("rest"))
|
| 665 |
+
ok(Wild("coeff", exclude=[x])*x + Wild("rest"))
|
| 666 |
+
ok(Wild("w", exclude=[x])*x + Wild("rest"))
|
| 667 |
+
ok(Wild("e", exclude=[x])*x + Wild("rest"))
|
| 668 |
+
ok(Wild("ress", exclude=[x])*x + Wild("rest"))
|
| 669 |
+
ok(Wild("resu", exclude=[x])*x + Wild("rest"))
|
| 670 |
+
|
| 671 |
+
|
| 672 |
+
def test_issue_3778():
|
| 673 |
+
p, c, q = symbols('p c q', cls=Wild)
|
| 674 |
+
x = Symbol('x')
|
| 675 |
+
|
| 676 |
+
assert (sin(x)**2).match(sin(p)*sin(q)*c) == {q: x, c: 1, p: x}
|
| 677 |
+
assert (2*sin(x)).match(sin(p) + sin(q) + c) == {q: x, c: 0, p: x}
|
| 678 |
+
|
| 679 |
+
|
| 680 |
+
def test_issue_6103():
|
| 681 |
+
x = Symbol('x')
|
| 682 |
+
a = Wild('a')
|
| 683 |
+
assert (-I*x*oo).match(I*a*oo) == {a: -x}
|
| 684 |
+
|
| 685 |
+
|
| 686 |
+
def test_issue_3539():
|
| 687 |
+
a = Wild('a')
|
| 688 |
+
x = Symbol('x')
|
| 689 |
+
assert (x - 2).match(a - x) is None
|
| 690 |
+
assert (6/x).match(a*x) is None
|
| 691 |
+
assert (6/x**2).match(a/x) == {a: 6/x}
|
| 692 |
+
|
| 693 |
+
def test_gh_issue_2711():
|
| 694 |
+
x = Symbol('x')
|
| 695 |
+
f = meijerg(((), ()), ((0,), ()), x)
|
| 696 |
+
a = Wild('a')
|
| 697 |
+
b = Wild('b')
|
| 698 |
+
|
| 699 |
+
assert f.find(a) == {(S.Zero,), ((), ()), ((S.Zero,), ()), x, S.Zero,
|
| 700 |
+
(), meijerg(((), ()), ((S.Zero,), ()), x)}
|
| 701 |
+
assert f.find(a + b) == \
|
| 702 |
+
{meijerg(((), ()), ((S.Zero,), ()), x), x, S.Zero}
|
| 703 |
+
assert f.find(a**2) == {meijerg(((), ()), ((S.Zero,), ()), x), x}
|
| 704 |
+
|
| 705 |
+
|
| 706 |
+
def test_issue_17354():
|
| 707 |
+
from sympy.core.symbol import (Wild, symbols)
|
| 708 |
+
x, y = symbols("x y", real=True)
|
| 709 |
+
a, b = symbols("a b", cls=Wild)
|
| 710 |
+
assert ((0 <= x).reversed | (y <= x)).match((1/a <= b) | (a <= b)) is None
|
| 711 |
+
|
| 712 |
+
|
| 713 |
+
def test_match_issue_17397():
|
| 714 |
+
f = Function("f")
|
| 715 |
+
x = Symbol("x")
|
| 716 |
+
a3 = Wild('a3', exclude=[f(x), f(x).diff(x), f(x).diff(x, 2)])
|
| 717 |
+
b3 = Wild('b3', exclude=[f(x), f(x).diff(x), f(x).diff(x, 2)])
|
| 718 |
+
c3 = Wild('c3', exclude=[f(x), f(x).diff(x), f(x).diff(x, 2)])
|
| 719 |
+
deq = a3*(f(x).diff(x, 2)) + b3*f(x).diff(x) + c3*f(x)
|
| 720 |
+
|
| 721 |
+
eq = (x-2)**2*(f(x).diff(x, 2)) + (x-2)*(f(x).diff(x)) + ((x-2)**2 - 4)*f(x)
|
| 722 |
+
r = collect(eq, [f(x).diff(x, 2), f(x).diff(x), f(x)]).match(deq)
|
| 723 |
+
assert r == {a3: (x - 2)**2, c3: (x - 2)**2 - 4, b3: x - 2}
|
| 724 |
+
|
| 725 |
+
eq =x*f(x) + x*Derivative(f(x), (x, 2)) - 4*f(x) + Derivative(f(x), x) \
|
| 726 |
+
- 4*Derivative(f(x), (x, 2)) - 2*Derivative(f(x), x)/x + 4*Derivative(f(x), (x, 2))/x
|
| 727 |
+
r = collect(eq, [f(x).diff(x, 2), f(x).diff(x), f(x)]).match(deq)
|
| 728 |
+
assert r == {a3: x - 4 + 4/x, b3: 1 - 2/x, c3: x - 4}
|
| 729 |
+
|
| 730 |
+
|
| 731 |
+
def test_match_issue_21942():
|
| 732 |
+
a, r, w = symbols('a, r, w', nonnegative=True)
|
| 733 |
+
p = symbols('p', positive=True)
|
| 734 |
+
g_ = Wild('g')
|
| 735 |
+
pattern = g_ ** (1 / (1 - p))
|
| 736 |
+
eq = (a * r ** (1 - p) + w ** (1 - p) * (1 - a)) ** (1 / (1 - p))
|
| 737 |
+
m = {g_: a * r ** (1 - p) + w ** (1 - p) * (1 - a)}
|
| 738 |
+
assert pattern.matches(eq) == m
|
| 739 |
+
assert (-pattern).matches(-eq) == m
|
| 740 |
+
assert pattern.matches(signsimp(eq)) is None
|
| 741 |
+
|
| 742 |
+
|
| 743 |
+
def test_match_terms():
|
| 744 |
+
X, Y = map(Wild, "XY")
|
| 745 |
+
x, y, z = symbols('x y z')
|
| 746 |
+
assert (5*y - x).match(5*X - Y) == {X: y, Y: x}
|
| 747 |
+
# 15907
|
| 748 |
+
assert (x + (y - 1)*z).match(x + X*z) == {X: y - 1}
|
| 749 |
+
# 20747
|
| 750 |
+
assert (x - log(x/y)*(1-exp(x/y))).match(x - log(X/y)*(1-exp(x/y))) == {X: x}
|
| 751 |
+
|
| 752 |
+
|
| 753 |
+
def test_match_bound():
|
| 754 |
+
V, W = map(Wild, "VW")
|
| 755 |
+
x, y = symbols('x y')
|
| 756 |
+
assert Sum(x, (x, 1, 2)).match(Sum(y, (y, 1, W))) is None
|
| 757 |
+
assert Sum(x, (x, 1, 2)).match(Sum(V, (V, 1, W))) == {W: 2, V:x}
|
| 758 |
+
assert Sum(x, (x, 1, 2)).match(Sum(V, (V, 1, 2))) == {V:x}
|
| 759 |
+
|
| 760 |
+
|
| 761 |
+
def test_issue_22462():
|
| 762 |
+
x, f = symbols('x'), Function('f')
|
| 763 |
+
n, Q = symbols('n Q', cls=Wild)
|
| 764 |
+
pattern = -Q*f(x)**n
|
| 765 |
+
eq = 5*f(x)**2
|
| 766 |
+
assert pattern.matches(eq) == {n: 2, Q: -5}
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_noncommutative.py
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Tests for noncommutative symbols and expressions."""
|
| 2 |
+
|
| 3 |
+
from sympy.core.function import expand
|
| 4 |
+
from sympy.core.numbers import I
|
| 5 |
+
from sympy.core.symbol import symbols
|
| 6 |
+
from sympy.functions.elementary.complexes import (adjoint, conjugate, transpose)
|
| 7 |
+
from sympy.functions.elementary.trigonometric import (cos, sin)
|
| 8 |
+
from sympy.polys.polytools import (cancel, factor)
|
| 9 |
+
from sympy.simplify.combsimp import combsimp
|
| 10 |
+
from sympy.simplify.gammasimp import gammasimp
|
| 11 |
+
from sympy.simplify.radsimp import (collect, radsimp, rcollect)
|
| 12 |
+
from sympy.simplify.ratsimp import ratsimp
|
| 13 |
+
from sympy.simplify.simplify import (posify, simplify)
|
| 14 |
+
from sympy.simplify.trigsimp import trigsimp
|
| 15 |
+
from sympy.abc import x, y, z
|
| 16 |
+
from sympy.testing.pytest import XFAIL
|
| 17 |
+
|
| 18 |
+
A, B, C = symbols("A B C", commutative=False)
|
| 19 |
+
X = symbols("X", commutative=False, hermitian=True)
|
| 20 |
+
Y = symbols("Y", commutative=False, antihermitian=True)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def test_adjoint():
|
| 24 |
+
assert adjoint(A).is_commutative is False
|
| 25 |
+
assert adjoint(A*A) == adjoint(A)**2
|
| 26 |
+
assert adjoint(A*B) == adjoint(B)*adjoint(A)
|
| 27 |
+
assert adjoint(A*B**2) == adjoint(B)**2*adjoint(A)
|
| 28 |
+
assert adjoint(A*B - B*A) == adjoint(B)*adjoint(A) - adjoint(A)*adjoint(B)
|
| 29 |
+
assert adjoint(A + I*B) == adjoint(A) - I*adjoint(B)
|
| 30 |
+
|
| 31 |
+
assert adjoint(X) == X
|
| 32 |
+
assert adjoint(-I*X) == I*X
|
| 33 |
+
assert adjoint(Y) == -Y
|
| 34 |
+
assert adjoint(-I*Y) == -I*Y
|
| 35 |
+
|
| 36 |
+
assert adjoint(X) == conjugate(transpose(X))
|
| 37 |
+
assert adjoint(Y) == conjugate(transpose(Y))
|
| 38 |
+
assert adjoint(X) == transpose(conjugate(X))
|
| 39 |
+
assert adjoint(Y) == transpose(conjugate(Y))
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def test_cancel():
|
| 43 |
+
assert cancel(A*B - B*A) == A*B - B*A
|
| 44 |
+
assert cancel(A*B*(x - 1)) == A*B*(x - 1)
|
| 45 |
+
assert cancel(A*B*(x**2 - 1)/(x + 1)) == A*B*(x - 1)
|
| 46 |
+
assert cancel(A*B*(x**2 - 1)/(x + 1) - B*A*(x - 1)) == A*B*(x - 1) + (1 - x)*B*A
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
@XFAIL
|
| 50 |
+
def test_collect():
|
| 51 |
+
assert collect(A*B - B*A, A) == A*B - B*A
|
| 52 |
+
assert collect(A*B - B*A, B) == A*B - B*A
|
| 53 |
+
assert collect(A*B - B*A, x) == A*B - B*A
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def test_combsimp():
|
| 57 |
+
assert combsimp(A*B - B*A) == A*B - B*A
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def test_gammasimp():
|
| 61 |
+
assert gammasimp(A*B - B*A) == A*B - B*A
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
def test_conjugate():
|
| 65 |
+
assert conjugate(A).is_commutative is False
|
| 66 |
+
assert (A*A).conjugate() == conjugate(A)**2
|
| 67 |
+
assert (A*B).conjugate() == conjugate(A)*conjugate(B)
|
| 68 |
+
assert (A*B**2).conjugate() == conjugate(A)*conjugate(B)**2
|
| 69 |
+
assert (A*B - B*A).conjugate() == \
|
| 70 |
+
conjugate(A)*conjugate(B) - conjugate(B)*conjugate(A)
|
| 71 |
+
assert (A*B).conjugate() - (B*A).conjugate() == \
|
| 72 |
+
conjugate(A)*conjugate(B) - conjugate(B)*conjugate(A)
|
| 73 |
+
assert (A + I*B).conjugate() == conjugate(A) - I*conjugate(B)
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
def test_expand():
|
| 77 |
+
assert expand((A*B)**2) == A*B*A*B
|
| 78 |
+
assert expand(A*B - B*A) == A*B - B*A
|
| 79 |
+
assert expand((A*B/A)**2) == A*B*B/A
|
| 80 |
+
assert expand(B*A*(A + B)*B) == B*A**2*B + B*A*B**2
|
| 81 |
+
assert expand(B*A*(A + C)*B) == B*A**2*B + B*A*C*B
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def test_factor():
|
| 85 |
+
assert factor(A*B - B*A) == A*B - B*A
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def test_posify():
|
| 89 |
+
assert posify(A)[0].is_commutative is False
|
| 90 |
+
for q in (A*B/A, (A*B/A)**2, (A*B)**2, A*B - B*A):
|
| 91 |
+
p = posify(q)
|
| 92 |
+
assert p[0].subs(p[1]) == q
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
def test_radsimp():
|
| 96 |
+
assert radsimp(A*B - B*A) == A*B - B*A
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
@XFAIL
|
| 100 |
+
def test_ratsimp():
|
| 101 |
+
assert ratsimp(A*B - B*A) == A*B - B*A
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
@XFAIL
|
| 105 |
+
def test_rcollect():
|
| 106 |
+
assert rcollect(A*B - B*A, A) == A*B - B*A
|
| 107 |
+
assert rcollect(A*B - B*A, B) == A*B - B*A
|
| 108 |
+
assert rcollect(A*B - B*A, x) == A*B - B*A
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
def test_simplify():
|
| 112 |
+
assert simplify(A*B - B*A) == A*B - B*A
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def test_subs():
|
| 116 |
+
assert (x*y*A).subs(x*y, z) == A*z
|
| 117 |
+
assert (x*A*B).subs(x*A, C) == C*B
|
| 118 |
+
assert (x*A*x*x).subs(x**2*A, C) == x*C
|
| 119 |
+
assert (x*A*x*B).subs(x**2*A, C) == C*B
|
| 120 |
+
assert (A**2*B**2).subs(A*B**2, C) == A*C
|
| 121 |
+
assert (A*A*A + A*B*A).subs(A*A*A, C) == C + A*B*A
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def test_transpose():
|
| 125 |
+
assert transpose(A).is_commutative is False
|
| 126 |
+
assert transpose(A*A) == transpose(A)**2
|
| 127 |
+
assert transpose(A*B) == transpose(B)*transpose(A)
|
| 128 |
+
assert transpose(A*B**2) == transpose(B)**2*transpose(A)
|
| 129 |
+
assert transpose(A*B - B*A) == \
|
| 130 |
+
transpose(B)*transpose(A) - transpose(A)*transpose(B)
|
| 131 |
+
assert transpose(A + I*B) == transpose(A) + I*transpose(B)
|
| 132 |
+
|
| 133 |
+
assert transpose(X) == conjugate(X)
|
| 134 |
+
assert transpose(-I*X) == -I*conjugate(X)
|
| 135 |
+
assert transpose(Y) == -conjugate(Y)
|
| 136 |
+
assert transpose(-I*Y) == I*conjugate(Y)
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
def test_trigsimp():
|
| 140 |
+
assert trigsimp(A*sin(x)**2 + A*cos(x)**2) == A
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_numbers.py
ADDED
|
@@ -0,0 +1,2335 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numbers as nums
|
| 2 |
+
import decimal
|
| 3 |
+
from sympy.concrete.summations import Sum
|
| 4 |
+
from sympy.core import (EulerGamma, Catalan, TribonacciConstant,
|
| 5 |
+
GoldenRatio)
|
| 6 |
+
from sympy.core.containers import Tuple
|
| 7 |
+
from sympy.core.expr import unchanged
|
| 8 |
+
from sympy.core.logic import fuzzy_not
|
| 9 |
+
from sympy.core.mul import Mul
|
| 10 |
+
from sympy.core.numbers import (mpf_norm, seterr,
|
| 11 |
+
Integer, I, pi, comp, Rational, E, nan,
|
| 12 |
+
oo, AlgebraicNumber, Number, Float, zoo, equal_valued,
|
| 13 |
+
int_valued, all_close)
|
| 14 |
+
from sympy.core.intfunc import (igcd, igcdex, igcd2, igcd_lehmer,
|
| 15 |
+
ilcm, integer_nthroot, isqrt, integer_log, mod_inverse)
|
| 16 |
+
from sympy.core.power import Pow
|
| 17 |
+
from sympy.core.relational import Ge, Gt, Le, Lt
|
| 18 |
+
from sympy.core.singleton import S
|
| 19 |
+
from sympy.core.symbol import Dummy, Symbol
|
| 20 |
+
from sympy.core.sympify import sympify
|
| 21 |
+
from sympy.functions.combinatorial.factorials import factorial
|
| 22 |
+
from sympy.functions.elementary.integers import floor
|
| 23 |
+
from sympy.functions.combinatorial.numbers import fibonacci
|
| 24 |
+
from sympy.functions.elementary.exponential import exp, log
|
| 25 |
+
from sympy.functions.elementary.miscellaneous import sqrt, cbrt
|
| 26 |
+
from sympy.functions.elementary.trigonometric import cos, sin
|
| 27 |
+
from sympy.polys.domains.realfield import RealField
|
| 28 |
+
from sympy.printing.latex import latex
|
| 29 |
+
from sympy.printing.repr import srepr
|
| 30 |
+
from sympy.simplify import simplify
|
| 31 |
+
from sympy.polys.domains.groundtypes import PythonRational
|
| 32 |
+
from sympy.utilities.decorator import conserve_mpmath_dps
|
| 33 |
+
from sympy.utilities.iterables import permutations
|
| 34 |
+
from sympy.testing.pytest import (XFAIL, raises, _both_exp_pow,
|
| 35 |
+
warns_deprecated_sympy)
|
| 36 |
+
from sympy import Add
|
| 37 |
+
|
| 38 |
+
from mpmath import mpf
|
| 39 |
+
import mpmath
|
| 40 |
+
from sympy.core import numbers
|
| 41 |
+
t = Symbol('t', real=False)
|
| 42 |
+
|
| 43 |
+
_ninf = float(-oo)
|
| 44 |
+
_inf = float(oo)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def same_and_same_prec(a, b):
|
| 48 |
+
# stricter matching for Floats
|
| 49 |
+
return a == b and a._prec == b._prec
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def test_seterr():
|
| 53 |
+
seterr(divide=True)
|
| 54 |
+
raises(ValueError, lambda: S.Zero/S.Zero)
|
| 55 |
+
seterr(divide=False)
|
| 56 |
+
assert S.Zero / S.Zero is S.NaN
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def test_mod():
|
| 60 |
+
x = S.Half
|
| 61 |
+
y = Rational(3, 4)
|
| 62 |
+
z = Rational(5, 18043)
|
| 63 |
+
|
| 64 |
+
assert x % x == 0
|
| 65 |
+
assert x % y == S.Half
|
| 66 |
+
assert x % z == Rational(3, 36086)
|
| 67 |
+
assert y % x == Rational(1, 4)
|
| 68 |
+
assert y % y == 0
|
| 69 |
+
assert y % z == Rational(9, 72172)
|
| 70 |
+
assert z % x == Rational(5, 18043)
|
| 71 |
+
assert z % y == Rational(5, 18043)
|
| 72 |
+
assert z % z == 0
|
| 73 |
+
|
| 74 |
+
a = Float(2.6)
|
| 75 |
+
|
| 76 |
+
assert (a % .2) == 0.0
|
| 77 |
+
assert (a % 2).round(15) == 0.6
|
| 78 |
+
assert (a % 0.5).round(15) == 0.1
|
| 79 |
+
|
| 80 |
+
p = Symbol('p', infinite=True)
|
| 81 |
+
|
| 82 |
+
assert oo % oo is nan
|
| 83 |
+
assert zoo % oo is nan
|
| 84 |
+
assert 5 % oo is nan
|
| 85 |
+
assert p % 5 is nan
|
| 86 |
+
|
| 87 |
+
# In these two tests, if the precision of m does
|
| 88 |
+
# not match the precision of the ans, then it is
|
| 89 |
+
# likely that the change made now gives an answer
|
| 90 |
+
# with degraded accuracy.
|
| 91 |
+
r = Rational(500, 41)
|
| 92 |
+
f = Float('.36', 3)
|
| 93 |
+
m = r % f
|
| 94 |
+
ans = Float(r % Rational(f), 3)
|
| 95 |
+
assert m == ans and m._prec == ans._prec
|
| 96 |
+
f = Float('8.36', 3)
|
| 97 |
+
m = f % r
|
| 98 |
+
ans = Float(Rational(f) % r, 3)
|
| 99 |
+
assert m == ans and m._prec == ans._prec
|
| 100 |
+
|
| 101 |
+
s = S.Zero
|
| 102 |
+
|
| 103 |
+
assert s % float(1) == 0.0
|
| 104 |
+
|
| 105 |
+
# No rounding required since these numbers can be represented
|
| 106 |
+
# exactly.
|
| 107 |
+
assert Rational(3, 4) % Float(1.1) == 0.75
|
| 108 |
+
assert Float(1.5) % Rational(5, 4) == 0.25
|
| 109 |
+
assert Rational(5, 4).__rmod__(Float('1.5')) == 0.25
|
| 110 |
+
assert Float('1.5').__rmod__(Float('2.75')) == Float('1.25')
|
| 111 |
+
assert 2.75 % Float('1.5') == Float('1.25')
|
| 112 |
+
|
| 113 |
+
a = Integer(7)
|
| 114 |
+
b = Integer(4)
|
| 115 |
+
|
| 116 |
+
assert type(a % b) == Integer
|
| 117 |
+
assert a % b == Integer(3)
|
| 118 |
+
assert Integer(1) % Rational(2, 3) == Rational(1, 3)
|
| 119 |
+
assert Rational(7, 5) % Integer(1) == Rational(2, 5)
|
| 120 |
+
assert Integer(2) % 1.5 == 0.5
|
| 121 |
+
|
| 122 |
+
assert Integer(3).__rmod__(Integer(10)) == Integer(1)
|
| 123 |
+
assert Integer(10) % 4 == Integer(2)
|
| 124 |
+
assert 15 % Integer(4) == Integer(3)
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def test_divmod():
|
| 128 |
+
x = Symbol("x")
|
| 129 |
+
assert divmod(S(12), S(8)) == Tuple(1, 4)
|
| 130 |
+
assert divmod(-S(12), S(8)) == Tuple(-2, 4)
|
| 131 |
+
assert divmod(S.Zero, S.One) == Tuple(0, 0)
|
| 132 |
+
raises(ZeroDivisionError, lambda: divmod(S.Zero, S.Zero))
|
| 133 |
+
raises(ZeroDivisionError, lambda: divmod(S.One, S.Zero))
|
| 134 |
+
assert divmod(S(12), 8) == Tuple(1, 4)
|
| 135 |
+
assert divmod(12, S(8)) == Tuple(1, 4)
|
| 136 |
+
assert S(1024)//x == 1024//x == floor(1024/x)
|
| 137 |
+
|
| 138 |
+
assert divmod(S("2"), S("3/2")) == Tuple(S("1"), S("1/2"))
|
| 139 |
+
assert divmod(S("3/2"), S("2")) == Tuple(S("0"), S("3/2"))
|
| 140 |
+
assert divmod(S("2"), S("3.5")) == Tuple(S("0"), S("2."))
|
| 141 |
+
assert divmod(S("3.5"), S("2")) == Tuple(S("1"), S("1.5"))
|
| 142 |
+
assert divmod(S("2"), S("1/3")) == Tuple(S("6"), S("0"))
|
| 143 |
+
assert divmod(S("1/3"), S("2")) == Tuple(S("0"), S("1/3"))
|
| 144 |
+
assert divmod(S("2"), S("1/10")) == Tuple(S("20"), S("0"))
|
| 145 |
+
assert divmod(S("2"), S(".1"))[0] == 19
|
| 146 |
+
assert divmod(S("0.1"), S("2")) == Tuple(S("0"), S("0.1"))
|
| 147 |
+
assert divmod(S("2"), 2) == Tuple(S("1"), S("0"))
|
| 148 |
+
assert divmod(2, S("2")) == Tuple(S("1"), S("0"))
|
| 149 |
+
assert divmod(S("2"), 1.5) == Tuple(S("1"), S("0.5"))
|
| 150 |
+
assert divmod(1.5, S("2")) == Tuple(S("0"), S("1.5"))
|
| 151 |
+
assert divmod(0.3, S("2")) == Tuple(S("0"), S("0.3"))
|
| 152 |
+
assert divmod(S("3/2"), S("3.5")) == Tuple(S("0"), S(3/2))
|
| 153 |
+
assert divmod(S("3.5"), S("3/2")) == Tuple(S("2"), S("0.5"))
|
| 154 |
+
assert divmod(S("3/2"), S("1/3")) == Tuple(S("4"), S("1/6"))
|
| 155 |
+
assert divmod(S("1/3"), S("3/2")) == Tuple(S("0"), S("1/3"))
|
| 156 |
+
assert divmod(S("3/2"), S("0.1"))[0] == 14
|
| 157 |
+
assert divmod(S("0.1"), S("3/2")) == Tuple(S("0"), S("0.1"))
|
| 158 |
+
assert divmod(S("3/2"), 2) == Tuple(S("0"), S("3/2"))
|
| 159 |
+
assert divmod(2, S("3/2")) == Tuple(S("1"), S("1/2"))
|
| 160 |
+
assert divmod(S("3/2"), 1.5) == Tuple(S("1"), S("0."))
|
| 161 |
+
assert divmod(1.5, S("3/2")) == Tuple(S("1"), S("0."))
|
| 162 |
+
assert divmod(S("3/2"), 0.3) == Tuple(S("5"), S("0."))
|
| 163 |
+
assert divmod(0.3, S("3/2")) == Tuple(S("0"), S("0.3"))
|
| 164 |
+
assert divmod(S("1/3"), S("3.5")) == (0, 1/3)
|
| 165 |
+
assert divmod(S("3.5"), S("0.1")) == Tuple(S("35"), S("0."))
|
| 166 |
+
assert divmod(S("0.1"), S("3.5")) == Tuple(S("0"), S("0.1"))
|
| 167 |
+
assert divmod(S("3.5"), 2) == Tuple(S("1"), S("1.5"))
|
| 168 |
+
assert divmod(2, S("3.5")) == Tuple(S("0"), S("2."))
|
| 169 |
+
assert divmod(S("3.5"), 1.5) == Tuple(S("2"), S("0.5"))
|
| 170 |
+
assert divmod(1.5, S("3.5")) == Tuple(S("0"), S("1.5"))
|
| 171 |
+
assert divmod(0.3, S("3.5")) == Tuple(S("0"), S("0.3"))
|
| 172 |
+
assert divmod(S("0.1"), S("1/3")) == Tuple(S("0"), S("0.1"))
|
| 173 |
+
assert divmod(S("1/3"), 2) == Tuple(S("0"), S("1/3"))
|
| 174 |
+
assert divmod(2, S("1/3")) == Tuple(S("6"), S("0"))
|
| 175 |
+
assert divmod(S("1/3"), 1.5) == (0, 1/3)
|
| 176 |
+
assert divmod(0.3, S("1/3")) == (0, 0.3)
|
| 177 |
+
assert divmod(S("0.1"), 2) == (0, 0.1)
|
| 178 |
+
assert divmod(2, S("0.1"))[0] == 19
|
| 179 |
+
assert divmod(S("0.1"), 1.5) == (0, 0.1)
|
| 180 |
+
assert divmod(1.5, S("0.1")) == Tuple(S("15"), S("0."))
|
| 181 |
+
assert divmod(S("0.1"), 0.3) == Tuple(S("0"), S("0.1"))
|
| 182 |
+
|
| 183 |
+
assert str(divmod(S("2"), 0.3)) == '(6, 0.2)'
|
| 184 |
+
assert str(divmod(S("3.5"), S("1/3"))) == '(10, 0.166666666666667)'
|
| 185 |
+
assert str(divmod(S("3.5"), 0.3)) == '(11, 0.2)'
|
| 186 |
+
assert str(divmod(S("1/3"), S("0.1"))) == '(3, 0.0333333333333333)'
|
| 187 |
+
assert str(divmod(1.5, S("1/3"))) == '(4, 0.166666666666667)'
|
| 188 |
+
assert str(divmod(S("1/3"), 0.3)) == '(1, 0.0333333333333333)'
|
| 189 |
+
assert str(divmod(0.3, S("0.1"))) == '(2, 0.1)'
|
| 190 |
+
|
| 191 |
+
assert divmod(-3, S(2)) == (-2, 1)
|
| 192 |
+
assert divmod(S(-3), S(2)) == (-2, 1)
|
| 193 |
+
assert divmod(S(-3), 2) == (-2, 1)
|
| 194 |
+
|
| 195 |
+
assert divmod(oo, 1) == (S.NaN, S.NaN)
|
| 196 |
+
assert divmod(S.NaN, 1) == (S.NaN, S.NaN)
|
| 197 |
+
assert divmod(1, S.NaN) == (S.NaN, S.NaN)
|
| 198 |
+
ans = [(-1, oo), (-1, oo), (0, 0), (0, 1), (0, 2)]
|
| 199 |
+
OO = float('inf')
|
| 200 |
+
ANS = [tuple(map(float, i)) for i in ans]
|
| 201 |
+
assert [divmod(i, oo) for i in range(-2, 3)] == ans
|
| 202 |
+
ans = [(0, -2), (0, -1), (0, 0), (-1, -oo), (-1, -oo)]
|
| 203 |
+
ANS = [tuple(map(float, i)) for i in ans]
|
| 204 |
+
assert [divmod(i, -oo) for i in range(-2, 3)] == ans
|
| 205 |
+
assert [divmod(i, -OO) for i in range(-2, 3)] == ANS
|
| 206 |
+
|
| 207 |
+
# sympy's divmod gives an Integer for the quotient rather than a float
|
| 208 |
+
dmod = lambda a, b: tuple([j if i else int(j) for i, j in enumerate(divmod(a, b))])
|
| 209 |
+
for a in (4, 4., 4.25, 0, 0., -4, -4. -4.25):
|
| 210 |
+
for b in (2, 2., 2.5, -2, -2., -2.5):
|
| 211 |
+
assert divmod(S(a), S(b)) == dmod(a, b)
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def test_igcd():
|
| 215 |
+
assert igcd(0, 0) == 0
|
| 216 |
+
assert igcd(0, 1) == 1
|
| 217 |
+
assert igcd(1, 0) == 1
|
| 218 |
+
assert igcd(0, 7) == 7
|
| 219 |
+
assert igcd(7, 0) == 7
|
| 220 |
+
assert igcd(7, 1) == 1
|
| 221 |
+
assert igcd(1, 7) == 1
|
| 222 |
+
assert igcd(-1, 0) == 1
|
| 223 |
+
assert igcd(0, -1) == 1
|
| 224 |
+
assert igcd(-1, -1) == 1
|
| 225 |
+
assert igcd(-1, 7) == 1
|
| 226 |
+
assert igcd(7, -1) == 1
|
| 227 |
+
assert igcd(8, 2) == 2
|
| 228 |
+
assert igcd(4, 8) == 4
|
| 229 |
+
assert igcd(8, 16) == 8
|
| 230 |
+
assert igcd(7, -3) == 1
|
| 231 |
+
assert igcd(-7, 3) == 1
|
| 232 |
+
assert igcd(-7, -3) == 1
|
| 233 |
+
assert igcd(*[10, 20, 30]) == 10
|
| 234 |
+
raises(TypeError, lambda: igcd())
|
| 235 |
+
raises(TypeError, lambda: igcd(2))
|
| 236 |
+
raises(ValueError, lambda: igcd(0, None))
|
| 237 |
+
raises(ValueError, lambda: igcd(1, 2.2))
|
| 238 |
+
for args in permutations((45.1, 1, 30)):
|
| 239 |
+
raises(ValueError, lambda: igcd(*args))
|
| 240 |
+
for args in permutations((1, 2, None)):
|
| 241 |
+
raises(ValueError, lambda: igcd(*args))
|
| 242 |
+
|
| 243 |
+
|
| 244 |
+
def test_igcd_lehmer():
|
| 245 |
+
a, b = fibonacci(10001), fibonacci(10000)
|
| 246 |
+
# len(str(a)) == 2090
|
| 247 |
+
# small divisors, long Euclidean sequence
|
| 248 |
+
assert igcd_lehmer(a, b) == 1
|
| 249 |
+
c = fibonacci(100)
|
| 250 |
+
assert igcd_lehmer(a*c, b*c) == c
|
| 251 |
+
# big divisor
|
| 252 |
+
assert igcd_lehmer(a, 10**1000) == 1
|
| 253 |
+
# swapping argument
|
| 254 |
+
assert igcd_lehmer(1, 2) == igcd_lehmer(2, 1)
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
def test_igcd2():
|
| 258 |
+
# short loop
|
| 259 |
+
assert igcd2(2**100 - 1, 2**99 - 1) == 1
|
| 260 |
+
# Lehmer's algorithm
|
| 261 |
+
a, b = int(fibonacci(10001)), int(fibonacci(10000))
|
| 262 |
+
assert igcd2(a, b) == 1
|
| 263 |
+
|
| 264 |
+
|
| 265 |
+
def test_ilcm():
|
| 266 |
+
assert ilcm(0, 0) == 0
|
| 267 |
+
assert ilcm(1, 0) == 0
|
| 268 |
+
assert ilcm(0, 1) == 0
|
| 269 |
+
assert ilcm(1, 1) == 1
|
| 270 |
+
assert ilcm(2, 1) == 2
|
| 271 |
+
assert ilcm(8, 2) == 8
|
| 272 |
+
assert ilcm(8, 6) == 24
|
| 273 |
+
assert ilcm(8, 7) == 56
|
| 274 |
+
assert ilcm(*[10, 20, 30]) == 60
|
| 275 |
+
raises(ValueError, lambda: ilcm(8.1, 7))
|
| 276 |
+
raises(ValueError, lambda: ilcm(8, 7.1))
|
| 277 |
+
raises(TypeError, lambda: ilcm(8))
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
def test_igcdex():
|
| 281 |
+
assert igcdex(2, 3) == (-1, 1, 1)
|
| 282 |
+
assert igcdex(10, 12) == (-1, 1, 2)
|
| 283 |
+
assert igcdex(100, 2004) == (-20, 1, 4)
|
| 284 |
+
assert igcdex(0, 0) == (0, 0, 0)
|
| 285 |
+
assert igcdex(1, 0) == (1, 0, 1)
|
| 286 |
+
|
| 287 |
+
|
| 288 |
+
def _strictly_equal(a, b):
|
| 289 |
+
return (a.p, a.q, type(a.p), type(a.q)) == \
|
| 290 |
+
(b.p, b.q, type(b.p), type(b.q))
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
def _test_rational_new(cls):
|
| 294 |
+
"""
|
| 295 |
+
Tests that are common between Integer and Rational.
|
| 296 |
+
"""
|
| 297 |
+
assert cls(0) is S.Zero
|
| 298 |
+
assert cls(1) is S.One
|
| 299 |
+
assert cls(-1) is S.NegativeOne
|
| 300 |
+
# These look odd, but are similar to int():
|
| 301 |
+
assert cls('1') is S.One
|
| 302 |
+
assert cls('-1') is S.NegativeOne
|
| 303 |
+
|
| 304 |
+
i = Integer(10)
|
| 305 |
+
assert _strictly_equal(i, cls('10'))
|
| 306 |
+
assert _strictly_equal(i, cls('10'))
|
| 307 |
+
assert _strictly_equal(i, cls(int(10)))
|
| 308 |
+
assert _strictly_equal(i, cls(i))
|
| 309 |
+
|
| 310 |
+
raises(TypeError, lambda: cls(Symbol('x')))
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
def test_Integer_new():
|
| 314 |
+
"""
|
| 315 |
+
Test for Integer constructor
|
| 316 |
+
"""
|
| 317 |
+
_test_rational_new(Integer)
|
| 318 |
+
|
| 319 |
+
assert _strictly_equal(Integer(0.9), S.Zero)
|
| 320 |
+
assert _strictly_equal(Integer(10.5), Integer(10))
|
| 321 |
+
raises(ValueError, lambda: Integer("10.5"))
|
| 322 |
+
assert Integer(Rational('1.' + '9'*20)) == 1
|
| 323 |
+
|
| 324 |
+
|
| 325 |
+
def test_Rational_new():
|
| 326 |
+
""""
|
| 327 |
+
Test for Rational constructor
|
| 328 |
+
"""
|
| 329 |
+
_test_rational_new(Rational)
|
| 330 |
+
|
| 331 |
+
n1 = S.Half
|
| 332 |
+
assert n1 == Rational(Integer(1), 2)
|
| 333 |
+
assert n1 == Rational(Integer(1), Integer(2))
|
| 334 |
+
assert n1 == Rational(1, Integer(2))
|
| 335 |
+
assert n1 == Rational(S.Half)
|
| 336 |
+
assert 1 == Rational(n1, n1)
|
| 337 |
+
assert Rational(3, 2) == Rational(S.Half, Rational(1, 3))
|
| 338 |
+
assert Rational(3, 1) == Rational(1, Rational(1, 3))
|
| 339 |
+
n3_4 = Rational(3, 4)
|
| 340 |
+
assert Rational('3/4') == n3_4
|
| 341 |
+
assert -Rational('-3/4') == n3_4
|
| 342 |
+
assert Rational('.76').limit_denominator(4) == n3_4
|
| 343 |
+
assert Rational(19, 25).limit_denominator(4) == n3_4
|
| 344 |
+
assert Rational('19/25').limit_denominator(4) == n3_4
|
| 345 |
+
assert Rational(1.0, 3) == Rational(1, 3)
|
| 346 |
+
assert Rational(1, 3.0) == Rational(1, 3)
|
| 347 |
+
assert Rational(Float(0.5)) == S.Half
|
| 348 |
+
assert Rational('1e2/1e-2') == Rational(10000)
|
| 349 |
+
assert Rational('1 234') == Rational(1234)
|
| 350 |
+
assert Rational('1/1 234') == Rational(1, 1234)
|
| 351 |
+
assert Rational(-1, 0) is S.ComplexInfinity
|
| 352 |
+
assert Rational(1, 0) is S.ComplexInfinity
|
| 353 |
+
# Make sure Rational doesn't lose precision on Floats
|
| 354 |
+
assert Rational(pi.evalf(100)).evalf(100) == pi.evalf(100)
|
| 355 |
+
raises(TypeError, lambda: Rational('3**3'))
|
| 356 |
+
raises(TypeError, lambda: Rational('1/2 + 2/3'))
|
| 357 |
+
|
| 358 |
+
# handle fractions.Fraction instances
|
| 359 |
+
try:
|
| 360 |
+
import fractions
|
| 361 |
+
assert Rational(fractions.Fraction(1, 2)) == S.Half
|
| 362 |
+
except ImportError:
|
| 363 |
+
pass
|
| 364 |
+
|
| 365 |
+
assert Rational(PythonRational(2, 6)) == Rational(1, 3)
|
| 366 |
+
|
| 367 |
+
with warns_deprecated_sympy():
|
| 368 |
+
assert Rational(2, 4, gcd=1).q == 4
|
| 369 |
+
with warns_deprecated_sympy():
|
| 370 |
+
n = Rational(2, -4, gcd=1)
|
| 371 |
+
assert n.q == 4
|
| 372 |
+
assert n.p == -2
|
| 373 |
+
|
| 374 |
+
assert Rational.from_coprime_ints(3, 5) == Rational(3, 5)
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
def test_issue_24543():
|
| 378 |
+
for p in ('1.5', 1.5, 2):
|
| 379 |
+
for q in ('1.5', 1.5, 2):
|
| 380 |
+
assert Rational(p, q).as_numer_denom() == Rational('%s/%s'%(p,q)).as_numer_denom()
|
| 381 |
+
|
| 382 |
+
assert Rational('0.5', '100') == Rational(1, 200)
|
| 383 |
+
|
| 384 |
+
|
| 385 |
+
def test_Number_new():
|
| 386 |
+
""""
|
| 387 |
+
Test for Number constructor
|
| 388 |
+
"""
|
| 389 |
+
# Expected behavior on numbers and strings
|
| 390 |
+
assert Number(1) is S.One
|
| 391 |
+
assert Number(2).__class__ is Integer
|
| 392 |
+
assert Number(-622).__class__ is Integer
|
| 393 |
+
assert Number(5, 3).__class__ is Rational
|
| 394 |
+
assert Number(5.3).__class__ is Float
|
| 395 |
+
assert Number('1') is S.One
|
| 396 |
+
assert Number('2').__class__ is Integer
|
| 397 |
+
assert Number('-622').__class__ is Integer
|
| 398 |
+
assert Number('5/3').__class__ is Rational
|
| 399 |
+
assert Number('5.3').__class__ is Float
|
| 400 |
+
raises(ValueError, lambda: Number('cos'))
|
| 401 |
+
raises(TypeError, lambda: Number(cos))
|
| 402 |
+
a = Rational(3, 5)
|
| 403 |
+
assert Number(a) is a # Check idempotence on Numbers
|
| 404 |
+
u = ['inf', '-inf', 'nan', 'iNF', '+inf']
|
| 405 |
+
v = [oo, -oo, nan, oo, oo]
|
| 406 |
+
for i, a in zip(u, v):
|
| 407 |
+
assert Number(i) is a, (i, Number(i), a)
|
| 408 |
+
|
| 409 |
+
|
| 410 |
+
def test_Number_cmp():
|
| 411 |
+
n1 = Number(1)
|
| 412 |
+
n2 = Number(2)
|
| 413 |
+
n3 = Number(-3)
|
| 414 |
+
|
| 415 |
+
assert n1 < n2
|
| 416 |
+
assert n1 <= n2
|
| 417 |
+
assert n3 < n1
|
| 418 |
+
assert n2 > n3
|
| 419 |
+
assert n2 >= n3
|
| 420 |
+
|
| 421 |
+
raises(TypeError, lambda: n1 < S.NaN)
|
| 422 |
+
raises(TypeError, lambda: n1 <= S.NaN)
|
| 423 |
+
raises(TypeError, lambda: n1 > S.NaN)
|
| 424 |
+
raises(TypeError, lambda: n1 >= S.NaN)
|
| 425 |
+
|
| 426 |
+
|
| 427 |
+
def test_Rational_cmp():
|
| 428 |
+
n1 = Rational(1, 4)
|
| 429 |
+
n2 = Rational(1, 3)
|
| 430 |
+
n3 = Rational(2, 4)
|
| 431 |
+
n4 = Rational(2, -4)
|
| 432 |
+
n5 = Rational(0)
|
| 433 |
+
n6 = Rational(1)
|
| 434 |
+
n7 = Rational(3)
|
| 435 |
+
n8 = Rational(-3)
|
| 436 |
+
|
| 437 |
+
assert n8 < n5
|
| 438 |
+
assert n5 < n6
|
| 439 |
+
assert n6 < n7
|
| 440 |
+
assert n8 < n7
|
| 441 |
+
assert n7 > n8
|
| 442 |
+
assert (n1 + 1)**n2 < 2
|
| 443 |
+
assert ((n1 + n6)/n7) < 1
|
| 444 |
+
|
| 445 |
+
assert n4 < n3
|
| 446 |
+
assert n2 < n3
|
| 447 |
+
assert n1 < n2
|
| 448 |
+
assert n3 > n1
|
| 449 |
+
assert not n3 < n1
|
| 450 |
+
assert not (Rational(-1) > 0)
|
| 451 |
+
assert Rational(-1) < 0
|
| 452 |
+
|
| 453 |
+
raises(TypeError, lambda: n1 < S.NaN)
|
| 454 |
+
raises(TypeError, lambda: n1 <= S.NaN)
|
| 455 |
+
raises(TypeError, lambda: n1 > S.NaN)
|
| 456 |
+
raises(TypeError, lambda: n1 >= S.NaN)
|
| 457 |
+
|
| 458 |
+
|
| 459 |
+
def test_Float():
|
| 460 |
+
def eq(a, b):
|
| 461 |
+
t = Float("1.0E-15")
|
| 462 |
+
return (-t < a - b < t)
|
| 463 |
+
|
| 464 |
+
equal_pairs = [
|
| 465 |
+
(0, 0.0), # This is just how Python works...
|
| 466 |
+
(0, S.Zero),
|
| 467 |
+
(0.0, Float(0)),
|
| 468 |
+
]
|
| 469 |
+
unequal_pairs = [
|
| 470 |
+
(0.0, S.Zero),
|
| 471 |
+
(0, Float(0)),
|
| 472 |
+
(S.Zero, Float(0)),
|
| 473 |
+
]
|
| 474 |
+
for p1, p2 in equal_pairs:
|
| 475 |
+
assert (p1 == p2) is True
|
| 476 |
+
assert (p1 != p2) is False
|
| 477 |
+
assert (p2 == p1) is True
|
| 478 |
+
assert (p2 != p1) is False
|
| 479 |
+
for p1, p2 in unequal_pairs:
|
| 480 |
+
assert (p1 == p2) is False
|
| 481 |
+
assert (p1 != p2) is True
|
| 482 |
+
assert (p2 == p1) is False
|
| 483 |
+
assert (p2 != p1) is True
|
| 484 |
+
|
| 485 |
+
assert S.Zero.is_zero
|
| 486 |
+
|
| 487 |
+
a = Float(2) ** Float(3)
|
| 488 |
+
assert eq(a.evalf(), Float(8))
|
| 489 |
+
assert eq((pi ** -1).evalf(), Float("0.31830988618379067"))
|
| 490 |
+
a = Float(2) ** Float(4)
|
| 491 |
+
assert eq(a.evalf(), Float(16))
|
| 492 |
+
assert (S(.3) == S(.5)) is False
|
| 493 |
+
|
| 494 |
+
mpf = (0, 5404319552844595, -52, 53)
|
| 495 |
+
x_str = Float((0, '13333333333333', -52, 53))
|
| 496 |
+
x_0xstr = Float((0, '0x13333333333333', -52, 53))
|
| 497 |
+
x2_str = Float((0, '26666666666666', -53, 54))
|
| 498 |
+
x_hex = Float((0, int(0x13333333333333), -52, 53))
|
| 499 |
+
x_dec = Float(mpf)
|
| 500 |
+
assert x_str == x_0xstr == x_hex == x_dec == Float(1.2)
|
| 501 |
+
# x2_str was entered slightly malformed in that the mantissa
|
| 502 |
+
# was even -- it should be odd and the even part should be
|
| 503 |
+
# included with the exponent, but this is resolved by normalization
|
| 504 |
+
# ONLY IF REQUIREMENTS of mpf_norm are met: the bitcount must
|
| 505 |
+
# be exact: double the mantissa ==> increase bc by 1
|
| 506 |
+
assert Float(1.2)._mpf_ == mpf
|
| 507 |
+
assert x2_str._mpf_ == mpf
|
| 508 |
+
|
| 509 |
+
assert Float((0, int(0), -123, -1)) is S.NaN
|
| 510 |
+
assert Float((0, int(0), -456, -2)) is S.Infinity
|
| 511 |
+
assert Float((1, int(0), -789, -3)) is S.NegativeInfinity
|
| 512 |
+
# if you don't give the full signature, it's not special
|
| 513 |
+
assert Float((0, int(0), -123)) == Float(0)
|
| 514 |
+
assert Float((0, int(0), -456)) == Float(0)
|
| 515 |
+
assert Float((1, int(0), -789)) == Float(0)
|
| 516 |
+
|
| 517 |
+
raises(ValueError, lambda: Float((0, 7, 1, 3), ''))
|
| 518 |
+
|
| 519 |
+
assert Float('0.0').is_finite is True
|
| 520 |
+
assert Float('0.0').is_negative is False
|
| 521 |
+
assert Float('0.0').is_positive is False
|
| 522 |
+
assert Float('0.0').is_infinite is False
|
| 523 |
+
assert Float('0.0').is_zero is True
|
| 524 |
+
|
| 525 |
+
# rationality properties
|
| 526 |
+
# if the integer test fails then the use of intlike
|
| 527 |
+
# should be removed from gamma_functions.py
|
| 528 |
+
assert Float(1).is_integer is None
|
| 529 |
+
assert Float(1).is_rational is None
|
| 530 |
+
assert Float(1).is_irrational is None
|
| 531 |
+
assert sqrt(2).n(15).is_rational is None
|
| 532 |
+
assert sqrt(2).n(15).is_irrational is None
|
| 533 |
+
|
| 534 |
+
# do not automatically evalf
|
| 535 |
+
def teq(a):
|
| 536 |
+
assert (a.evalf() == a) is False
|
| 537 |
+
assert (a.evalf() != a) is True
|
| 538 |
+
assert (a == a.evalf()) is False
|
| 539 |
+
assert (a != a.evalf()) is True
|
| 540 |
+
|
| 541 |
+
teq(pi)
|
| 542 |
+
teq(2*pi)
|
| 543 |
+
teq(cos(0.1, evaluate=False))
|
| 544 |
+
|
| 545 |
+
# long integer
|
| 546 |
+
i = 12345678901234567890
|
| 547 |
+
assert same_and_same_prec(Float(12, ''), Float('12', ''))
|
| 548 |
+
assert same_and_same_prec(Float(Integer(i), ''), Float(i, ''))
|
| 549 |
+
assert same_and_same_prec(Float(i, ''), Float(str(i), 20))
|
| 550 |
+
assert same_and_same_prec(Float(str(i)), Float(i, ''))
|
| 551 |
+
assert same_and_same_prec(Float(i), Float(i, ''))
|
| 552 |
+
|
| 553 |
+
# inexact floats (repeating binary = denom not multiple of 2)
|
| 554 |
+
# cannot have precision greater than 15
|
| 555 |
+
assert Float(.125, 22)._prec == 76
|
| 556 |
+
assert Float(2.0, 22)._prec == 76
|
| 557 |
+
# only default prec is equal, even for exactly representable float
|
| 558 |
+
assert Float(.125, 22) != .125
|
| 559 |
+
#assert Float(2.0, 22) == 2
|
| 560 |
+
assert float(Float('.12500000000000001', '')) == .125
|
| 561 |
+
raises(ValueError, lambda: Float(.12500000000000001, ''))
|
| 562 |
+
|
| 563 |
+
# allow spaces
|
| 564 |
+
assert Float('123 456.123 456') == Float('123456.123456')
|
| 565 |
+
assert Integer('123 456') == Integer('123456')
|
| 566 |
+
assert Rational('123 456.123 456') == Rational('123456.123456')
|
| 567 |
+
assert Float(' .3e2') == Float('0.3e2')
|
| 568 |
+
# but treat them as strictly ass underscore between digits: only 1
|
| 569 |
+
raises(ValueError, lambda: Float('1 2'))
|
| 570 |
+
|
| 571 |
+
# allow underscore between digits
|
| 572 |
+
assert Float('1_23.4_56') == Float('123.456')
|
| 573 |
+
# assert Float('1_23.4_5_6', 12) == Float('123.456', 12)
|
| 574 |
+
# ...but not in all cases (per Py 3.6)
|
| 575 |
+
raises(ValueError, lambda: Float('1_'))
|
| 576 |
+
raises(ValueError, lambda: Float('1__2'))
|
| 577 |
+
raises(ValueError, lambda: Float('_1'))
|
| 578 |
+
raises(ValueError, lambda: Float('_inf'))
|
| 579 |
+
|
| 580 |
+
# allow auto precision detection
|
| 581 |
+
assert Float('.1', '') == Float(.1, 1)
|
| 582 |
+
assert Float('.125', '') == Float(.125, 3)
|
| 583 |
+
assert Float('.100', '') == Float(.1, 3)
|
| 584 |
+
assert Float('2.0', '') == Float('2', 2)
|
| 585 |
+
|
| 586 |
+
raises(ValueError, lambda: Float("12.3d-4", ""))
|
| 587 |
+
raises(ValueError, lambda: Float(12.3, ""))
|
| 588 |
+
raises(ValueError, lambda: Float('.'))
|
| 589 |
+
raises(ValueError, lambda: Float('-.'))
|
| 590 |
+
|
| 591 |
+
zero = Float('0.0')
|
| 592 |
+
assert Float('-0') == zero
|
| 593 |
+
assert Float('.0') == zero
|
| 594 |
+
assert Float('-.0') == zero
|
| 595 |
+
assert Float('-0.0') == zero
|
| 596 |
+
assert Float(0.0) == zero
|
| 597 |
+
assert Float(0) == zero
|
| 598 |
+
assert Float(0, '') == Float('0', '')
|
| 599 |
+
assert Float(1) == Float(1.0)
|
| 600 |
+
assert Float(S.Zero) == zero
|
| 601 |
+
assert Float(S.One) == Float(1.0)
|
| 602 |
+
|
| 603 |
+
assert Float(decimal.Decimal('0.1'), 3) == Float('.1', 3)
|
| 604 |
+
assert Float(decimal.Decimal('nan')) is S.NaN
|
| 605 |
+
assert Float(decimal.Decimal('Infinity')) is S.Infinity
|
| 606 |
+
assert Float(decimal.Decimal('-Infinity')) is S.NegativeInfinity
|
| 607 |
+
|
| 608 |
+
assert '{:.3f}'.format(Float(4.236622)) == '4.237'
|
| 609 |
+
assert '{:.35f}'.format(Float(pi.n(40), 40)) == \
|
| 610 |
+
'3.14159265358979323846264338327950288'
|
| 611 |
+
|
| 612 |
+
# unicode
|
| 613 |
+
assert Float('0.73908513321516064100000000') == \
|
| 614 |
+
Float('0.73908513321516064100000000')
|
| 615 |
+
assert Float('0.73908513321516064100000000', 28) == \
|
| 616 |
+
Float('0.73908513321516064100000000', 28)
|
| 617 |
+
|
| 618 |
+
# binary precision
|
| 619 |
+
# Decimal value 0.1 cannot be expressed precisely as a base 2 fraction
|
| 620 |
+
a = Float(S.One/10, dps=15)
|
| 621 |
+
b = Float(S.One/10, dps=16)
|
| 622 |
+
p = Float(S.One/10, precision=53)
|
| 623 |
+
q = Float(S.One/10, precision=54)
|
| 624 |
+
assert a._mpf_ == p._mpf_
|
| 625 |
+
assert not a._mpf_ == q._mpf_
|
| 626 |
+
assert not b._mpf_ == q._mpf_
|
| 627 |
+
|
| 628 |
+
# Precision specifying errors
|
| 629 |
+
raises(ValueError, lambda: Float("1.23", dps=3, precision=10))
|
| 630 |
+
raises(ValueError, lambda: Float("1.23", dps="", precision=10))
|
| 631 |
+
raises(ValueError, lambda: Float("1.23", dps=3, precision=""))
|
| 632 |
+
raises(ValueError, lambda: Float("1.23", dps="", precision=""))
|
| 633 |
+
|
| 634 |
+
# from NumberSymbol
|
| 635 |
+
assert same_and_same_prec(Float(pi, 32), pi.evalf(32))
|
| 636 |
+
assert same_and_same_prec(Float(Catalan), Catalan.evalf())
|
| 637 |
+
|
| 638 |
+
# oo and nan
|
| 639 |
+
u = ['inf', '-inf', 'nan', 'iNF', '+inf']
|
| 640 |
+
v = [oo, -oo, nan, oo, oo]
|
| 641 |
+
for i, a in zip(u, v):
|
| 642 |
+
assert Float(i) is a
|
| 643 |
+
|
| 644 |
+
|
| 645 |
+
def test_zero_not_false():
|
| 646 |
+
# https://github.com/sympy/sympy/issues/20796
|
| 647 |
+
assert (S(0.0) == S.false) is False
|
| 648 |
+
assert (S.false == S(0.0)) is False
|
| 649 |
+
assert (S(0) == S.false) is False
|
| 650 |
+
assert (S.false == S(0)) is False
|
| 651 |
+
|
| 652 |
+
|
| 653 |
+
@conserve_mpmath_dps
|
| 654 |
+
def test_float_mpf():
|
| 655 |
+
import mpmath
|
| 656 |
+
mpmath.mp.dps = 100
|
| 657 |
+
mp_pi = mpmath.pi()
|
| 658 |
+
|
| 659 |
+
assert Float(mp_pi, 100) == Float(mp_pi._mpf_, 100) == pi.evalf(100)
|
| 660 |
+
|
| 661 |
+
mpmath.mp.dps = 15
|
| 662 |
+
|
| 663 |
+
assert Float(mp_pi, 100) == Float(mp_pi._mpf_, 100) == pi.evalf(100)
|
| 664 |
+
|
| 665 |
+
|
| 666 |
+
def test_Float_RealElement():
|
| 667 |
+
repi = RealField(dps=100)(pi.evalf(100))
|
| 668 |
+
# We still have to pass the precision because Float doesn't know what
|
| 669 |
+
# RealElement is, but make sure it keeps full precision from the result.
|
| 670 |
+
assert Float(repi, 100) == pi.evalf(100)
|
| 671 |
+
|
| 672 |
+
|
| 673 |
+
def test_Float_default_to_highprec_from_str():
|
| 674 |
+
s = str(pi.evalf(128))
|
| 675 |
+
assert same_and_same_prec(Float(s), Float(s, ''))
|
| 676 |
+
|
| 677 |
+
|
| 678 |
+
def test_Float_eval():
|
| 679 |
+
a = Float(3.2)
|
| 680 |
+
assert (a**2).is_Float
|
| 681 |
+
|
| 682 |
+
|
| 683 |
+
def test_Float_issue_2107():
|
| 684 |
+
a = Float(0.1, 10)
|
| 685 |
+
b = Float("0.1", 10)
|
| 686 |
+
|
| 687 |
+
assert a - a == 0
|
| 688 |
+
assert a + (-a) == 0
|
| 689 |
+
assert S.Zero + a - a == 0
|
| 690 |
+
assert S.Zero + a + (-a) == 0
|
| 691 |
+
|
| 692 |
+
assert b - b == 0
|
| 693 |
+
assert b + (-b) == 0
|
| 694 |
+
assert S.Zero + b - b == 0
|
| 695 |
+
assert S.Zero + b + (-b) == 0
|
| 696 |
+
|
| 697 |
+
|
| 698 |
+
def test_issue_14289():
|
| 699 |
+
from sympy.polys.numberfields import to_number_field
|
| 700 |
+
|
| 701 |
+
a = 1 - sqrt(2)
|
| 702 |
+
b = to_number_field(a)
|
| 703 |
+
assert b.as_expr() == a
|
| 704 |
+
assert b.minpoly(a).expand() == 0
|
| 705 |
+
|
| 706 |
+
|
| 707 |
+
def test_Float_from_tuple():
|
| 708 |
+
a = Float((0, '1L', 0, 1))
|
| 709 |
+
b = Float((0, '1', 0, 1))
|
| 710 |
+
assert a == b
|
| 711 |
+
|
| 712 |
+
|
| 713 |
+
def test_Infinity():
|
| 714 |
+
assert oo != 1
|
| 715 |
+
assert 1*oo is oo
|
| 716 |
+
assert 1 != oo
|
| 717 |
+
assert oo != -oo
|
| 718 |
+
assert oo != Symbol("x")**3
|
| 719 |
+
assert oo + 1 is oo
|
| 720 |
+
assert 2 + oo is oo
|
| 721 |
+
assert 3*oo + 2 is oo
|
| 722 |
+
assert S.Half**oo == 0
|
| 723 |
+
assert S.Half**(-oo) is oo
|
| 724 |
+
assert -oo*3 is -oo
|
| 725 |
+
assert oo + oo is oo
|
| 726 |
+
assert -oo + oo*(-5) is -oo
|
| 727 |
+
assert 1/oo == 0
|
| 728 |
+
assert 1/(-oo) == 0
|
| 729 |
+
assert 8/oo == 0
|
| 730 |
+
assert oo % 2 is nan
|
| 731 |
+
assert 2 % oo is nan
|
| 732 |
+
assert oo/oo is nan
|
| 733 |
+
assert oo/-oo is nan
|
| 734 |
+
assert -oo/oo is nan
|
| 735 |
+
assert -oo/-oo is nan
|
| 736 |
+
assert oo - oo is nan
|
| 737 |
+
assert oo - -oo is oo
|
| 738 |
+
assert -oo - oo is -oo
|
| 739 |
+
assert -oo - -oo is nan
|
| 740 |
+
assert oo + -oo is nan
|
| 741 |
+
assert -oo + oo is nan
|
| 742 |
+
assert oo + oo is oo
|
| 743 |
+
assert -oo + oo is nan
|
| 744 |
+
assert oo + -oo is nan
|
| 745 |
+
assert -oo + -oo is -oo
|
| 746 |
+
assert oo*oo is oo
|
| 747 |
+
assert -oo*oo is -oo
|
| 748 |
+
assert oo*-oo is -oo
|
| 749 |
+
assert -oo*-oo is oo
|
| 750 |
+
assert oo/0 is oo
|
| 751 |
+
assert -oo/0 is -oo
|
| 752 |
+
assert 0/oo == 0
|
| 753 |
+
assert 0/-oo == 0
|
| 754 |
+
assert oo*0 is nan
|
| 755 |
+
assert -oo*0 is nan
|
| 756 |
+
assert 0*oo is nan
|
| 757 |
+
assert 0*-oo is nan
|
| 758 |
+
assert oo + 0 is oo
|
| 759 |
+
assert -oo + 0 is -oo
|
| 760 |
+
assert 0 + oo is oo
|
| 761 |
+
assert 0 + -oo is -oo
|
| 762 |
+
assert oo - 0 is oo
|
| 763 |
+
assert -oo - 0 is -oo
|
| 764 |
+
assert 0 - oo is -oo
|
| 765 |
+
assert 0 - -oo is oo
|
| 766 |
+
assert oo/2 is oo
|
| 767 |
+
assert -oo/2 is -oo
|
| 768 |
+
assert oo/-2 is -oo
|
| 769 |
+
assert -oo/-2 is oo
|
| 770 |
+
assert oo*2 is oo
|
| 771 |
+
assert -oo*2 is -oo
|
| 772 |
+
assert oo*-2 is -oo
|
| 773 |
+
assert 2/oo == 0
|
| 774 |
+
assert 2/-oo == 0
|
| 775 |
+
assert -2/oo == 0
|
| 776 |
+
assert -2/-oo == 0
|
| 777 |
+
assert 2*oo is oo
|
| 778 |
+
assert 2*-oo is -oo
|
| 779 |
+
assert -2*oo is -oo
|
| 780 |
+
assert -2*-oo is oo
|
| 781 |
+
assert 2 + oo is oo
|
| 782 |
+
assert 2 - oo is -oo
|
| 783 |
+
assert -2 + oo is oo
|
| 784 |
+
assert -2 - oo is -oo
|
| 785 |
+
assert 2 + -oo is -oo
|
| 786 |
+
assert 2 - -oo is oo
|
| 787 |
+
assert -2 + -oo is -oo
|
| 788 |
+
assert -2 - -oo is oo
|
| 789 |
+
assert S(2) + oo is oo
|
| 790 |
+
assert S(2) - oo is -oo
|
| 791 |
+
assert oo/I == -oo*I
|
| 792 |
+
assert -oo/I == oo*I
|
| 793 |
+
assert oo*float(1) == _inf and (oo*float(1)) is oo
|
| 794 |
+
assert -oo*float(1) == _ninf and (-oo*float(1)) is -oo
|
| 795 |
+
assert oo/float(1) == _inf and (oo/float(1)) is oo
|
| 796 |
+
assert -oo/float(1) == _ninf and (-oo/float(1)) is -oo
|
| 797 |
+
assert oo*float(-1) == _ninf and (oo*float(-1)) is -oo
|
| 798 |
+
assert -oo*float(-1) == _inf and (-oo*float(-1)) is oo
|
| 799 |
+
assert oo/float(-1) == _ninf and (oo/float(-1)) is -oo
|
| 800 |
+
assert -oo/float(-1) == _inf and (-oo/float(-1)) is oo
|
| 801 |
+
assert oo + float(1) == _inf and (oo + float(1)) is oo
|
| 802 |
+
assert -oo + float(1) == _ninf and (-oo + float(1)) is -oo
|
| 803 |
+
assert oo - float(1) == _inf and (oo - float(1)) is oo
|
| 804 |
+
assert -oo - float(1) == _ninf and (-oo - float(1)) is -oo
|
| 805 |
+
assert float(1)*oo == _inf and (float(1)*oo) is oo
|
| 806 |
+
assert float(1)*-oo == _ninf and (float(1)*-oo) is -oo
|
| 807 |
+
assert float(1)/oo == 0
|
| 808 |
+
assert float(1)/-oo == 0
|
| 809 |
+
assert float(-1)*oo == _ninf and (float(-1)*oo) is -oo
|
| 810 |
+
assert float(-1)*-oo == _inf and (float(-1)*-oo) is oo
|
| 811 |
+
assert float(-1)/oo == 0
|
| 812 |
+
assert float(-1)/-oo == 0
|
| 813 |
+
assert float(1) + oo is oo
|
| 814 |
+
assert float(1) + -oo is -oo
|
| 815 |
+
assert float(1) - oo is -oo
|
| 816 |
+
assert float(1) - -oo is oo
|
| 817 |
+
assert oo == float(oo)
|
| 818 |
+
assert (oo != float(oo)) is False
|
| 819 |
+
assert type(float(oo)) is float
|
| 820 |
+
assert -oo == float(-oo)
|
| 821 |
+
assert (-oo != float(-oo)) is False
|
| 822 |
+
assert type(float(-oo)) is float
|
| 823 |
+
|
| 824 |
+
assert Float('nan') is nan
|
| 825 |
+
assert nan*1.0 is nan
|
| 826 |
+
assert -1.0*nan is nan
|
| 827 |
+
assert nan*oo is nan
|
| 828 |
+
assert nan*-oo is nan
|
| 829 |
+
assert nan/oo is nan
|
| 830 |
+
assert nan/-oo is nan
|
| 831 |
+
assert nan + oo is nan
|
| 832 |
+
assert nan + -oo is nan
|
| 833 |
+
assert nan - oo is nan
|
| 834 |
+
assert nan - -oo is nan
|
| 835 |
+
assert -oo * S.Zero is nan
|
| 836 |
+
|
| 837 |
+
assert oo*nan is nan
|
| 838 |
+
assert -oo*nan is nan
|
| 839 |
+
assert oo/nan is nan
|
| 840 |
+
assert -oo/nan is nan
|
| 841 |
+
assert oo + nan is nan
|
| 842 |
+
assert -oo + nan is nan
|
| 843 |
+
assert oo - nan is nan
|
| 844 |
+
assert -oo - nan is nan
|
| 845 |
+
assert S.Zero * oo is nan
|
| 846 |
+
assert oo.is_Rational is False
|
| 847 |
+
assert isinstance(oo, Rational) is False
|
| 848 |
+
|
| 849 |
+
assert S.One/oo == 0
|
| 850 |
+
assert -S.One/oo == 0
|
| 851 |
+
assert S.One/-oo == 0
|
| 852 |
+
assert -S.One/-oo == 0
|
| 853 |
+
assert S.One*oo is oo
|
| 854 |
+
assert -S.One*oo is -oo
|
| 855 |
+
assert S.One*-oo is -oo
|
| 856 |
+
assert -S.One*-oo is oo
|
| 857 |
+
assert S.One/nan is nan
|
| 858 |
+
assert S.One - -oo is oo
|
| 859 |
+
assert S.One + nan is nan
|
| 860 |
+
assert S.One - nan is nan
|
| 861 |
+
assert nan - S.One is nan
|
| 862 |
+
assert nan/S.One is nan
|
| 863 |
+
assert -oo - S.One is -oo
|
| 864 |
+
|
| 865 |
+
|
| 866 |
+
def test_Infinity_2():
|
| 867 |
+
x = Symbol('x')
|
| 868 |
+
assert oo*x != oo
|
| 869 |
+
assert oo*(pi - 1) is oo
|
| 870 |
+
assert oo*(1 - pi) is -oo
|
| 871 |
+
|
| 872 |
+
assert (-oo)*x != -oo
|
| 873 |
+
assert (-oo)*(pi - 1) is -oo
|
| 874 |
+
assert (-oo)*(1 - pi) is oo
|
| 875 |
+
|
| 876 |
+
assert (-1)**S.NaN is S.NaN
|
| 877 |
+
assert oo - _inf is S.NaN
|
| 878 |
+
assert oo + _ninf is S.NaN
|
| 879 |
+
assert oo*0 is S.NaN
|
| 880 |
+
assert oo/_inf is S.NaN
|
| 881 |
+
assert oo/_ninf is S.NaN
|
| 882 |
+
assert oo**S.NaN is S.NaN
|
| 883 |
+
assert -oo + _inf is S.NaN
|
| 884 |
+
assert -oo - _ninf is S.NaN
|
| 885 |
+
assert -oo*S.NaN is S.NaN
|
| 886 |
+
assert -oo*0 is S.NaN
|
| 887 |
+
assert -oo/_inf is S.NaN
|
| 888 |
+
assert -oo/_ninf is S.NaN
|
| 889 |
+
assert -oo/S.NaN is S.NaN
|
| 890 |
+
assert abs(-oo) is oo
|
| 891 |
+
assert all((-oo)**i is S.NaN for i in (oo, -oo, S.NaN))
|
| 892 |
+
assert (-oo)**3 is -oo
|
| 893 |
+
assert (-oo)**2 is oo
|
| 894 |
+
assert abs(S.ComplexInfinity) is oo
|
| 895 |
+
|
| 896 |
+
|
| 897 |
+
def test_Mul_Infinity_Zero():
|
| 898 |
+
assert Float(0)*_inf is nan
|
| 899 |
+
assert Float(0)*_ninf is nan
|
| 900 |
+
assert Float(0)*_inf is nan
|
| 901 |
+
assert Float(0)*_ninf is nan
|
| 902 |
+
assert _inf*Float(0) is nan
|
| 903 |
+
assert _ninf*Float(0) is nan
|
| 904 |
+
assert _inf*Float(0) is nan
|
| 905 |
+
assert _ninf*Float(0) is nan
|
| 906 |
+
|
| 907 |
+
|
| 908 |
+
def test_Div_By_Zero():
|
| 909 |
+
assert 1/S.Zero is zoo
|
| 910 |
+
assert 1/Float(0) is zoo
|
| 911 |
+
assert 0/S.Zero is nan
|
| 912 |
+
assert 0/Float(0) is nan
|
| 913 |
+
assert S.Zero/0 is nan
|
| 914 |
+
assert Float(0)/0 is nan
|
| 915 |
+
assert -1/S.Zero is zoo
|
| 916 |
+
assert -1/Float(0) is zoo
|
| 917 |
+
|
| 918 |
+
|
| 919 |
+
@_both_exp_pow
|
| 920 |
+
def test_Infinity_inequations():
|
| 921 |
+
assert oo > pi
|
| 922 |
+
assert not (oo < pi)
|
| 923 |
+
assert exp(-3) < oo
|
| 924 |
+
|
| 925 |
+
assert _inf > pi
|
| 926 |
+
assert not (_inf < pi)
|
| 927 |
+
assert exp(-3) < _inf
|
| 928 |
+
|
| 929 |
+
raises(TypeError, lambda: oo < I)
|
| 930 |
+
raises(TypeError, lambda: oo <= I)
|
| 931 |
+
raises(TypeError, lambda: oo > I)
|
| 932 |
+
raises(TypeError, lambda: oo >= I)
|
| 933 |
+
raises(TypeError, lambda: -oo < I)
|
| 934 |
+
raises(TypeError, lambda: -oo <= I)
|
| 935 |
+
raises(TypeError, lambda: -oo > I)
|
| 936 |
+
raises(TypeError, lambda: -oo >= I)
|
| 937 |
+
|
| 938 |
+
raises(TypeError, lambda: I < oo)
|
| 939 |
+
raises(TypeError, lambda: I <= oo)
|
| 940 |
+
raises(TypeError, lambda: I > oo)
|
| 941 |
+
raises(TypeError, lambda: I >= oo)
|
| 942 |
+
raises(TypeError, lambda: I < -oo)
|
| 943 |
+
raises(TypeError, lambda: I <= -oo)
|
| 944 |
+
raises(TypeError, lambda: I > -oo)
|
| 945 |
+
raises(TypeError, lambda: I >= -oo)
|
| 946 |
+
|
| 947 |
+
assert oo > -oo and oo >= -oo
|
| 948 |
+
assert (oo < -oo) == False and (oo <= -oo) == False
|
| 949 |
+
assert -oo < oo and -oo <= oo
|
| 950 |
+
assert (-oo > oo) == False and (-oo >= oo) == False
|
| 951 |
+
|
| 952 |
+
assert (oo < oo) == False # issue 7775
|
| 953 |
+
assert (oo > oo) == False
|
| 954 |
+
assert (-oo > -oo) == False and (-oo < -oo) == False
|
| 955 |
+
assert oo >= oo and oo <= oo and -oo >= -oo and -oo <= -oo
|
| 956 |
+
assert (-oo < -_inf) == False
|
| 957 |
+
assert (oo > _inf) == False
|
| 958 |
+
assert -oo >= -_inf
|
| 959 |
+
assert oo <= _inf
|
| 960 |
+
|
| 961 |
+
x = Symbol('x')
|
| 962 |
+
b = Symbol('b', finite=True, real=True)
|
| 963 |
+
assert (x < oo) == Lt(x, oo) # issue 7775
|
| 964 |
+
assert b < oo and b > -oo and b <= oo and b >= -oo
|
| 965 |
+
assert oo > b and oo >= b and (oo < b) == False and (oo <= b) == False
|
| 966 |
+
assert (-oo > b) == False and (-oo >= b) == False and -oo < b and -oo <= b
|
| 967 |
+
assert (oo < x) == Lt(oo, x) and (oo > x) == Gt(oo, x)
|
| 968 |
+
assert (oo <= x) == Le(oo, x) and (oo >= x) == Ge(oo, x)
|
| 969 |
+
assert (-oo < x) == Lt(-oo, x) and (-oo > x) == Gt(-oo, x)
|
| 970 |
+
assert (-oo <= x) == Le(-oo, x) and (-oo >= x) == Ge(-oo, x)
|
| 971 |
+
|
| 972 |
+
|
| 973 |
+
def test_NaN():
|
| 974 |
+
assert nan is nan
|
| 975 |
+
assert nan != 1
|
| 976 |
+
assert 1*nan is nan
|
| 977 |
+
assert 1 != nan
|
| 978 |
+
assert -nan is nan
|
| 979 |
+
assert oo != Symbol("x")**3
|
| 980 |
+
assert 2 + nan is nan
|
| 981 |
+
assert 3*nan + 2 is nan
|
| 982 |
+
assert -nan*3 is nan
|
| 983 |
+
assert nan + nan is nan
|
| 984 |
+
assert -nan + nan*(-5) is nan
|
| 985 |
+
assert 8/nan is nan
|
| 986 |
+
raises(TypeError, lambda: nan > 0)
|
| 987 |
+
raises(TypeError, lambda: nan < 0)
|
| 988 |
+
raises(TypeError, lambda: nan >= 0)
|
| 989 |
+
raises(TypeError, lambda: nan <= 0)
|
| 990 |
+
raises(TypeError, lambda: 0 < nan)
|
| 991 |
+
raises(TypeError, lambda: 0 > nan)
|
| 992 |
+
raises(TypeError, lambda: 0 <= nan)
|
| 993 |
+
raises(TypeError, lambda: 0 >= nan)
|
| 994 |
+
assert nan**0 == 1 # as per IEEE 754
|
| 995 |
+
assert 1**nan is nan # IEEE 754 is not the best choice for symbolic work
|
| 996 |
+
# test Pow._eval_power's handling of NaN
|
| 997 |
+
assert Pow(nan, 0, evaluate=False)**2 == 1
|
| 998 |
+
for n in (1, 1., S.One, S.NegativeOne, Float(1)):
|
| 999 |
+
assert n + nan is nan
|
| 1000 |
+
assert n - nan is nan
|
| 1001 |
+
assert nan + n is nan
|
| 1002 |
+
assert nan - n is nan
|
| 1003 |
+
assert n/nan is nan
|
| 1004 |
+
assert nan/n is nan
|
| 1005 |
+
|
| 1006 |
+
|
| 1007 |
+
def test_special_numbers():
|
| 1008 |
+
assert isinstance(S.NaN, Number) is True
|
| 1009 |
+
assert isinstance(S.Infinity, Number) is True
|
| 1010 |
+
assert isinstance(S.NegativeInfinity, Number) is True
|
| 1011 |
+
|
| 1012 |
+
assert S.NaN.is_number is True
|
| 1013 |
+
assert S.Infinity.is_number is True
|
| 1014 |
+
assert S.NegativeInfinity.is_number is True
|
| 1015 |
+
assert S.ComplexInfinity.is_number is True
|
| 1016 |
+
|
| 1017 |
+
assert isinstance(S.NaN, Rational) is False
|
| 1018 |
+
assert isinstance(S.Infinity, Rational) is False
|
| 1019 |
+
assert isinstance(S.NegativeInfinity, Rational) is False
|
| 1020 |
+
|
| 1021 |
+
assert S.NaN.is_rational is not True
|
| 1022 |
+
assert S.Infinity.is_rational is not True
|
| 1023 |
+
assert S.NegativeInfinity.is_rational is not True
|
| 1024 |
+
|
| 1025 |
+
|
| 1026 |
+
def test_powers():
|
| 1027 |
+
assert integer_nthroot(1, 2) == (1, True)
|
| 1028 |
+
assert integer_nthroot(1, 5) == (1, True)
|
| 1029 |
+
assert integer_nthroot(2, 1) == (2, True)
|
| 1030 |
+
assert integer_nthroot(2, 2) == (1, False)
|
| 1031 |
+
assert integer_nthroot(2, 5) == (1, False)
|
| 1032 |
+
assert integer_nthroot(4, 2) == (2, True)
|
| 1033 |
+
assert integer_nthroot(123**25, 25) == (123, True)
|
| 1034 |
+
assert integer_nthroot(123**25 + 1, 25) == (123, False)
|
| 1035 |
+
assert integer_nthroot(123**25 - 1, 25) == (122, False)
|
| 1036 |
+
assert integer_nthroot(1, 1) == (1, True)
|
| 1037 |
+
assert integer_nthroot(0, 1) == (0, True)
|
| 1038 |
+
assert integer_nthroot(0, 3) == (0, True)
|
| 1039 |
+
assert integer_nthroot(10000, 1) == (10000, True)
|
| 1040 |
+
assert integer_nthroot(4, 2) == (2, True)
|
| 1041 |
+
assert integer_nthroot(16, 2) == (4, True)
|
| 1042 |
+
assert integer_nthroot(26, 2) == (5, False)
|
| 1043 |
+
assert integer_nthroot(1234567**7, 7) == (1234567, True)
|
| 1044 |
+
assert integer_nthroot(1234567**7 + 1, 7) == (1234567, False)
|
| 1045 |
+
assert integer_nthroot(1234567**7 - 1, 7) == (1234566, False)
|
| 1046 |
+
b = 25**1000
|
| 1047 |
+
assert integer_nthroot(b, 1000) == (25, True)
|
| 1048 |
+
assert integer_nthroot(b + 1, 1000) == (25, False)
|
| 1049 |
+
assert integer_nthroot(b - 1, 1000) == (24, False)
|
| 1050 |
+
c = 10**400
|
| 1051 |
+
c2 = c**2
|
| 1052 |
+
assert integer_nthroot(c2, 2) == (c, True)
|
| 1053 |
+
assert integer_nthroot(c2 + 1, 2) == (c, False)
|
| 1054 |
+
assert integer_nthroot(c2 - 1, 2) == (c - 1, False)
|
| 1055 |
+
assert integer_nthroot(2, 10**10) == (1, False)
|
| 1056 |
+
|
| 1057 |
+
p, r = integer_nthroot(int(factorial(10000)), 100)
|
| 1058 |
+
assert p % (10**10) == 5322420655
|
| 1059 |
+
assert not r
|
| 1060 |
+
|
| 1061 |
+
# Test that this is fast
|
| 1062 |
+
assert integer_nthroot(2, 10**10) == (1, False)
|
| 1063 |
+
|
| 1064 |
+
# output should be int if possible
|
| 1065 |
+
assert type(integer_nthroot(2**61, 2)[0]) is int
|
| 1066 |
+
|
| 1067 |
+
|
| 1068 |
+
def test_integer_nthroot_overflow():
|
| 1069 |
+
assert integer_nthroot(10**(50*50), 50) == (10**50, True)
|
| 1070 |
+
assert integer_nthroot(10**100000, 10000) == (10**10, True)
|
| 1071 |
+
|
| 1072 |
+
|
| 1073 |
+
def test_integer_log():
|
| 1074 |
+
raises(ValueError, lambda: integer_log(2, 1))
|
| 1075 |
+
raises(ValueError, lambda: integer_log(0, 2))
|
| 1076 |
+
raises(ValueError, lambda: integer_log(1.1, 2))
|
| 1077 |
+
raises(ValueError, lambda: integer_log(1, 2.2))
|
| 1078 |
+
|
| 1079 |
+
assert integer_log(1, 2) == (0, True)
|
| 1080 |
+
assert integer_log(1, 3) == (0, True)
|
| 1081 |
+
assert integer_log(2, 3) == (0, False)
|
| 1082 |
+
assert integer_log(3, 3) == (1, True)
|
| 1083 |
+
assert integer_log(3*2, 3) == (1, False)
|
| 1084 |
+
assert integer_log(3**2, 3) == (2, True)
|
| 1085 |
+
assert integer_log(3*4, 3) == (2, False)
|
| 1086 |
+
assert integer_log(3**3, 3) == (3, True)
|
| 1087 |
+
assert integer_log(27, 5) == (2, False)
|
| 1088 |
+
assert integer_log(2, 3) == (0, False)
|
| 1089 |
+
assert integer_log(-4, 2) == (2, False)
|
| 1090 |
+
assert integer_log(-16, 4) == (0, False)
|
| 1091 |
+
assert integer_log(-4, -2) == (2, False)
|
| 1092 |
+
assert integer_log(4, -2) == (2, True)
|
| 1093 |
+
assert integer_log(-8, -2) == (3, True)
|
| 1094 |
+
assert integer_log(8, -2) == (3, False)
|
| 1095 |
+
assert integer_log(-9, 3) == (0, False)
|
| 1096 |
+
assert integer_log(-9, -3) == (2, False)
|
| 1097 |
+
assert integer_log(9, -3) == (2, True)
|
| 1098 |
+
assert integer_log(-27, -3) == (3, True)
|
| 1099 |
+
assert integer_log(27, -3) == (3, False)
|
| 1100 |
+
|
| 1101 |
+
|
| 1102 |
+
def test_isqrt():
|
| 1103 |
+
from math import sqrt as _sqrt
|
| 1104 |
+
limit = 4503599761588223
|
| 1105 |
+
assert int(_sqrt(limit)) == integer_nthroot(limit, 2)[0]
|
| 1106 |
+
assert int(_sqrt(limit + 1)) != integer_nthroot(limit + 1, 2)[0]
|
| 1107 |
+
assert isqrt(limit + 1) == integer_nthroot(limit + 1, 2)[0]
|
| 1108 |
+
assert isqrt(limit + S.Half) == integer_nthroot(limit, 2)[0]
|
| 1109 |
+
assert isqrt(limit + 1 + S.Half) == integer_nthroot(limit + 1, 2)[0]
|
| 1110 |
+
assert isqrt(limit + 2 + S.Half) == integer_nthroot(limit + 2, 2)[0]
|
| 1111 |
+
|
| 1112 |
+
# Regression tests for https://github.com/sympy/sympy/issues/17034
|
| 1113 |
+
assert isqrt(4503599761588224) == 67108864
|
| 1114 |
+
assert isqrt(9999999999999999) == 99999999
|
| 1115 |
+
|
| 1116 |
+
# Other corner cases, especially involving non-integers.
|
| 1117 |
+
raises(ValueError, lambda: isqrt(-1))
|
| 1118 |
+
raises(ValueError, lambda: isqrt(-10**1000))
|
| 1119 |
+
raises(ValueError, lambda: isqrt(Rational(-1, 2)))
|
| 1120 |
+
|
| 1121 |
+
tiny = Rational(1, 10**1000)
|
| 1122 |
+
raises(ValueError, lambda: isqrt(-tiny))
|
| 1123 |
+
assert isqrt(1-tiny) == 0
|
| 1124 |
+
assert isqrt(4503599761588224-tiny) == 67108864
|
| 1125 |
+
assert isqrt(10**100 - tiny) == 10**50 - 1
|
| 1126 |
+
|
| 1127 |
+
|
| 1128 |
+
def test_powers_Integer():
|
| 1129 |
+
"""Test Integer._eval_power"""
|
| 1130 |
+
# check infinity
|
| 1131 |
+
assert S.One ** S.Infinity is S.NaN
|
| 1132 |
+
assert S.NegativeOne** S.Infinity is S.NaN
|
| 1133 |
+
assert S(2) ** S.Infinity is S.Infinity
|
| 1134 |
+
assert S(-2)** S.Infinity == zoo
|
| 1135 |
+
assert S(0) ** S.Infinity is S.Zero
|
| 1136 |
+
|
| 1137 |
+
# check Nan
|
| 1138 |
+
assert S.One ** S.NaN is S.NaN
|
| 1139 |
+
assert S.NegativeOne ** S.NaN is S.NaN
|
| 1140 |
+
|
| 1141 |
+
# check for exact roots
|
| 1142 |
+
assert S.NegativeOne ** Rational(6, 5) == - (-1)**(S.One/5)
|
| 1143 |
+
assert sqrt(S(4)) == 2
|
| 1144 |
+
assert sqrt(S(-4)) == I * 2
|
| 1145 |
+
assert S(16) ** Rational(1, 4) == 2
|
| 1146 |
+
assert S(-16) ** Rational(1, 4) == 2 * (-1)**Rational(1, 4)
|
| 1147 |
+
assert S(9) ** Rational(3, 2) == 27
|
| 1148 |
+
assert S(-9) ** Rational(3, 2) == -27*I
|
| 1149 |
+
assert S(27) ** Rational(2, 3) == 9
|
| 1150 |
+
assert S(-27) ** Rational(2, 3) == 9 * (S.NegativeOne ** Rational(2, 3))
|
| 1151 |
+
assert (-2) ** Rational(-2, 1) == Rational(1, 4)
|
| 1152 |
+
|
| 1153 |
+
# not exact roots
|
| 1154 |
+
assert sqrt(-3) == I*sqrt(3)
|
| 1155 |
+
assert (3) ** (Rational(3, 2)) == 3 * sqrt(3)
|
| 1156 |
+
assert (-3) ** (Rational(3, 2)) == - 3 * sqrt(-3)
|
| 1157 |
+
assert (-3) ** (Rational(5, 2)) == 9 * I * sqrt(3)
|
| 1158 |
+
assert (-3) ** (Rational(7, 2)) == - I * 27 * sqrt(3)
|
| 1159 |
+
assert (2) ** (Rational(3, 2)) == 2 * sqrt(2)
|
| 1160 |
+
assert (2) ** (Rational(-3, 2)) == sqrt(2) / 4
|
| 1161 |
+
assert (81) ** (Rational(2, 3)) == 9 * (S(3) ** (Rational(2, 3)))
|
| 1162 |
+
assert (-81) ** (Rational(2, 3)) == 9 * (S(-3) ** (Rational(2, 3)))
|
| 1163 |
+
assert (-3) ** Rational(-7, 3) == \
|
| 1164 |
+
-(-1)**Rational(2, 3)*3**Rational(2, 3)/27
|
| 1165 |
+
assert (-3) ** Rational(-2, 3) == \
|
| 1166 |
+
-(-1)**Rational(1, 3)*3**Rational(1, 3)/3
|
| 1167 |
+
|
| 1168 |
+
# join roots
|
| 1169 |
+
assert sqrt(6) + sqrt(24) == 3*sqrt(6)
|
| 1170 |
+
assert sqrt(2) * sqrt(3) == sqrt(6)
|
| 1171 |
+
|
| 1172 |
+
# separate symbols & constansts
|
| 1173 |
+
x = Symbol("x")
|
| 1174 |
+
assert sqrt(49 * x) == 7 * sqrt(x)
|
| 1175 |
+
assert sqrt((3 - sqrt(pi)) ** 2) == 3 - sqrt(pi)
|
| 1176 |
+
|
| 1177 |
+
# check that it is fast for big numbers
|
| 1178 |
+
assert (2**64 + 1) ** Rational(4, 3)
|
| 1179 |
+
assert (2**64 + 1) ** Rational(17, 25)
|
| 1180 |
+
|
| 1181 |
+
# negative rational power and negative base
|
| 1182 |
+
assert (-3) ** Rational(-7, 3) == \
|
| 1183 |
+
-(-1)**Rational(2, 3)*3**Rational(2, 3)/27
|
| 1184 |
+
assert (-3) ** Rational(-2, 3) == \
|
| 1185 |
+
-(-1)**Rational(1, 3)*3**Rational(1, 3)/3
|
| 1186 |
+
assert (-2) ** Rational(-10, 3) == \
|
| 1187 |
+
(-1)**Rational(2, 3)*2**Rational(2, 3)/16
|
| 1188 |
+
assert abs(Pow(-2, Rational(-10, 3)).n() -
|
| 1189 |
+
Pow(-2, Rational(-10, 3), evaluate=False).n()) < 1e-16
|
| 1190 |
+
|
| 1191 |
+
# negative base and rational power with some simplification
|
| 1192 |
+
assert (-8) ** Rational(2, 5) == \
|
| 1193 |
+
2*(-1)**Rational(2, 5)*2**Rational(1, 5)
|
| 1194 |
+
assert (-4) ** Rational(9, 5) == \
|
| 1195 |
+
-8*(-1)**Rational(4, 5)*2**Rational(3, 5)
|
| 1196 |
+
|
| 1197 |
+
assert S(1234).factors() == {617: 1, 2: 1}
|
| 1198 |
+
assert Rational(2*3, 3*5*7).factors() == {2: 1, 5: -1, 7: -1}
|
| 1199 |
+
|
| 1200 |
+
# test that eval_power factors numbers bigger than
|
| 1201 |
+
# the current limit in factor_trial_division (2**15)
|
| 1202 |
+
from sympy.ntheory.generate import nextprime
|
| 1203 |
+
n = nextprime(2**15)
|
| 1204 |
+
assert sqrt(n**2) == n
|
| 1205 |
+
assert sqrt(n**3) == n*sqrt(n)
|
| 1206 |
+
assert sqrt(4*n) == 2*sqrt(n)
|
| 1207 |
+
|
| 1208 |
+
# check that factors of base with powers sharing gcd with power are removed
|
| 1209 |
+
assert (2**4*3)**Rational(1, 6) == 2**Rational(2, 3)*3**Rational(1, 6)
|
| 1210 |
+
assert (2**4*3)**Rational(5, 6) == 8*2**Rational(1, 3)*3**Rational(5, 6)
|
| 1211 |
+
|
| 1212 |
+
# check that bases sharing a gcd are exptracted
|
| 1213 |
+
assert 2**Rational(1, 3)*3**Rational(1, 4)*6**Rational(1, 5) == \
|
| 1214 |
+
2**Rational(8, 15)*3**Rational(9, 20)
|
| 1215 |
+
assert sqrt(8)*24**Rational(1, 3)*6**Rational(1, 5) == \
|
| 1216 |
+
4*2**Rational(7, 10)*3**Rational(8, 15)
|
| 1217 |
+
assert sqrt(8)*(-24)**Rational(1, 3)*(-6)**Rational(1, 5) == \
|
| 1218 |
+
4*(-3)**Rational(8, 15)*2**Rational(7, 10)
|
| 1219 |
+
assert 2**Rational(1, 3)*2**Rational(8, 9) == 2*2**Rational(2, 9)
|
| 1220 |
+
assert 2**Rational(2, 3)*6**Rational(1, 3) == 2*3**Rational(1, 3)
|
| 1221 |
+
assert 2**Rational(2, 3)*6**Rational(8, 9) == \
|
| 1222 |
+
2*2**Rational(5, 9)*3**Rational(8, 9)
|
| 1223 |
+
assert (-2)**Rational(2, S(3))*(-4)**Rational(1, S(3)) == -2*2**Rational(1, 3)
|
| 1224 |
+
assert 3*Pow(3, 2, evaluate=False) == 3**3
|
| 1225 |
+
assert 3*Pow(3, Rational(-1, 3), evaluate=False) == 3**Rational(2, 3)
|
| 1226 |
+
assert (-2)**Rational(1, 3)*(-3)**Rational(1, 4)*(-5)**Rational(5, 6) == \
|
| 1227 |
+
-(-1)**Rational(5, 12)*2**Rational(1, 3)*3**Rational(1, 4) * \
|
| 1228 |
+
5**Rational(5, 6)
|
| 1229 |
+
|
| 1230 |
+
assert Integer(-2)**Symbol('', even=True) == \
|
| 1231 |
+
Integer(2)**Symbol('', even=True)
|
| 1232 |
+
assert (-1)**Float(.5) == 1.0*I
|
| 1233 |
+
|
| 1234 |
+
|
| 1235 |
+
def test_powers_Rational():
|
| 1236 |
+
"""Test Rational._eval_power"""
|
| 1237 |
+
# check infinity
|
| 1238 |
+
assert S.Half ** S.Infinity == 0
|
| 1239 |
+
assert Rational(3, 2) ** S.Infinity is S.Infinity
|
| 1240 |
+
assert Rational(-1, 2) ** S.Infinity == 0
|
| 1241 |
+
assert Rational(-3, 2) ** S.Infinity == zoo
|
| 1242 |
+
|
| 1243 |
+
# check Nan
|
| 1244 |
+
assert Rational(3, 4) ** S.NaN is S.NaN
|
| 1245 |
+
assert Rational(-2, 3) ** S.NaN is S.NaN
|
| 1246 |
+
|
| 1247 |
+
# exact roots on numerator
|
| 1248 |
+
assert sqrt(Rational(4, 3)) == 2 * sqrt(3) / 3
|
| 1249 |
+
assert Rational(4, 3) ** Rational(3, 2) == 8 * sqrt(3) / 9
|
| 1250 |
+
assert sqrt(Rational(-4, 3)) == I * 2 * sqrt(3) / 3
|
| 1251 |
+
assert Rational(-4, 3) ** Rational(3, 2) == - I * 8 * sqrt(3) / 9
|
| 1252 |
+
assert Rational(27, 2) ** Rational(1, 3) == 3 * (2 ** Rational(2, 3)) / 2
|
| 1253 |
+
assert Rational(5**3, 8**3) ** Rational(4, 3) == Rational(5**4, 8**4)
|
| 1254 |
+
|
| 1255 |
+
# exact root on denominator
|
| 1256 |
+
assert sqrt(Rational(1, 4)) == S.Half
|
| 1257 |
+
assert sqrt(Rational(1, -4)) == I * S.Half
|
| 1258 |
+
assert sqrt(Rational(3, 4)) == sqrt(3) / 2
|
| 1259 |
+
assert sqrt(Rational(3, -4)) == I * sqrt(3) / 2
|
| 1260 |
+
assert Rational(5, 27) ** Rational(1, 3) == (5 ** Rational(1, 3)) / 3
|
| 1261 |
+
|
| 1262 |
+
# not exact roots
|
| 1263 |
+
assert sqrt(S.Half) == sqrt(2) / 2
|
| 1264 |
+
assert sqrt(Rational(-4, 7)) == I * sqrt(Rational(4, 7))
|
| 1265 |
+
assert Rational(-3, 2)**Rational(-7, 3) == \
|
| 1266 |
+
-4*(-1)**Rational(2, 3)*2**Rational(1, 3)*3**Rational(2, 3)/27
|
| 1267 |
+
assert Rational(-3, 2)**Rational(-2, 3) == \
|
| 1268 |
+
-(-1)**Rational(1, 3)*2**Rational(2, 3)*3**Rational(1, 3)/3
|
| 1269 |
+
assert Rational(-3, 2)**Rational(-10, 3) == \
|
| 1270 |
+
8*(-1)**Rational(2, 3)*2**Rational(1, 3)*3**Rational(2, 3)/81
|
| 1271 |
+
assert abs(Pow(Rational(-2, 3), Rational(-7, 4)).n() -
|
| 1272 |
+
Pow(Rational(-2, 3), Rational(-7, 4), evaluate=False).n()) < 1e-16
|
| 1273 |
+
|
| 1274 |
+
# negative integer power and negative rational base
|
| 1275 |
+
assert Rational(-2, 3) ** Rational(-2, 1) == Rational(9, 4)
|
| 1276 |
+
|
| 1277 |
+
a = Rational(1, 10)
|
| 1278 |
+
assert a**Float(a, 2) == Float(a, 2)**Float(a, 2)
|
| 1279 |
+
assert Rational(-2, 3)**Symbol('', even=True) == \
|
| 1280 |
+
Rational(2, 3)**Symbol('', even=True)
|
| 1281 |
+
|
| 1282 |
+
|
| 1283 |
+
def test_powers_Float():
|
| 1284 |
+
assert str((S('-1/10')**S('3/10')).n()) == str(Float(-.1)**(.3))
|
| 1285 |
+
|
| 1286 |
+
|
| 1287 |
+
def test_lshift_Integer():
|
| 1288 |
+
assert Integer(0) << Integer(2) == Integer(0)
|
| 1289 |
+
assert Integer(0) << 2 == Integer(0)
|
| 1290 |
+
assert 0 << Integer(2) == Integer(0)
|
| 1291 |
+
|
| 1292 |
+
assert Integer(0b11) << Integer(0) == Integer(0b11)
|
| 1293 |
+
assert Integer(0b11) << 0 == Integer(0b11)
|
| 1294 |
+
assert 0b11 << Integer(0) == Integer(0b11)
|
| 1295 |
+
|
| 1296 |
+
assert Integer(0b11) << Integer(2) == Integer(0b11 << 2)
|
| 1297 |
+
assert Integer(0b11) << 2 == Integer(0b11 << 2)
|
| 1298 |
+
assert 0b11 << Integer(2) == Integer(0b11 << 2)
|
| 1299 |
+
|
| 1300 |
+
assert Integer(-0b11) << Integer(2) == Integer(-0b11 << 2)
|
| 1301 |
+
assert Integer(-0b11) << 2 == Integer(-0b11 << 2)
|
| 1302 |
+
assert -0b11 << Integer(2) == Integer(-0b11 << 2)
|
| 1303 |
+
|
| 1304 |
+
raises(TypeError, lambda: Integer(2) << 0.0)
|
| 1305 |
+
raises(TypeError, lambda: 0.0 << Integer(2))
|
| 1306 |
+
raises(ValueError, lambda: Integer(1) << Integer(-1))
|
| 1307 |
+
|
| 1308 |
+
|
| 1309 |
+
def test_rshift_Integer():
|
| 1310 |
+
assert Integer(0) >> Integer(2) == Integer(0)
|
| 1311 |
+
assert Integer(0) >> 2 == Integer(0)
|
| 1312 |
+
assert 0 >> Integer(2) == Integer(0)
|
| 1313 |
+
|
| 1314 |
+
assert Integer(0b11) >> Integer(0) == Integer(0b11)
|
| 1315 |
+
assert Integer(0b11) >> 0 == Integer(0b11)
|
| 1316 |
+
assert 0b11 >> Integer(0) == Integer(0b11)
|
| 1317 |
+
|
| 1318 |
+
assert Integer(0b11) >> Integer(2) == Integer(0)
|
| 1319 |
+
assert Integer(0b11) >> 2 == Integer(0)
|
| 1320 |
+
assert 0b11 >> Integer(2) == Integer(0)
|
| 1321 |
+
|
| 1322 |
+
assert Integer(-0b11) >> Integer(2) == Integer(-1)
|
| 1323 |
+
assert Integer(-0b11) >> 2 == Integer(-1)
|
| 1324 |
+
assert -0b11 >> Integer(2) == Integer(-1)
|
| 1325 |
+
|
| 1326 |
+
assert Integer(0b1100) >> Integer(2) == Integer(0b1100 >> 2)
|
| 1327 |
+
assert Integer(0b1100) >> 2 == Integer(0b1100 >> 2)
|
| 1328 |
+
assert 0b1100 >> Integer(2) == Integer(0b1100 >> 2)
|
| 1329 |
+
|
| 1330 |
+
assert Integer(-0b1100) >> Integer(2) == Integer(-0b1100 >> 2)
|
| 1331 |
+
assert Integer(-0b1100) >> 2 == Integer(-0b1100 >> 2)
|
| 1332 |
+
assert -0b1100 >> Integer(2) == Integer(-0b1100 >> 2)
|
| 1333 |
+
|
| 1334 |
+
raises(TypeError, lambda: Integer(0b10) >> 0.0)
|
| 1335 |
+
raises(TypeError, lambda: 0.0 >> Integer(2))
|
| 1336 |
+
raises(ValueError, lambda: Integer(1) >> Integer(-1))
|
| 1337 |
+
|
| 1338 |
+
|
| 1339 |
+
def test_and_Integer():
|
| 1340 |
+
assert Integer(0b01010101) & Integer(0b10101010) == Integer(0)
|
| 1341 |
+
assert Integer(0b01010101) & 0b10101010 == Integer(0)
|
| 1342 |
+
assert 0b01010101 & Integer(0b10101010) == Integer(0)
|
| 1343 |
+
|
| 1344 |
+
assert Integer(0b01010101) & Integer(0b11011011) == Integer(0b01010001)
|
| 1345 |
+
assert Integer(0b01010101) & 0b11011011 == Integer(0b01010001)
|
| 1346 |
+
assert 0b01010101 & Integer(0b11011011) == Integer(0b01010001)
|
| 1347 |
+
|
| 1348 |
+
assert -Integer(0b01010101) & Integer(0b11011011) == Integer(-0b01010101 & 0b11011011)
|
| 1349 |
+
assert Integer(-0b01010101) & 0b11011011 == Integer(-0b01010101 & 0b11011011)
|
| 1350 |
+
assert -0b01010101 & Integer(0b11011011) == Integer(-0b01010101 & 0b11011011)
|
| 1351 |
+
|
| 1352 |
+
assert Integer(0b01010101) & -Integer(0b11011011) == Integer(0b01010101 & -0b11011011)
|
| 1353 |
+
assert Integer(0b01010101) & -0b11011011 == Integer(0b01010101 & -0b11011011)
|
| 1354 |
+
assert 0b01010101 & Integer(-0b11011011) == Integer(0b01010101 & -0b11011011)
|
| 1355 |
+
|
| 1356 |
+
raises(TypeError, lambda: Integer(2) & 0.0)
|
| 1357 |
+
raises(TypeError, lambda: 0.0 & Integer(2))
|
| 1358 |
+
|
| 1359 |
+
|
| 1360 |
+
def test_xor_Integer():
|
| 1361 |
+
assert Integer(0b01010101) ^ Integer(0b11111111) == Integer(0b10101010)
|
| 1362 |
+
assert Integer(0b01010101) ^ 0b11111111 == Integer(0b10101010)
|
| 1363 |
+
assert 0b01010101 ^ Integer(0b11111111) == Integer(0b10101010)
|
| 1364 |
+
|
| 1365 |
+
assert Integer(0b01010101) ^ Integer(0b11011011) == Integer(0b10001110)
|
| 1366 |
+
assert Integer(0b01010101) ^ 0b11011011 == Integer(0b10001110)
|
| 1367 |
+
assert 0b01010101 ^ Integer(0b11011011) == Integer(0b10001110)
|
| 1368 |
+
|
| 1369 |
+
assert -Integer(0b01010101) ^ Integer(0b11011011) == Integer(-0b01010101 ^ 0b11011011)
|
| 1370 |
+
assert Integer(-0b01010101) ^ 0b11011011 == Integer(-0b01010101 ^ 0b11011011)
|
| 1371 |
+
assert -0b01010101 ^ Integer(0b11011011) == Integer(-0b01010101 ^ 0b11011011)
|
| 1372 |
+
|
| 1373 |
+
assert Integer(0b01010101) ^ -Integer(0b11011011) == Integer(0b01010101 ^ -0b11011011)
|
| 1374 |
+
assert Integer(0b01010101) ^ -0b11011011 == Integer(0b01010101 ^ -0b11011011)
|
| 1375 |
+
assert 0b01010101 ^ Integer(-0b11011011) == Integer(0b01010101 ^ -0b11011011)
|
| 1376 |
+
|
| 1377 |
+
raises(TypeError, lambda: Integer(2) ^ 0.0)
|
| 1378 |
+
raises(TypeError, lambda: 0.0 ^ Integer(2))
|
| 1379 |
+
|
| 1380 |
+
|
| 1381 |
+
def test_or_Integer():
|
| 1382 |
+
assert Integer(0b01010101) | Integer(0b10101010) == Integer(0b11111111)
|
| 1383 |
+
assert Integer(0b01010101) | 0b10101010 == Integer(0b11111111)
|
| 1384 |
+
assert 0b01010101 | Integer(0b10101010) == Integer(0b11111111)
|
| 1385 |
+
|
| 1386 |
+
assert Integer(0b01010101) | Integer(0b11011011) == Integer(0b11011111)
|
| 1387 |
+
assert Integer(0b01010101) | 0b11011011 == Integer(0b11011111)
|
| 1388 |
+
assert 0b01010101 | Integer(0b11011011) == Integer(0b11011111)
|
| 1389 |
+
|
| 1390 |
+
assert -Integer(0b01010101) | Integer(0b11011011) == Integer(-0b01010101 | 0b11011011)
|
| 1391 |
+
assert Integer(-0b01010101) | 0b11011011 == Integer(-0b01010101 | 0b11011011)
|
| 1392 |
+
assert -0b01010101 | Integer(0b11011011) == Integer(-0b01010101 | 0b11011011)
|
| 1393 |
+
|
| 1394 |
+
assert Integer(0b01010101) | -Integer(0b11011011) == Integer(0b01010101 | -0b11011011)
|
| 1395 |
+
assert Integer(0b01010101) | -0b11011011 == Integer(0b01010101 | -0b11011011)
|
| 1396 |
+
assert 0b01010101 | Integer(-0b11011011) == Integer(0b01010101 | -0b11011011)
|
| 1397 |
+
|
| 1398 |
+
raises(TypeError, lambda: Integer(2) | 0.0)
|
| 1399 |
+
raises(TypeError, lambda: 0.0 | Integer(2))
|
| 1400 |
+
|
| 1401 |
+
|
| 1402 |
+
def test_invert_Integer():
|
| 1403 |
+
assert ~Integer(0b01010101) == Integer(-0b01010110)
|
| 1404 |
+
assert ~Integer(0b01010101) == Integer(~0b01010101)
|
| 1405 |
+
assert ~(~Integer(0b01010101)) == Integer(0b01010101)
|
| 1406 |
+
|
| 1407 |
+
|
| 1408 |
+
def test_abs1():
|
| 1409 |
+
assert Rational(1, 6) != Rational(-1, 6)
|
| 1410 |
+
assert abs(Rational(1, 6)) == abs(Rational(-1, 6))
|
| 1411 |
+
|
| 1412 |
+
|
| 1413 |
+
def test_accept_int():
|
| 1414 |
+
assert not Float(4) == 4
|
| 1415 |
+
assert Float(4) != 4
|
| 1416 |
+
assert Float(4) == 4.0
|
| 1417 |
+
|
| 1418 |
+
|
| 1419 |
+
def test_dont_accept_str():
|
| 1420 |
+
assert Float("0.2") != "0.2"
|
| 1421 |
+
assert not (Float("0.2") == "0.2")
|
| 1422 |
+
|
| 1423 |
+
|
| 1424 |
+
def test_int():
|
| 1425 |
+
a = Rational(5)
|
| 1426 |
+
assert int(a) == 5
|
| 1427 |
+
a = Rational(9, 10)
|
| 1428 |
+
assert int(a) == int(-a) == 0
|
| 1429 |
+
assert 1/(-1)**Rational(2, 3) == -(-1)**Rational(1, 3)
|
| 1430 |
+
# issue 10368
|
| 1431 |
+
a = Rational(32442016954, 78058255275)
|
| 1432 |
+
assert type(int(a)) is type(int(-a)) is int
|
| 1433 |
+
|
| 1434 |
+
|
| 1435 |
+
def test_int_NumberSymbols():
|
| 1436 |
+
assert int(Catalan) == 0
|
| 1437 |
+
assert int(EulerGamma) == 0
|
| 1438 |
+
assert int(pi) == 3
|
| 1439 |
+
assert int(E) == 2
|
| 1440 |
+
assert int(GoldenRatio) == 1
|
| 1441 |
+
assert int(TribonacciConstant) == 1
|
| 1442 |
+
for i in [Catalan, E, EulerGamma, GoldenRatio, TribonacciConstant, pi]:
|
| 1443 |
+
a, b = i.approximation_interval(Integer)
|
| 1444 |
+
ia = int(i)
|
| 1445 |
+
assert ia == a
|
| 1446 |
+
assert isinstance(ia, int)
|
| 1447 |
+
assert b == a + 1
|
| 1448 |
+
assert a.is_Integer and b.is_Integer
|
| 1449 |
+
|
| 1450 |
+
|
| 1451 |
+
def test_real_bug():
|
| 1452 |
+
x = Symbol("x")
|
| 1453 |
+
assert str(2.0*x*x) in ["(2.0*x)*x", "2.0*x**2", "2.00000000000000*x**2"]
|
| 1454 |
+
assert str(2.1*x*x) != "(2.0*x)*x"
|
| 1455 |
+
|
| 1456 |
+
|
| 1457 |
+
def test_bug_sqrt():
|
| 1458 |
+
assert ((sqrt(Rational(2)) + 1)*(sqrt(Rational(2)) - 1)).expand() == 1
|
| 1459 |
+
|
| 1460 |
+
|
| 1461 |
+
def test_pi_Pi():
|
| 1462 |
+
"Test that pi (instance) is imported, but Pi (class) is not"
|
| 1463 |
+
from sympy import pi # noqa
|
| 1464 |
+
with raises(ImportError):
|
| 1465 |
+
from sympy import Pi # noqa
|
| 1466 |
+
|
| 1467 |
+
|
| 1468 |
+
def test_no_len():
|
| 1469 |
+
# there should be no len for numbers
|
| 1470 |
+
raises(TypeError, lambda: len(Rational(2)))
|
| 1471 |
+
raises(TypeError, lambda: len(Rational(2, 3)))
|
| 1472 |
+
raises(TypeError, lambda: len(Integer(2)))
|
| 1473 |
+
|
| 1474 |
+
|
| 1475 |
+
def test_issue_3321():
|
| 1476 |
+
assert sqrt(Rational(1, 5)) == Rational(1, 5)**S.Half
|
| 1477 |
+
assert 5 * sqrt(Rational(1, 5)) == sqrt(5)
|
| 1478 |
+
|
| 1479 |
+
|
| 1480 |
+
def test_issue_3692():
|
| 1481 |
+
assert ((-1)**Rational(1, 6)).expand(complex=True) == I/2 + sqrt(3)/2
|
| 1482 |
+
assert ((-5)**Rational(1, 6)).expand(complex=True) == \
|
| 1483 |
+
5**Rational(1, 6)*I/2 + 5**Rational(1, 6)*sqrt(3)/2
|
| 1484 |
+
assert ((-64)**Rational(1, 6)).expand(complex=True) == I + sqrt(3)
|
| 1485 |
+
|
| 1486 |
+
|
| 1487 |
+
def test_issue_3423():
|
| 1488 |
+
x = Symbol("x")
|
| 1489 |
+
assert sqrt(x - 1).as_base_exp() == (x - 1, S.Half)
|
| 1490 |
+
assert sqrt(x - 1) != I*sqrt(1 - x)
|
| 1491 |
+
|
| 1492 |
+
|
| 1493 |
+
def test_issue_3449():
|
| 1494 |
+
x = Symbol("x")
|
| 1495 |
+
assert sqrt(x - 1).subs(x, 5) == 2
|
| 1496 |
+
|
| 1497 |
+
|
| 1498 |
+
def test_issue_13890():
|
| 1499 |
+
x = Symbol("x")
|
| 1500 |
+
e = (-x/4 - S.One/12)**x - 1
|
| 1501 |
+
f = simplify(e)
|
| 1502 |
+
a = Rational(9, 5)
|
| 1503 |
+
assert abs(e.subs(x,a).evalf() - f.subs(x,a).evalf()) < 1e-15
|
| 1504 |
+
|
| 1505 |
+
|
| 1506 |
+
def test_Integer_factors():
|
| 1507 |
+
def F(i):
|
| 1508 |
+
return Integer(i).factors()
|
| 1509 |
+
|
| 1510 |
+
assert F(1) == {}
|
| 1511 |
+
assert F(2) == {2: 1}
|
| 1512 |
+
assert F(3) == {3: 1}
|
| 1513 |
+
assert F(4) == {2: 2}
|
| 1514 |
+
assert F(5) == {5: 1}
|
| 1515 |
+
assert F(6) == {2: 1, 3: 1}
|
| 1516 |
+
assert F(7) == {7: 1}
|
| 1517 |
+
assert F(8) == {2: 3}
|
| 1518 |
+
assert F(9) == {3: 2}
|
| 1519 |
+
assert F(10) == {2: 1, 5: 1}
|
| 1520 |
+
assert F(11) == {11: 1}
|
| 1521 |
+
assert F(12) == {2: 2, 3: 1}
|
| 1522 |
+
assert F(13) == {13: 1}
|
| 1523 |
+
assert F(14) == {2: 1, 7: 1}
|
| 1524 |
+
assert F(15) == {3: 1, 5: 1}
|
| 1525 |
+
assert F(16) == {2: 4}
|
| 1526 |
+
assert F(17) == {17: 1}
|
| 1527 |
+
assert F(18) == {2: 1, 3: 2}
|
| 1528 |
+
assert F(19) == {19: 1}
|
| 1529 |
+
assert F(20) == {2: 2, 5: 1}
|
| 1530 |
+
assert F(21) == {3: 1, 7: 1}
|
| 1531 |
+
assert F(22) == {2: 1, 11: 1}
|
| 1532 |
+
assert F(23) == {23: 1}
|
| 1533 |
+
assert F(24) == {2: 3, 3: 1}
|
| 1534 |
+
assert F(25) == {5: 2}
|
| 1535 |
+
assert F(26) == {2: 1, 13: 1}
|
| 1536 |
+
assert F(27) == {3: 3}
|
| 1537 |
+
assert F(28) == {2: 2, 7: 1}
|
| 1538 |
+
assert F(29) == {29: 1}
|
| 1539 |
+
assert F(30) == {2: 1, 3: 1, 5: 1}
|
| 1540 |
+
assert F(31) == {31: 1}
|
| 1541 |
+
assert F(32) == {2: 5}
|
| 1542 |
+
assert F(33) == {3: 1, 11: 1}
|
| 1543 |
+
assert F(34) == {2: 1, 17: 1}
|
| 1544 |
+
assert F(35) == {5: 1, 7: 1}
|
| 1545 |
+
assert F(36) == {2: 2, 3: 2}
|
| 1546 |
+
assert F(37) == {37: 1}
|
| 1547 |
+
assert F(38) == {2: 1, 19: 1}
|
| 1548 |
+
assert F(39) == {3: 1, 13: 1}
|
| 1549 |
+
assert F(40) == {2: 3, 5: 1}
|
| 1550 |
+
assert F(41) == {41: 1}
|
| 1551 |
+
assert F(42) == {2: 1, 3: 1, 7: 1}
|
| 1552 |
+
assert F(43) == {43: 1}
|
| 1553 |
+
assert F(44) == {2: 2, 11: 1}
|
| 1554 |
+
assert F(45) == {3: 2, 5: 1}
|
| 1555 |
+
assert F(46) == {2: 1, 23: 1}
|
| 1556 |
+
assert F(47) == {47: 1}
|
| 1557 |
+
assert F(48) == {2: 4, 3: 1}
|
| 1558 |
+
assert F(49) == {7: 2}
|
| 1559 |
+
assert F(50) == {2: 1, 5: 2}
|
| 1560 |
+
assert F(51) == {3: 1, 17: 1}
|
| 1561 |
+
|
| 1562 |
+
|
| 1563 |
+
def test_Rational_factors():
|
| 1564 |
+
def F(p, q, visual=None):
|
| 1565 |
+
return Rational(p, q).factors(visual=visual)
|
| 1566 |
+
|
| 1567 |
+
assert F(2, 3) == {2: 1, 3: -1}
|
| 1568 |
+
assert F(2, 9) == {2: 1, 3: -2}
|
| 1569 |
+
assert F(2, 15) == {2: 1, 3: -1, 5: -1}
|
| 1570 |
+
assert F(6, 10) == {3: 1, 5: -1}
|
| 1571 |
+
|
| 1572 |
+
|
| 1573 |
+
def test_issue_4107():
|
| 1574 |
+
assert pi*(E + 10) + pi*(-E - 10) != 0
|
| 1575 |
+
assert pi*(E + 10**10) + pi*(-E - 10**10) != 0
|
| 1576 |
+
assert pi*(E + 10**20) + pi*(-E - 10**20) != 0
|
| 1577 |
+
assert pi*(E + 10**80) + pi*(-E - 10**80) != 0
|
| 1578 |
+
|
| 1579 |
+
assert (pi*(E + 10) + pi*(-E - 10)).expand() == 0
|
| 1580 |
+
assert (pi*(E + 10**10) + pi*(-E - 10**10)).expand() == 0
|
| 1581 |
+
assert (pi*(E + 10**20) + pi*(-E - 10**20)).expand() == 0
|
| 1582 |
+
assert (pi*(E + 10**80) + pi*(-E - 10**80)).expand() == 0
|
| 1583 |
+
|
| 1584 |
+
|
| 1585 |
+
def test_IntegerInteger():
|
| 1586 |
+
a = Integer(4)
|
| 1587 |
+
b = Integer(a)
|
| 1588 |
+
|
| 1589 |
+
assert a == b
|
| 1590 |
+
|
| 1591 |
+
|
| 1592 |
+
def test_Rational_gcd_lcm_cofactors():
|
| 1593 |
+
assert Integer(4).gcd(2) == Integer(2)
|
| 1594 |
+
assert Integer(4).lcm(2) == Integer(4)
|
| 1595 |
+
assert Integer(4).gcd(Integer(2)) == Integer(2)
|
| 1596 |
+
assert Integer(4).lcm(Integer(2)) == Integer(4)
|
| 1597 |
+
a, b = 720**99911, 480**12342
|
| 1598 |
+
assert Integer(a).lcm(b) == a*b/Integer(a).gcd(b)
|
| 1599 |
+
|
| 1600 |
+
assert Integer(4).gcd(3) == Integer(1)
|
| 1601 |
+
assert Integer(4).lcm(3) == Integer(12)
|
| 1602 |
+
assert Integer(4).gcd(Integer(3)) == Integer(1)
|
| 1603 |
+
assert Integer(4).lcm(Integer(3)) == Integer(12)
|
| 1604 |
+
|
| 1605 |
+
assert Rational(4, 3).gcd(2) == Rational(2, 3)
|
| 1606 |
+
assert Rational(4, 3).lcm(2) == Integer(4)
|
| 1607 |
+
assert Rational(4, 3).gcd(Integer(2)) == Rational(2, 3)
|
| 1608 |
+
assert Rational(4, 3).lcm(Integer(2)) == Integer(4)
|
| 1609 |
+
|
| 1610 |
+
assert Integer(4).gcd(Rational(2, 9)) == Rational(2, 9)
|
| 1611 |
+
assert Integer(4).lcm(Rational(2, 9)) == Integer(4)
|
| 1612 |
+
|
| 1613 |
+
assert Rational(4, 3).gcd(Rational(2, 9)) == Rational(2, 9)
|
| 1614 |
+
assert Rational(4, 3).lcm(Rational(2, 9)) == Rational(4, 3)
|
| 1615 |
+
assert Rational(4, 5).gcd(Rational(2, 9)) == Rational(2, 45)
|
| 1616 |
+
assert Rational(4, 5).lcm(Rational(2, 9)) == Integer(4)
|
| 1617 |
+
assert Rational(5, 9).lcm(Rational(3, 7)) == Rational(Integer(5).lcm(3),Integer(9).gcd(7))
|
| 1618 |
+
|
| 1619 |
+
assert Integer(4).cofactors(2) == (Integer(2), Integer(2), Integer(1))
|
| 1620 |
+
assert Integer(4).cofactors(Integer(2)) == \
|
| 1621 |
+
(Integer(2), Integer(2), Integer(1))
|
| 1622 |
+
|
| 1623 |
+
assert Integer(4).gcd(Float(2.0)) == Float(1.0)
|
| 1624 |
+
assert Integer(4).lcm(Float(2.0)) == Float(8.0)
|
| 1625 |
+
assert Integer(4).cofactors(Float(2.0)) == (Float(1.0), Float(4.0), Float(2.0))
|
| 1626 |
+
|
| 1627 |
+
assert S.Half.gcd(Float(2.0)) == Float(1.0)
|
| 1628 |
+
assert S.Half.lcm(Float(2.0)) == Float(1.0)
|
| 1629 |
+
assert S.Half.cofactors(Float(2.0)) == \
|
| 1630 |
+
(Float(1.0), Float(0.5), Float(2.0))
|
| 1631 |
+
|
| 1632 |
+
|
| 1633 |
+
def test_Float_gcd_lcm_cofactors():
|
| 1634 |
+
assert Float(2.0).gcd(Integer(4)) == Float(1.0)
|
| 1635 |
+
assert Float(2.0).lcm(Integer(4)) == Float(8.0)
|
| 1636 |
+
assert Float(2.0).cofactors(Integer(4)) == (Float(1.0), Float(2.0), Float(4.0))
|
| 1637 |
+
|
| 1638 |
+
assert Float(2.0).gcd(S.Half) == Float(1.0)
|
| 1639 |
+
assert Float(2.0).lcm(S.Half) == Float(1.0)
|
| 1640 |
+
assert Float(2.0).cofactors(S.Half) == \
|
| 1641 |
+
(Float(1.0), Float(2.0), Float(0.5))
|
| 1642 |
+
|
| 1643 |
+
|
| 1644 |
+
def test_issue_4611():
|
| 1645 |
+
assert abs(pi._evalf(50) - 3.14159265358979) < 1e-10
|
| 1646 |
+
assert abs(E._evalf(50) - 2.71828182845905) < 1e-10
|
| 1647 |
+
assert abs(Catalan._evalf(50) - 0.915965594177219) < 1e-10
|
| 1648 |
+
assert abs(EulerGamma._evalf(50) - 0.577215664901533) < 1e-10
|
| 1649 |
+
assert abs(GoldenRatio._evalf(50) - 1.61803398874989) < 1e-10
|
| 1650 |
+
assert abs(TribonacciConstant._evalf(50) - 1.83928675521416) < 1e-10
|
| 1651 |
+
|
| 1652 |
+
x = Symbol("x")
|
| 1653 |
+
assert (pi + x).evalf() == pi.evalf() + x
|
| 1654 |
+
assert (E + x).evalf() == E.evalf() + x
|
| 1655 |
+
assert (Catalan + x).evalf() == Catalan.evalf() + x
|
| 1656 |
+
assert (EulerGamma + x).evalf() == EulerGamma.evalf() + x
|
| 1657 |
+
assert (GoldenRatio + x).evalf() == GoldenRatio.evalf() + x
|
| 1658 |
+
assert (TribonacciConstant + x).evalf() == TribonacciConstant.evalf() + x
|
| 1659 |
+
|
| 1660 |
+
|
| 1661 |
+
@conserve_mpmath_dps
|
| 1662 |
+
def test_conversion_to_mpmath():
|
| 1663 |
+
assert mpmath.mpmathify(Integer(1)) == mpmath.mpf(1)
|
| 1664 |
+
assert mpmath.mpmathify(S.Half) == mpmath.mpf(0.5)
|
| 1665 |
+
assert mpmath.mpmathify(Float('1.23', 15)) == mpmath.mpf('1.23')
|
| 1666 |
+
|
| 1667 |
+
assert mpmath.mpmathify(I) == mpmath.mpc(1j)
|
| 1668 |
+
|
| 1669 |
+
assert mpmath.mpmathify(1 + 2*I) == mpmath.mpc(1 + 2j)
|
| 1670 |
+
assert mpmath.mpmathify(1.0 + 2*I) == mpmath.mpc(1 + 2j)
|
| 1671 |
+
assert mpmath.mpmathify(1 + 2.0*I) == mpmath.mpc(1 + 2j)
|
| 1672 |
+
assert mpmath.mpmathify(1.0 + 2.0*I) == mpmath.mpc(1 + 2j)
|
| 1673 |
+
assert mpmath.mpmathify(S.Half + S.Half*I) == mpmath.mpc(0.5 + 0.5j)
|
| 1674 |
+
|
| 1675 |
+
assert mpmath.mpmathify(2*I) == mpmath.mpc(2j)
|
| 1676 |
+
assert mpmath.mpmathify(2.0*I) == mpmath.mpc(2j)
|
| 1677 |
+
assert mpmath.mpmathify(S.Half*I) == mpmath.mpc(0.5j)
|
| 1678 |
+
|
| 1679 |
+
mpmath.mp.dps = 100
|
| 1680 |
+
assert mpmath.mpmathify(pi.evalf(100) + pi.evalf(100)*I) == mpmath.pi + mpmath.pi*mpmath.j
|
| 1681 |
+
assert mpmath.mpmathify(pi.evalf(100)*I) == mpmath.pi*mpmath.j
|
| 1682 |
+
|
| 1683 |
+
|
| 1684 |
+
def test_relational():
|
| 1685 |
+
# real
|
| 1686 |
+
x = S(.1)
|
| 1687 |
+
assert (x != cos) is True
|
| 1688 |
+
assert (x == cos) is False
|
| 1689 |
+
|
| 1690 |
+
# rational
|
| 1691 |
+
x = Rational(1, 3)
|
| 1692 |
+
assert (x != cos) is True
|
| 1693 |
+
assert (x == cos) is False
|
| 1694 |
+
|
| 1695 |
+
# integer defers to rational so these tests are omitted
|
| 1696 |
+
|
| 1697 |
+
# number symbol
|
| 1698 |
+
x = pi
|
| 1699 |
+
assert (x != cos) is True
|
| 1700 |
+
assert (x == cos) is False
|
| 1701 |
+
|
| 1702 |
+
|
| 1703 |
+
def test_Integer_as_index():
|
| 1704 |
+
assert 'hello'[Integer(2):] == 'llo'
|
| 1705 |
+
|
| 1706 |
+
|
| 1707 |
+
def test_Rational_int():
|
| 1708 |
+
assert int( Rational(7, 5)) == 1
|
| 1709 |
+
assert int( S.Half) == 0
|
| 1710 |
+
assert int(Rational(-1, 2)) == 0
|
| 1711 |
+
assert int(-Rational(7, 5)) == -1
|
| 1712 |
+
|
| 1713 |
+
|
| 1714 |
+
def test_zoo():
|
| 1715 |
+
b = Symbol('b', finite=True)
|
| 1716 |
+
nz = Symbol('nz', nonzero=True)
|
| 1717 |
+
p = Symbol('p', positive=True)
|
| 1718 |
+
n = Symbol('n', negative=True)
|
| 1719 |
+
im = Symbol('i', imaginary=True)
|
| 1720 |
+
c = Symbol('c', complex=True)
|
| 1721 |
+
pb = Symbol('pb', positive=True)
|
| 1722 |
+
nb = Symbol('nb', negative=True)
|
| 1723 |
+
imb = Symbol('ib', imaginary=True, finite=True)
|
| 1724 |
+
for i in [I, S.Infinity, S.NegativeInfinity, S.Zero, S.One, S.Pi, S.Half, S(3), log(3),
|
| 1725 |
+
b, nz, p, n, im, pb, nb, imb, c]:
|
| 1726 |
+
if i.is_finite and (i.is_real or i.is_imaginary):
|
| 1727 |
+
assert i + zoo is zoo
|
| 1728 |
+
assert i - zoo is zoo
|
| 1729 |
+
assert zoo + i is zoo
|
| 1730 |
+
assert zoo - i is zoo
|
| 1731 |
+
elif i.is_finite is not False:
|
| 1732 |
+
assert (i + zoo).is_Add
|
| 1733 |
+
assert (i - zoo).is_Add
|
| 1734 |
+
assert (zoo + i).is_Add
|
| 1735 |
+
assert (zoo - i).is_Add
|
| 1736 |
+
else:
|
| 1737 |
+
assert (i + zoo) is S.NaN
|
| 1738 |
+
assert (i - zoo) is S.NaN
|
| 1739 |
+
assert (zoo + i) is S.NaN
|
| 1740 |
+
assert (zoo - i) is S.NaN
|
| 1741 |
+
|
| 1742 |
+
if fuzzy_not(i.is_zero) and (i.is_extended_real or i.is_imaginary):
|
| 1743 |
+
assert i*zoo is zoo
|
| 1744 |
+
assert zoo*i is zoo
|
| 1745 |
+
elif i.is_zero:
|
| 1746 |
+
assert i*zoo is S.NaN
|
| 1747 |
+
assert zoo*i is S.NaN
|
| 1748 |
+
else:
|
| 1749 |
+
assert (i*zoo).is_Mul
|
| 1750 |
+
assert (zoo*i).is_Mul
|
| 1751 |
+
|
| 1752 |
+
if fuzzy_not((1/i).is_zero) and (i.is_real or i.is_imaginary):
|
| 1753 |
+
assert zoo/i is zoo
|
| 1754 |
+
elif (1/i).is_zero:
|
| 1755 |
+
assert zoo/i is S.NaN
|
| 1756 |
+
elif i.is_zero:
|
| 1757 |
+
assert zoo/i is zoo
|
| 1758 |
+
else:
|
| 1759 |
+
assert (zoo/i).is_Mul
|
| 1760 |
+
|
| 1761 |
+
assert (I*oo).is_Mul # allow directed infinity
|
| 1762 |
+
assert zoo + zoo is S.NaN
|
| 1763 |
+
assert zoo * zoo is zoo
|
| 1764 |
+
assert zoo - zoo is S.NaN
|
| 1765 |
+
assert zoo/zoo is S.NaN
|
| 1766 |
+
assert zoo**zoo is S.NaN
|
| 1767 |
+
assert zoo**0 is S.One
|
| 1768 |
+
assert zoo**2 is zoo
|
| 1769 |
+
assert 1/zoo is S.Zero
|
| 1770 |
+
|
| 1771 |
+
assert Mul.flatten([S.NegativeOne, oo, S(0)]) == ([S.NaN], [], None)
|
| 1772 |
+
|
| 1773 |
+
|
| 1774 |
+
def test_issue_4122():
|
| 1775 |
+
x = Symbol('x', nonpositive=True)
|
| 1776 |
+
assert oo + x is oo
|
| 1777 |
+
x = Symbol('x', extended_nonpositive=True)
|
| 1778 |
+
assert (oo + x).is_Add
|
| 1779 |
+
x = Symbol('x', finite=True)
|
| 1780 |
+
assert (oo + x).is_Add # x could be imaginary
|
| 1781 |
+
x = Symbol('x', nonnegative=True)
|
| 1782 |
+
assert oo + x is oo
|
| 1783 |
+
x = Symbol('x', extended_nonnegative=True)
|
| 1784 |
+
assert oo + x is oo
|
| 1785 |
+
x = Symbol('x', finite=True, real=True)
|
| 1786 |
+
assert oo + x is oo
|
| 1787 |
+
|
| 1788 |
+
# similarly for negative infinity
|
| 1789 |
+
x = Symbol('x', nonnegative=True)
|
| 1790 |
+
assert -oo + x is -oo
|
| 1791 |
+
x = Symbol('x', extended_nonnegative=True)
|
| 1792 |
+
assert (-oo + x).is_Add
|
| 1793 |
+
x = Symbol('x', finite=True)
|
| 1794 |
+
assert (-oo + x).is_Add
|
| 1795 |
+
x = Symbol('x', nonpositive=True)
|
| 1796 |
+
assert -oo + x is -oo
|
| 1797 |
+
x = Symbol('x', extended_nonpositive=True)
|
| 1798 |
+
assert -oo + x is -oo
|
| 1799 |
+
x = Symbol('x', finite=True, real=True)
|
| 1800 |
+
assert -oo + x is -oo
|
| 1801 |
+
|
| 1802 |
+
|
| 1803 |
+
def test_GoldenRatio_expand():
|
| 1804 |
+
assert GoldenRatio.expand(func=True) == S.Half + sqrt(5)/2
|
| 1805 |
+
|
| 1806 |
+
|
| 1807 |
+
def test_TribonacciConstant_expand():
|
| 1808 |
+
assert TribonacciConstant.expand(func=True) == \
|
| 1809 |
+
(1 + cbrt(19 - 3*sqrt(33)) + cbrt(19 + 3*sqrt(33))) / 3
|
| 1810 |
+
|
| 1811 |
+
|
| 1812 |
+
def test_as_content_primitive():
|
| 1813 |
+
assert S.Zero.as_content_primitive() == (1, 0)
|
| 1814 |
+
assert S.Half.as_content_primitive() == (S.Half, 1)
|
| 1815 |
+
assert (Rational(-1, 2)).as_content_primitive() == (S.Half, -1)
|
| 1816 |
+
assert S(3).as_content_primitive() == (3, 1)
|
| 1817 |
+
assert S(3.1).as_content_primitive() == (1, 3.1)
|
| 1818 |
+
|
| 1819 |
+
|
| 1820 |
+
def test_hashing_sympy_integers():
|
| 1821 |
+
# Test for issue 5072
|
| 1822 |
+
assert {Integer(3)} == {int(3)}
|
| 1823 |
+
assert hash(Integer(4)) == hash(int(4))
|
| 1824 |
+
|
| 1825 |
+
|
| 1826 |
+
def test_rounding_issue_4172():
|
| 1827 |
+
assert int((E**100).round()) == \
|
| 1828 |
+
26881171418161354484126255515800135873611119
|
| 1829 |
+
assert int((pi**100).round()) == \
|
| 1830 |
+
51878483143196131920862615246303013562686760680406
|
| 1831 |
+
assert int((Rational(1)/EulerGamma**100).round()) == \
|
| 1832 |
+
734833795660954410469466
|
| 1833 |
+
|
| 1834 |
+
|
| 1835 |
+
@XFAIL
|
| 1836 |
+
def test_mpmath_issues():
|
| 1837 |
+
from mpmath.libmp.libmpf import _normalize
|
| 1838 |
+
import mpmath.libmp as mlib
|
| 1839 |
+
rnd = mlib.round_nearest
|
| 1840 |
+
mpf = (0, int(0), -123, -1, 53, rnd) # nan
|
| 1841 |
+
assert _normalize(mpf, 53) != (0, int(0), 0, 0)
|
| 1842 |
+
mpf = (0, int(0), -456, -2, 53, rnd) # +inf
|
| 1843 |
+
assert _normalize(mpf, 53) != (0, int(0), 0, 0)
|
| 1844 |
+
mpf = (1, int(0), -789, -3, 53, rnd) # -inf
|
| 1845 |
+
assert _normalize(mpf, 53) != (0, int(0), 0, 0)
|
| 1846 |
+
|
| 1847 |
+
from mpmath.libmp.libmpf import fnan
|
| 1848 |
+
assert mlib.mpf_eq(fnan, fnan)
|
| 1849 |
+
|
| 1850 |
+
|
| 1851 |
+
def test_Catalan_EulerGamma_prec():
|
| 1852 |
+
n = GoldenRatio
|
| 1853 |
+
f = Float(n.n(), 5)
|
| 1854 |
+
assert f._mpf_ == (0, int(212079), -17, 18)
|
| 1855 |
+
assert f._prec == 20
|
| 1856 |
+
assert n._as_mpf_val(20) == f._mpf_
|
| 1857 |
+
|
| 1858 |
+
n = EulerGamma
|
| 1859 |
+
f = Float(n.n(), 5)
|
| 1860 |
+
assert f._mpf_ == (0, int(302627), -19, 19)
|
| 1861 |
+
assert f._prec == 20
|
| 1862 |
+
assert n._as_mpf_val(20) == f._mpf_
|
| 1863 |
+
|
| 1864 |
+
|
| 1865 |
+
def test_Catalan_rewrite():
|
| 1866 |
+
k = Dummy('k', integer=True, nonnegative=True)
|
| 1867 |
+
assert Catalan.rewrite(Sum).dummy_eq(
|
| 1868 |
+
Sum((-1)**k/(2*k + 1)**2, (k, 0, oo)))
|
| 1869 |
+
assert Catalan.rewrite() == Catalan
|
| 1870 |
+
|
| 1871 |
+
|
| 1872 |
+
def test_bool_eq():
|
| 1873 |
+
assert 0 == False
|
| 1874 |
+
assert S(0) == False
|
| 1875 |
+
assert S(0) != S.false
|
| 1876 |
+
assert 1 == True
|
| 1877 |
+
assert S.One == True
|
| 1878 |
+
assert S.One != S.true
|
| 1879 |
+
|
| 1880 |
+
|
| 1881 |
+
def test_Float_eq():
|
| 1882 |
+
# Floats with different precision should not compare equal
|
| 1883 |
+
assert Float(.5, 10) != Float(.5, 11) != Float(.5, 1)
|
| 1884 |
+
# but floats that aren't exact in base-2 still
|
| 1885 |
+
# don't compare the same because they have different
|
| 1886 |
+
# underlying mpf values
|
| 1887 |
+
assert Float(.12, 3) != Float(.12, 4)
|
| 1888 |
+
assert Float(.12, 3) != .12
|
| 1889 |
+
assert 0.12 != Float(.12, 3)
|
| 1890 |
+
assert Float('.12', 22) != .12
|
| 1891 |
+
# issue 11707
|
| 1892 |
+
# but Float/Rational -- except for 0 --
|
| 1893 |
+
# are exact so Rational(x) = Float(y) only if
|
| 1894 |
+
# Rational(x) == Rational(Float(y))
|
| 1895 |
+
assert Float('1.1') != Rational(11, 10)
|
| 1896 |
+
assert Rational(11, 10) != Float('1.1')
|
| 1897 |
+
# coverage
|
| 1898 |
+
assert not Float(3) == 2
|
| 1899 |
+
assert not Float(3) == Float(2)
|
| 1900 |
+
assert not Float(3) == 3
|
| 1901 |
+
assert not Float(2**2) == S.Half
|
| 1902 |
+
assert Float(2**2) == 4.0
|
| 1903 |
+
assert not Float(2**-2) == 1
|
| 1904 |
+
assert Float(2**-1) == 0.5
|
| 1905 |
+
assert not Float(2*3) == 3
|
| 1906 |
+
assert not Float(2*3) == 0.5
|
| 1907 |
+
assert Float(2*3) == 6.0
|
| 1908 |
+
assert not Float(2*3) == 6
|
| 1909 |
+
assert not Float(2*3) == 8
|
| 1910 |
+
assert not Float(.75) == Rational(3, 4)
|
| 1911 |
+
assert Float(.75) == 0.75
|
| 1912 |
+
assert Float(5/18) == 5/18
|
| 1913 |
+
# 4473
|
| 1914 |
+
assert Float(2.) != 3
|
| 1915 |
+
assert not Float((0,1,-3)) == S.One/8
|
| 1916 |
+
assert Float((0,1,-3)) == 1/8
|
| 1917 |
+
assert Float((0,1,-3)) != S.One/9
|
| 1918 |
+
# 16196
|
| 1919 |
+
assert not 2 == Float(2) # unlike Python
|
| 1920 |
+
assert t**2 != t**2.0
|
| 1921 |
+
|
| 1922 |
+
|
| 1923 |
+
def test_issue_6640():
|
| 1924 |
+
from mpmath.libmp.libmpf import finf, fninf
|
| 1925 |
+
# fnan is not included because Float no longer returns fnan,
|
| 1926 |
+
# but otherwise, the same sort of test could apply
|
| 1927 |
+
assert Float(finf).is_zero is False
|
| 1928 |
+
assert Float(fninf).is_zero is False
|
| 1929 |
+
assert bool(Float(0)) is False
|
| 1930 |
+
|
| 1931 |
+
|
| 1932 |
+
def test_issue_6349():
|
| 1933 |
+
assert Float('23.e3', '')._prec == 10
|
| 1934 |
+
assert Float('23e3', '')._prec == 20
|
| 1935 |
+
assert Float('23000', '')._prec == 20
|
| 1936 |
+
assert Float('-23000', '')._prec == 20
|
| 1937 |
+
|
| 1938 |
+
|
| 1939 |
+
def test_mpf_norm():
|
| 1940 |
+
assert mpf_norm((1, 0, 1, 0), 10) == mpf('0')._mpf_
|
| 1941 |
+
assert Float._new((1, 0, 1, 0), 10)._mpf_ == mpf('0')._mpf_
|
| 1942 |
+
|
| 1943 |
+
|
| 1944 |
+
def test_latex():
|
| 1945 |
+
assert latex(pi) == r"\pi"
|
| 1946 |
+
assert latex(E) == r"e"
|
| 1947 |
+
assert latex(GoldenRatio) == r"\phi"
|
| 1948 |
+
assert latex(TribonacciConstant) == r"\text{TribonacciConstant}"
|
| 1949 |
+
assert latex(EulerGamma) == r"\gamma"
|
| 1950 |
+
assert latex(oo) == r"\infty"
|
| 1951 |
+
assert latex(-oo) == r"-\infty"
|
| 1952 |
+
assert latex(zoo) == r"\tilde{\infty}"
|
| 1953 |
+
assert latex(nan) == r"\text{NaN}"
|
| 1954 |
+
assert latex(I) == r"i"
|
| 1955 |
+
|
| 1956 |
+
|
| 1957 |
+
def test_issue_7742():
|
| 1958 |
+
assert -oo % 1 is nan
|
| 1959 |
+
|
| 1960 |
+
|
| 1961 |
+
def test_simplify_AlgebraicNumber():
|
| 1962 |
+
A = AlgebraicNumber
|
| 1963 |
+
e = 3**(S.One/6)*(3 + (135 + 78*sqrt(3))**Rational(2, 3))/(45 + 26*sqrt(3))**(S.One/3)
|
| 1964 |
+
assert simplify(A(e)) == A(12) # wester test_C20
|
| 1965 |
+
|
| 1966 |
+
e = (41 + 29*sqrt(2))**(S.One/5)
|
| 1967 |
+
assert simplify(A(e)) == A(1 + sqrt(2)) # wester test_C21
|
| 1968 |
+
|
| 1969 |
+
e = (3 + 4*I)**Rational(3, 2)
|
| 1970 |
+
assert simplify(A(e)) == A(2 + 11*I) # issue 4401
|
| 1971 |
+
|
| 1972 |
+
|
| 1973 |
+
def test_Float_idempotence():
|
| 1974 |
+
x = Float('1.23', '')
|
| 1975 |
+
y = Float(x)
|
| 1976 |
+
z = Float(x, 15)
|
| 1977 |
+
assert same_and_same_prec(y, x)
|
| 1978 |
+
assert not same_and_same_prec(z, x)
|
| 1979 |
+
x = Float(10**20)
|
| 1980 |
+
y = Float(x)
|
| 1981 |
+
z = Float(x, 15)
|
| 1982 |
+
assert same_and_same_prec(y, x)
|
| 1983 |
+
assert not same_and_same_prec(z, x)
|
| 1984 |
+
|
| 1985 |
+
|
| 1986 |
+
def test_comp1():
|
| 1987 |
+
# sqrt(2) = 1.414213 5623730950...
|
| 1988 |
+
a = sqrt(2).n(7)
|
| 1989 |
+
assert comp(a, 1.4142129) is False
|
| 1990 |
+
assert comp(a, 1.4142130)
|
| 1991 |
+
# ...
|
| 1992 |
+
assert comp(a, 1.4142141)
|
| 1993 |
+
assert comp(a, 1.4142142) is False
|
| 1994 |
+
assert comp(sqrt(2).n(2), '1.4')
|
| 1995 |
+
assert comp(sqrt(2).n(2), Float(1.4, 2), '')
|
| 1996 |
+
assert comp(sqrt(2).n(2), 1.4, '')
|
| 1997 |
+
assert comp(sqrt(2).n(2), Float(1.4, 3), '') is False
|
| 1998 |
+
assert comp(sqrt(2) + sqrt(3)*I, 1.4 + 1.7*I, .1)
|
| 1999 |
+
assert not comp(sqrt(2) + sqrt(3)*I, (1.5 + 1.7*I)*0.89, .1)
|
| 2000 |
+
assert comp(sqrt(2) + sqrt(3)*I, (1.5 + 1.7*I)*0.90, .1)
|
| 2001 |
+
assert comp(sqrt(2) + sqrt(3)*I, (1.5 + 1.7*I)*1.07, .1)
|
| 2002 |
+
assert not comp(sqrt(2) + sqrt(3)*I, (1.5 + 1.7*I)*1.08, .1)
|
| 2003 |
+
assert [(i, j)
|
| 2004 |
+
for i in range(130, 150)
|
| 2005 |
+
for j in range(170, 180)
|
| 2006 |
+
if comp((sqrt(2)+ I*sqrt(3)).n(3), i/100. + I*j/100.)] == [
|
| 2007 |
+
(141, 173), (142, 173)]
|
| 2008 |
+
raises(ValueError, lambda: comp(t, '1'))
|
| 2009 |
+
raises(ValueError, lambda: comp(t, 1))
|
| 2010 |
+
assert comp(0, 0.0)
|
| 2011 |
+
assert comp(.5, S.Half)
|
| 2012 |
+
assert comp(2 + sqrt(2), 2.0 + sqrt(2))
|
| 2013 |
+
assert not comp(0, 1)
|
| 2014 |
+
assert not comp(2, sqrt(2))
|
| 2015 |
+
assert not comp(2 + I, 2.0 + sqrt(2))
|
| 2016 |
+
assert not comp(2.0 + sqrt(2), 2 + I)
|
| 2017 |
+
assert not comp(2.0 + sqrt(2), sqrt(3))
|
| 2018 |
+
assert comp(1/pi.n(4), 0.3183, 1e-5)
|
| 2019 |
+
assert not comp(1/pi.n(4), 0.3183, 8e-6)
|
| 2020 |
+
|
| 2021 |
+
|
| 2022 |
+
def test_issue_9491():
|
| 2023 |
+
assert oo**zoo is nan
|
| 2024 |
+
|
| 2025 |
+
|
| 2026 |
+
def test_issue_10063():
|
| 2027 |
+
assert 2**Float(3) == Float(8)
|
| 2028 |
+
|
| 2029 |
+
|
| 2030 |
+
def test_issue_10020():
|
| 2031 |
+
assert oo**I is S.NaN
|
| 2032 |
+
assert oo**(1 + I) is S.ComplexInfinity
|
| 2033 |
+
assert oo**(-1 + I) is S.Zero
|
| 2034 |
+
assert (-oo)**I is S.NaN
|
| 2035 |
+
assert (-oo)**(-1 + I) is S.Zero
|
| 2036 |
+
assert oo**t == Pow(oo, t, evaluate=False)
|
| 2037 |
+
assert (-oo)**t == Pow(-oo, t, evaluate=False)
|
| 2038 |
+
|
| 2039 |
+
|
| 2040 |
+
def test_invert_numbers():
|
| 2041 |
+
assert S(2).invert(5) == 3
|
| 2042 |
+
assert S(2).invert(Rational(5, 2)) == S.Half
|
| 2043 |
+
assert S(2).invert(5.) == S.Half
|
| 2044 |
+
assert S(2).invert(S(5)) == 3
|
| 2045 |
+
assert S(2.).invert(5) == 0.5
|
| 2046 |
+
assert S(sqrt(2)).invert(5) == 1/sqrt(2)
|
| 2047 |
+
assert S(sqrt(2)).invert(sqrt(3)) == 1/sqrt(2)
|
| 2048 |
+
|
| 2049 |
+
|
| 2050 |
+
def test_mod_inverse():
|
| 2051 |
+
assert mod_inverse(3, 11) == 4
|
| 2052 |
+
assert mod_inverse(5, 11) == 9
|
| 2053 |
+
assert mod_inverse(21124921, 521512) == 7713
|
| 2054 |
+
assert mod_inverse(124215421, 5125) == 2981
|
| 2055 |
+
assert mod_inverse(214, 12515) == 1579
|
| 2056 |
+
assert mod_inverse(5823991, 3299) == 1442
|
| 2057 |
+
assert mod_inverse(123, 44) == 39
|
| 2058 |
+
assert mod_inverse(2, 5) == 3
|
| 2059 |
+
assert mod_inverse(-2, 5) == 2
|
| 2060 |
+
assert mod_inverse(2, -5) == -2
|
| 2061 |
+
assert mod_inverse(-2, -5) == -3
|
| 2062 |
+
assert mod_inverse(-3, -7) == -5
|
| 2063 |
+
x = Symbol('x')
|
| 2064 |
+
assert S(2).invert(x) == S.Half
|
| 2065 |
+
raises(TypeError, lambda: mod_inverse(2, x))
|
| 2066 |
+
raises(ValueError, lambda: mod_inverse(2, S.Half))
|
| 2067 |
+
raises(ValueError, lambda: mod_inverse(2, cos(1)**2 + sin(1)**2))
|
| 2068 |
+
|
| 2069 |
+
|
| 2070 |
+
def test_golden_ratio_rewrite_as_sqrt():
|
| 2071 |
+
assert GoldenRatio.rewrite(sqrt) == S.Half + sqrt(5)*S.Half
|
| 2072 |
+
|
| 2073 |
+
|
| 2074 |
+
def test_tribonacci_constant_rewrite_as_sqrt():
|
| 2075 |
+
assert TribonacciConstant.rewrite(sqrt) == \
|
| 2076 |
+
(1 + cbrt(19 - 3*sqrt(33)) + cbrt(19 + 3*sqrt(33))) / 3
|
| 2077 |
+
|
| 2078 |
+
|
| 2079 |
+
def test_comparisons_with_unknown_type():
|
| 2080 |
+
class Foo:
|
| 2081 |
+
"""
|
| 2082 |
+
Class that is unaware of Basic, and relies on both classes returning
|
| 2083 |
+
the NotImplemented singleton for equivalence to evaluate to False.
|
| 2084 |
+
|
| 2085 |
+
"""
|
| 2086 |
+
|
| 2087 |
+
ni, nf, nr = Integer(3), Float(1.0), Rational(1, 3)
|
| 2088 |
+
foo = Foo()
|
| 2089 |
+
|
| 2090 |
+
for n in ni, nf, nr, oo, -oo, zoo, nan:
|
| 2091 |
+
assert n != foo
|
| 2092 |
+
assert foo != n
|
| 2093 |
+
assert not n == foo
|
| 2094 |
+
assert not foo == n
|
| 2095 |
+
raises(TypeError, lambda: n < foo)
|
| 2096 |
+
raises(TypeError, lambda: foo > n)
|
| 2097 |
+
raises(TypeError, lambda: n > foo)
|
| 2098 |
+
raises(TypeError, lambda: foo < n)
|
| 2099 |
+
raises(TypeError, lambda: n <= foo)
|
| 2100 |
+
raises(TypeError, lambda: foo >= n)
|
| 2101 |
+
raises(TypeError, lambda: n >= foo)
|
| 2102 |
+
raises(TypeError, lambda: foo <= n)
|
| 2103 |
+
|
| 2104 |
+
class Bar:
|
| 2105 |
+
"""
|
| 2106 |
+
Class that considers itself equal to any instance of Number except
|
| 2107 |
+
infinities and nans, and relies on SymPy types returning the
|
| 2108 |
+
NotImplemented singleton for symmetric equality relations.
|
| 2109 |
+
|
| 2110 |
+
"""
|
| 2111 |
+
def __eq__(self, other):
|
| 2112 |
+
if other in (oo, -oo, zoo, nan):
|
| 2113 |
+
return False
|
| 2114 |
+
if isinstance(other, Number):
|
| 2115 |
+
return True
|
| 2116 |
+
return NotImplemented
|
| 2117 |
+
|
| 2118 |
+
def __ne__(self, other):
|
| 2119 |
+
return not self == other
|
| 2120 |
+
|
| 2121 |
+
bar = Bar()
|
| 2122 |
+
|
| 2123 |
+
for n in ni, nf, nr:
|
| 2124 |
+
assert n == bar
|
| 2125 |
+
assert bar == n
|
| 2126 |
+
assert not n != bar
|
| 2127 |
+
assert not bar != n
|
| 2128 |
+
|
| 2129 |
+
for n in oo, -oo, zoo, nan:
|
| 2130 |
+
assert n != bar
|
| 2131 |
+
assert bar != n
|
| 2132 |
+
assert not n == bar
|
| 2133 |
+
assert not bar == n
|
| 2134 |
+
|
| 2135 |
+
for n in ni, nf, nr, oo, -oo, zoo, nan:
|
| 2136 |
+
raises(TypeError, lambda: n < bar)
|
| 2137 |
+
raises(TypeError, lambda: bar > n)
|
| 2138 |
+
raises(TypeError, lambda: n > bar)
|
| 2139 |
+
raises(TypeError, lambda: bar < n)
|
| 2140 |
+
raises(TypeError, lambda: n <= bar)
|
| 2141 |
+
raises(TypeError, lambda: bar >= n)
|
| 2142 |
+
raises(TypeError, lambda: n >= bar)
|
| 2143 |
+
raises(TypeError, lambda: bar <= n)
|
| 2144 |
+
|
| 2145 |
+
|
| 2146 |
+
def test_NumberSymbol_comparison():
|
| 2147 |
+
from sympy.core.tests.test_relational import rel_check
|
| 2148 |
+
rpi = Rational('905502432259640373/288230376151711744')
|
| 2149 |
+
fpi = Float(float(pi))
|
| 2150 |
+
assert rel_check(rpi, fpi)
|
| 2151 |
+
|
| 2152 |
+
|
| 2153 |
+
def test_Integer_precision():
|
| 2154 |
+
# Make sure Integer inputs for keyword args work
|
| 2155 |
+
assert Float('1.0', dps=Integer(15))._prec == 53
|
| 2156 |
+
assert Float('1.0', precision=Integer(15))._prec == 15
|
| 2157 |
+
assert type(Float('1.0', precision=Integer(15))._prec) == int
|
| 2158 |
+
assert sympify(srepr(Float('1.0', precision=15))) == Float('1.0', precision=15)
|
| 2159 |
+
|
| 2160 |
+
|
| 2161 |
+
def test_numpy_to_float():
|
| 2162 |
+
from sympy.testing.pytest import skip
|
| 2163 |
+
from sympy.external import import_module
|
| 2164 |
+
np = import_module('numpy')
|
| 2165 |
+
if not np:
|
| 2166 |
+
skip('numpy not installed. Abort numpy tests.')
|
| 2167 |
+
|
| 2168 |
+
def check_prec_and_relerr(npval, ratval):
|
| 2169 |
+
prec = np.finfo(npval).nmant + 1
|
| 2170 |
+
x = Float(npval)
|
| 2171 |
+
assert x._prec == prec
|
| 2172 |
+
y = Float(ratval, precision=prec)
|
| 2173 |
+
assert abs((x - y)/y) < 2**(-(prec + 1))
|
| 2174 |
+
|
| 2175 |
+
check_prec_and_relerr(np.float16(2.0/3), Rational(2, 3))
|
| 2176 |
+
check_prec_and_relerr(np.float32(2.0/3), Rational(2, 3))
|
| 2177 |
+
check_prec_and_relerr(np.float64(2.0/3), Rational(2, 3))
|
| 2178 |
+
# extended precision, on some arch/compilers:
|
| 2179 |
+
x = np.longdouble(2)/3
|
| 2180 |
+
check_prec_and_relerr(x, Rational(2, 3))
|
| 2181 |
+
y = Float(x, precision=10)
|
| 2182 |
+
assert same_and_same_prec(y, Float(Rational(2, 3), precision=10))
|
| 2183 |
+
|
| 2184 |
+
raises(TypeError, lambda: Float(np.complex64(1+2j)))
|
| 2185 |
+
raises(TypeError, lambda: Float(np.complex128(1+2j)))
|
| 2186 |
+
|
| 2187 |
+
|
| 2188 |
+
def test_Integer_ceiling_floor():
|
| 2189 |
+
a = Integer(4)
|
| 2190 |
+
|
| 2191 |
+
assert a.floor() == a
|
| 2192 |
+
assert a.ceiling() == a
|
| 2193 |
+
|
| 2194 |
+
|
| 2195 |
+
def test_ComplexInfinity():
|
| 2196 |
+
assert zoo.floor() is zoo
|
| 2197 |
+
assert zoo.ceiling() is zoo
|
| 2198 |
+
assert zoo**zoo is S.NaN
|
| 2199 |
+
|
| 2200 |
+
|
| 2201 |
+
def test_Infinity_floor_ceiling_power():
|
| 2202 |
+
assert oo.floor() is oo
|
| 2203 |
+
assert oo.ceiling() is oo
|
| 2204 |
+
assert oo**S.NaN is S.NaN
|
| 2205 |
+
assert oo**zoo is S.NaN
|
| 2206 |
+
|
| 2207 |
+
|
| 2208 |
+
def test_One_power():
|
| 2209 |
+
assert S.One**12 is S.One
|
| 2210 |
+
assert S.NegativeOne**S.NaN is S.NaN
|
| 2211 |
+
|
| 2212 |
+
|
| 2213 |
+
def test_NegativeInfinity():
|
| 2214 |
+
assert (-oo).floor() is -oo
|
| 2215 |
+
assert (-oo).ceiling() is -oo
|
| 2216 |
+
assert (-oo)**11 is -oo
|
| 2217 |
+
assert (-oo)**12 is oo
|
| 2218 |
+
|
| 2219 |
+
|
| 2220 |
+
def test_issue_6133():
|
| 2221 |
+
raises(TypeError, lambda: (-oo < None))
|
| 2222 |
+
raises(TypeError, lambda: (S(-2) < None))
|
| 2223 |
+
raises(TypeError, lambda: (oo < None))
|
| 2224 |
+
raises(TypeError, lambda: (oo > None))
|
| 2225 |
+
raises(TypeError, lambda: (S(2) < None))
|
| 2226 |
+
|
| 2227 |
+
|
| 2228 |
+
def test_abc():
|
| 2229 |
+
x = numbers.Float(5)
|
| 2230 |
+
assert(isinstance(x, nums.Number))
|
| 2231 |
+
assert(isinstance(x, numbers.Number))
|
| 2232 |
+
assert(isinstance(x, nums.Real))
|
| 2233 |
+
y = numbers.Rational(1, 3)
|
| 2234 |
+
assert(isinstance(y, nums.Number))
|
| 2235 |
+
assert(y.numerator == 1)
|
| 2236 |
+
assert(y.denominator == 3)
|
| 2237 |
+
assert(isinstance(y, nums.Rational))
|
| 2238 |
+
z = numbers.Integer(3)
|
| 2239 |
+
assert(isinstance(z, nums.Number))
|
| 2240 |
+
assert(isinstance(z, numbers.Number))
|
| 2241 |
+
assert(isinstance(z, nums.Rational))
|
| 2242 |
+
assert(isinstance(z, numbers.Rational))
|
| 2243 |
+
assert(isinstance(z, nums.Integral))
|
| 2244 |
+
|
| 2245 |
+
|
| 2246 |
+
def test_floordiv():
|
| 2247 |
+
assert S(2)//S.Half == 4
|
| 2248 |
+
|
| 2249 |
+
|
| 2250 |
+
def test_negation():
|
| 2251 |
+
assert -S.Zero is S.Zero
|
| 2252 |
+
assert -Float(0) is not S.Zero and -Float(0) == 0.0
|
| 2253 |
+
|
| 2254 |
+
|
| 2255 |
+
def test_exponentiation_of_0():
|
| 2256 |
+
x = Symbol('x')
|
| 2257 |
+
assert 0**-x == zoo**x
|
| 2258 |
+
assert unchanged(Pow, 0, x)
|
| 2259 |
+
x = Symbol('x', zero=True)
|
| 2260 |
+
assert 0**-x == S.One
|
| 2261 |
+
assert 0**x == S.One
|
| 2262 |
+
|
| 2263 |
+
|
| 2264 |
+
def test_int_valued():
|
| 2265 |
+
x = Symbol('x')
|
| 2266 |
+
assert int_valued(x) == False
|
| 2267 |
+
assert int_valued(S.Half) == False
|
| 2268 |
+
assert int_valued(S.One) == True
|
| 2269 |
+
assert int_valued(Float(1)) == True
|
| 2270 |
+
assert int_valued(Float(1.1)) == False
|
| 2271 |
+
assert int_valued(pi) == False
|
| 2272 |
+
|
| 2273 |
+
|
| 2274 |
+
def test_equal_valued():
|
| 2275 |
+
x = Symbol('x')
|
| 2276 |
+
|
| 2277 |
+
equal_values = [
|
| 2278 |
+
[1, 1.0, S(1), S(1.0), S(1).n(5)],
|
| 2279 |
+
[2, 2.0, S(2), S(2.0), S(2).n(5)],
|
| 2280 |
+
[-1, -1.0, -S(1), -S(1.0), -S(1).n(5)],
|
| 2281 |
+
[0.5, S(0.5), S(1)/2],
|
| 2282 |
+
[-0.5, -S(0.5), -S(1)/2],
|
| 2283 |
+
[0, 0.0, S(0), S(0.0), S(0).n()],
|
| 2284 |
+
[pi], [pi.n()], # <-- not equal
|
| 2285 |
+
[S(1)/10], [0.1, S(0.1)], # <-- not equal
|
| 2286 |
+
[S(0.1).n(5)],
|
| 2287 |
+
[oo],
|
| 2288 |
+
[cos(x/2)], [cos(0.5*x)], # <-- no recursion
|
| 2289 |
+
]
|
| 2290 |
+
|
| 2291 |
+
for m, values_m in enumerate(equal_values):
|
| 2292 |
+
for value_i in values_m:
|
| 2293 |
+
|
| 2294 |
+
# All values in same list equal
|
| 2295 |
+
for value_j in values_m:
|
| 2296 |
+
assert equal_valued(value_i, value_j) is True
|
| 2297 |
+
|
| 2298 |
+
# Not equal to anything in any other list:
|
| 2299 |
+
for n, values_n in enumerate(equal_values):
|
| 2300 |
+
if n == m:
|
| 2301 |
+
continue
|
| 2302 |
+
for value_j in values_n:
|
| 2303 |
+
assert equal_valued(value_i, value_j) is False
|
| 2304 |
+
|
| 2305 |
+
|
| 2306 |
+
def test_all_close():
|
| 2307 |
+
x = Symbol('x')
|
| 2308 |
+
y = Symbol('y')
|
| 2309 |
+
z = Symbol('z')
|
| 2310 |
+
assert all_close(2, 2) is True
|
| 2311 |
+
assert all_close(2, 2.0000) is True
|
| 2312 |
+
assert all_close(2, 2.0001) is False
|
| 2313 |
+
assert all_close(1/3, 1/3.0001) is False
|
| 2314 |
+
assert all_close(1/3, 1/3.0001, 1e-3, 1e-3) is True
|
| 2315 |
+
assert all_close(1/3, Rational(1, 3)) is True
|
| 2316 |
+
assert all_close(0.1*exp(0.2*x), exp(x/5)/10) is True
|
| 2317 |
+
# The expressions should be structurally the same modulo identity:
|
| 2318 |
+
assert all_close(1.4142135623730951, sqrt(2)) is False
|
| 2319 |
+
assert all_close(1.4142135623730951, sqrt(2).evalf()) is True
|
| 2320 |
+
assert all_close(x + 1e-20, x) is True
|
| 2321 |
+
# We should be able to match terms of an Add/Mul in any order
|
| 2322 |
+
assert all_close(Add(1, 2, evaluate=False), Add(2, 1, evaluate=False))
|
| 2323 |
+
# coverage
|
| 2324 |
+
assert not all_close(2*x, 3*x)
|
| 2325 |
+
assert all_close(2*x, 3*x, 1)
|
| 2326 |
+
assert not all_close(2*x, 3*x, 0, 0.5)
|
| 2327 |
+
assert all_close(2*x, 3*x, 0, 1)
|
| 2328 |
+
assert not all_close(y*x, z*x)
|
| 2329 |
+
assert all_close(2*x*exp(1.0*x), 2.0*x*exp(x))
|
| 2330 |
+
assert not all_close(2*x*exp(1.0*x), 2.0*x*exp(2.*x))
|
| 2331 |
+
assert all_close(x + 2.*y, 1.*x + 2*y)
|
| 2332 |
+
assert all_close(x + exp(2.*x)*y, 1.*x + exp(2*x)*y)
|
| 2333 |
+
assert not all_close(x + exp(2.*x)*y, 1.*x + 2*exp(2*x)*y)
|
| 2334 |
+
assert not all_close(x + exp(2.*x)*y, 1.*x + exp(3*x)*y)
|
| 2335 |
+
assert not all_close(x + 2.*y, 1.*x + 3*y)
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_operations.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.expr import Expr
|
| 2 |
+
from sympy.core.numbers import Integer
|
| 3 |
+
from sympy.core.singleton import S
|
| 4 |
+
from sympy.core.symbol import (Symbol, symbols)
|
| 5 |
+
from sympy.core.operations import AssocOp, LatticeOp
|
| 6 |
+
from sympy.testing.pytest import raises
|
| 7 |
+
from sympy.core.sympify import SympifyError
|
| 8 |
+
from sympy.core.add import Add, add
|
| 9 |
+
from sympy.core.mul import Mul, mul
|
| 10 |
+
|
| 11 |
+
# create the simplest possible Lattice class
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class join(LatticeOp):
|
| 15 |
+
zero = Integer(0)
|
| 16 |
+
identity = Integer(1)
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def test_lattice_simple():
|
| 20 |
+
assert join(join(2, 3), 4) == join(2, join(3, 4))
|
| 21 |
+
assert join(2, 3) == join(3, 2)
|
| 22 |
+
assert join(0, 2) == 0
|
| 23 |
+
assert join(1, 2) == 2
|
| 24 |
+
assert join(2, 2) == 2
|
| 25 |
+
|
| 26 |
+
assert join(join(2, 3), 4) == join(2, 3, 4)
|
| 27 |
+
assert join() == 1
|
| 28 |
+
assert join(4) == 4
|
| 29 |
+
assert join(1, 4, 2, 3, 1, 3, 2) == join(2, 3, 4)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def test_lattice_shortcircuit():
|
| 33 |
+
raises(SympifyError, lambda: join(object))
|
| 34 |
+
assert join(0, object) == 0
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def test_lattice_print():
|
| 38 |
+
assert str(join(5, 4, 3, 2)) == 'join(2, 3, 4, 5)'
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def test_lattice_make_args():
|
| 42 |
+
assert join.make_args(join(2, 3, 4)) == {S(2), S(3), S(4)}
|
| 43 |
+
assert join.make_args(0) == {0}
|
| 44 |
+
assert list(join.make_args(0))[0] is S.Zero
|
| 45 |
+
assert Add.make_args(0)[0] is S.Zero
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def test_issue_14025():
|
| 49 |
+
a, b, c, d = symbols('a,b,c,d', commutative=False)
|
| 50 |
+
assert Mul(a, b, c).has(c*b) == False
|
| 51 |
+
assert Mul(a, b, c).has(b*c) == True
|
| 52 |
+
assert Mul(a, b, c, d).has(b*c*d) == True
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def test_AssocOp_flatten():
|
| 56 |
+
a, b, c, d = symbols('a,b,c,d')
|
| 57 |
+
|
| 58 |
+
class MyAssoc(AssocOp):
|
| 59 |
+
identity = S.One
|
| 60 |
+
|
| 61 |
+
assert MyAssoc(a, MyAssoc(b, c)).args == \
|
| 62 |
+
MyAssoc(MyAssoc(a, b), c).args == \
|
| 63 |
+
MyAssoc(MyAssoc(a, b, c)).args == \
|
| 64 |
+
MyAssoc(a, b, c).args == \
|
| 65 |
+
(a, b, c)
|
| 66 |
+
u = MyAssoc(b, c)
|
| 67 |
+
v = MyAssoc(u, d, evaluate=False)
|
| 68 |
+
assert v.args == (u, d)
|
| 69 |
+
# like Add, any unevaluated outer call will flatten inner args
|
| 70 |
+
assert MyAssoc(a, v).args == (a, b, c, d)
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def test_add_dispatcher():
|
| 74 |
+
|
| 75 |
+
class NewBase(Expr):
|
| 76 |
+
@property
|
| 77 |
+
def _add_handler(self):
|
| 78 |
+
return NewAdd
|
| 79 |
+
class NewAdd(NewBase, Add):
|
| 80 |
+
pass
|
| 81 |
+
add.register_handlerclass((Add, NewAdd), NewAdd)
|
| 82 |
+
|
| 83 |
+
a, b = Symbol('a'), NewBase()
|
| 84 |
+
|
| 85 |
+
# Add called as fallback
|
| 86 |
+
assert add(1, 2) == Add(1, 2)
|
| 87 |
+
assert add(a, a) == Add(a, a)
|
| 88 |
+
|
| 89 |
+
# selection by registered priority
|
| 90 |
+
assert add(a,b,a) == NewAdd(2*a, b)
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def test_mul_dispatcher():
|
| 94 |
+
|
| 95 |
+
class NewBase(Expr):
|
| 96 |
+
@property
|
| 97 |
+
def _mul_handler(self):
|
| 98 |
+
return NewMul
|
| 99 |
+
class NewMul(NewBase, Mul):
|
| 100 |
+
pass
|
| 101 |
+
mul.register_handlerclass((Mul, NewMul), NewMul)
|
| 102 |
+
|
| 103 |
+
a, b = Symbol('a'), NewBase()
|
| 104 |
+
|
| 105 |
+
# Mul called as fallback
|
| 106 |
+
assert mul(1, 2) == Mul(1, 2)
|
| 107 |
+
assert mul(a, a) == Mul(a, a)
|
| 108 |
+
|
| 109 |
+
# selection by registered priority
|
| 110 |
+
assert mul(a,b,a) == NewMul(a**2, b)
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_parameters.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.abc import x, y
|
| 2 |
+
from sympy.core.parameters import evaluate
|
| 3 |
+
from sympy.core import Mul, Add, Pow, S
|
| 4 |
+
from sympy.core.numbers import oo
|
| 5 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 6 |
+
|
| 7 |
+
def test_add():
|
| 8 |
+
with evaluate(False):
|
| 9 |
+
p = oo - oo
|
| 10 |
+
assert isinstance(p, Add) and p.args == (oo, -oo)
|
| 11 |
+
p = 5 - oo
|
| 12 |
+
assert isinstance(p, Add) and p.args == (-oo, 5)
|
| 13 |
+
p = oo - 5
|
| 14 |
+
assert isinstance(p, Add) and p.args == (oo, -5)
|
| 15 |
+
p = oo + 5
|
| 16 |
+
assert isinstance(p, Add) and p.args == (oo, 5)
|
| 17 |
+
p = 5 + oo
|
| 18 |
+
assert isinstance(p, Add) and p.args == (oo, 5)
|
| 19 |
+
p = -oo + 5
|
| 20 |
+
assert isinstance(p, Add) and p.args == (-oo, 5)
|
| 21 |
+
p = -5 - oo
|
| 22 |
+
assert isinstance(p, Add) and p.args == (-oo, -5)
|
| 23 |
+
|
| 24 |
+
with evaluate(False):
|
| 25 |
+
expr = x + x
|
| 26 |
+
assert isinstance(expr, Add)
|
| 27 |
+
assert expr.args == (x, x)
|
| 28 |
+
|
| 29 |
+
with evaluate(True):
|
| 30 |
+
assert (x + x).args == (2, x)
|
| 31 |
+
|
| 32 |
+
assert (x + x).args == (x, x)
|
| 33 |
+
|
| 34 |
+
assert isinstance(x + x, Mul)
|
| 35 |
+
|
| 36 |
+
with evaluate(False):
|
| 37 |
+
assert S.One + 1 == Add(1, 1)
|
| 38 |
+
assert 1 + S.One == Add(1, 1)
|
| 39 |
+
|
| 40 |
+
assert S(4) - 3 == Add(4, -3)
|
| 41 |
+
assert -3 + S(4) == Add(4, -3)
|
| 42 |
+
|
| 43 |
+
assert S(2) * 4 == Mul(2, 4)
|
| 44 |
+
assert 4 * S(2) == Mul(2, 4)
|
| 45 |
+
|
| 46 |
+
assert S(6) / 3 == Mul(6, Pow(3, -1))
|
| 47 |
+
assert S.One / 3 * 6 == Mul(S.One / 3, 6)
|
| 48 |
+
|
| 49 |
+
assert 9 ** S(2) == Pow(9, 2)
|
| 50 |
+
assert S(2) ** 9 == Pow(2, 9)
|
| 51 |
+
|
| 52 |
+
assert S(2) / 2 == Mul(2, Pow(2, -1))
|
| 53 |
+
assert S.One / 2 * 2 == Mul(S.One / 2, 2)
|
| 54 |
+
|
| 55 |
+
assert S(2) / 3 + 1 == Add(S(2) / 3, 1)
|
| 56 |
+
assert 1 + S(2) / 3 == Add(1, S(2) / 3)
|
| 57 |
+
|
| 58 |
+
assert S(4) / 7 - 3 == Add(S(4) / 7, -3)
|
| 59 |
+
assert -3 + S(4) / 7 == Add(-3, S(4) / 7)
|
| 60 |
+
|
| 61 |
+
assert S(2) / 4 * 4 == Mul(S(2) / 4, 4)
|
| 62 |
+
assert 4 * (S(2) / 4) == Mul(4, S(2) / 4)
|
| 63 |
+
|
| 64 |
+
assert S(6) / 3 == Mul(6, Pow(3, -1))
|
| 65 |
+
assert S.One / 3 * 6 == Mul(S.One / 3, 6)
|
| 66 |
+
|
| 67 |
+
assert S.One / 3 + sqrt(3) == Add(S.One / 3, sqrt(3))
|
| 68 |
+
assert sqrt(3) + S.One / 3 == Add(sqrt(3), S.One / 3)
|
| 69 |
+
|
| 70 |
+
assert S.One / 2 * 10.333 == Mul(S.One / 2, 10.333)
|
| 71 |
+
assert 10.333 * (S.One / 2) == Mul(10.333, S.One / 2)
|
| 72 |
+
|
| 73 |
+
assert sqrt(2) * sqrt(2) == Mul(sqrt(2), sqrt(2))
|
| 74 |
+
|
| 75 |
+
assert S.One / 2 + x == Add(S.One / 2, x)
|
| 76 |
+
assert x + S.One / 2 == Add(x, S.One / 2)
|
| 77 |
+
|
| 78 |
+
assert S.One / x * x == Mul(S.One / x, x)
|
| 79 |
+
assert x * (S.One / x) == Mul(x, Pow(x, -1))
|
| 80 |
+
|
| 81 |
+
assert S.One / 3 == Pow(3, -1)
|
| 82 |
+
assert S.One / x == Pow(x, -1)
|
| 83 |
+
assert 1 / S(3) == Pow(3, -1)
|
| 84 |
+
assert 1 / x == Pow(x, -1)
|
| 85 |
+
|
| 86 |
+
def test_nested():
|
| 87 |
+
with evaluate(False):
|
| 88 |
+
expr = (x + x) + (y + y)
|
| 89 |
+
assert expr.args == ((x + x), (y + y))
|
| 90 |
+
assert expr.args[0].args == (x, x)
|
| 91 |
+
|
| 92 |
+
def test_reentrantcy():
|
| 93 |
+
with evaluate(False):
|
| 94 |
+
expr = x + x
|
| 95 |
+
assert expr.args == (x, x)
|
| 96 |
+
with evaluate(True):
|
| 97 |
+
expr = x + x
|
| 98 |
+
assert expr.args == (2, x)
|
| 99 |
+
expr = x + x
|
| 100 |
+
assert expr.args == (x, x)
|
| 101 |
+
|
| 102 |
+
def test_reusability():
|
| 103 |
+
f = evaluate(False)
|
| 104 |
+
|
| 105 |
+
with f:
|
| 106 |
+
expr = x + x
|
| 107 |
+
assert expr.args == (x, x)
|
| 108 |
+
|
| 109 |
+
expr = x + x
|
| 110 |
+
assert expr.args == (2, x)
|
| 111 |
+
|
| 112 |
+
with f:
|
| 113 |
+
expr = x + x
|
| 114 |
+
assert expr.args == (x, x)
|
| 115 |
+
|
| 116 |
+
# Assure reentrancy with reusability
|
| 117 |
+
ctx = evaluate(False)
|
| 118 |
+
with ctx:
|
| 119 |
+
expr = x + x
|
| 120 |
+
assert expr.args == (x, x)
|
| 121 |
+
with ctx:
|
| 122 |
+
expr = x + x
|
| 123 |
+
assert expr.args == (x, x)
|
| 124 |
+
|
| 125 |
+
expr = x + x
|
| 126 |
+
assert expr.args == (2, x)
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_power.py
ADDED
|
@@ -0,0 +1,670 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core import (
|
| 2 |
+
Basic, Rational, Symbol, S, Float, Integer, Mul, Number, Pow,
|
| 3 |
+
Expr, I, nan, pi, symbols, oo, zoo, N)
|
| 4 |
+
from sympy.core.parameters import global_parameters
|
| 5 |
+
from sympy.core.tests.test_evalf import NS
|
| 6 |
+
from sympy.core.function import expand_multinomial
|
| 7 |
+
from sympy.functions.elementary.miscellaneous import sqrt, cbrt
|
| 8 |
+
from sympy.functions.elementary.exponential import exp, log
|
| 9 |
+
from sympy.functions.special.error_functions import erf
|
| 10 |
+
from sympy.functions.elementary.trigonometric import (
|
| 11 |
+
sin, cos, tan, sec, csc, atan)
|
| 12 |
+
from sympy.functions.elementary.hyperbolic import cosh, sinh, tanh
|
| 13 |
+
from sympy.polys import Poly
|
| 14 |
+
from sympy.series.order import O
|
| 15 |
+
from sympy.sets import FiniteSet
|
| 16 |
+
from sympy.core.power import power
|
| 17 |
+
from sympy.core.intfunc import integer_nthroot
|
| 18 |
+
from sympy.testing.pytest import warns, _both_exp_pow
|
| 19 |
+
from sympy.utilities.exceptions import SymPyDeprecationWarning
|
| 20 |
+
from sympy.abc import a, b, c, x, y
|
| 21 |
+
from sympy.core.numbers import all_close
|
| 22 |
+
|
| 23 |
+
def test_rational():
|
| 24 |
+
a = Rational(1, 5)
|
| 25 |
+
|
| 26 |
+
r = sqrt(5)/5
|
| 27 |
+
assert sqrt(a) == r
|
| 28 |
+
assert 2*sqrt(a) == 2*r
|
| 29 |
+
|
| 30 |
+
r = a*a**S.Half
|
| 31 |
+
assert a**Rational(3, 2) == r
|
| 32 |
+
assert 2*a**Rational(3, 2) == 2*r
|
| 33 |
+
|
| 34 |
+
r = a**5*a**Rational(2, 3)
|
| 35 |
+
assert a**Rational(17, 3) == r
|
| 36 |
+
assert 2 * a**Rational(17, 3) == 2*r
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def test_large_rational():
|
| 40 |
+
e = (Rational(123712**12 - 1, 7) + Rational(1, 7))**Rational(1, 3)
|
| 41 |
+
assert e == 234232585392159195136 * (Rational(1, 7)**Rational(1, 3))
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def test_negative_real():
|
| 45 |
+
def feq(a, b):
|
| 46 |
+
return abs(a - b) < 1E-10
|
| 47 |
+
|
| 48 |
+
assert feq(S.One / Float(-0.5), -Integer(2))
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def test_expand():
|
| 52 |
+
assert (2**(-1 - x)).expand() == S.Half*2**(-x)
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def test_issue_3449():
|
| 56 |
+
#test if powers are simplified correctly
|
| 57 |
+
#see also issue 3995
|
| 58 |
+
assert ((x**Rational(1, 3))**Rational(2)) == x**Rational(2, 3)
|
| 59 |
+
assert (
|
| 60 |
+
(x**Rational(3))**Rational(2, 5)) == (x**Rational(3))**Rational(2, 5)
|
| 61 |
+
|
| 62 |
+
a = Symbol('a', real=True)
|
| 63 |
+
b = Symbol('b', real=True)
|
| 64 |
+
assert (a**2)**b == (abs(a)**b)**2
|
| 65 |
+
assert sqrt(1/a) != 1/sqrt(a) # e.g. for a = -1
|
| 66 |
+
assert (a**3)**Rational(1, 3) != a
|
| 67 |
+
assert (x**a)**b != x**(a*b) # e.g. x = -1, a=2, b=1/2
|
| 68 |
+
assert (x**.5)**b == x**(.5*b)
|
| 69 |
+
assert (x**.5)**.5 == x**.25
|
| 70 |
+
assert (x**2.5)**.5 != x**1.25 # e.g. for x = 5*I
|
| 71 |
+
|
| 72 |
+
k = Symbol('k', integer=True)
|
| 73 |
+
m = Symbol('m', integer=True)
|
| 74 |
+
assert (x**k)**m == x**(k*m)
|
| 75 |
+
assert Number(5)**Rational(2, 3) == Number(25)**Rational(1, 3)
|
| 76 |
+
|
| 77 |
+
assert (x**.5)**2 == x**1.0
|
| 78 |
+
assert (x**2)**k == (x**k)**2 == x**(2*k)
|
| 79 |
+
|
| 80 |
+
a = Symbol('a', positive=True)
|
| 81 |
+
assert (a**3)**Rational(2, 5) == a**Rational(6, 5)
|
| 82 |
+
assert (a**2)**b == (a**b)**2
|
| 83 |
+
assert (a**Rational(2, 3))**x == a**(x*Rational(2, 3)) != (a**x)**Rational(2, 3)
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def test_issue_3866():
|
| 87 |
+
assert --sqrt(sqrt(5) - 1) == sqrt(sqrt(5) - 1)
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def test_negative_one():
|
| 91 |
+
x = Symbol('x', complex=True)
|
| 92 |
+
y = Symbol('y', complex=True)
|
| 93 |
+
assert 1/x**y == x**(-y)
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def test_issue_4362():
|
| 97 |
+
neg = Symbol('neg', negative=True)
|
| 98 |
+
nonneg = Symbol('nonneg', nonnegative=True)
|
| 99 |
+
any = Symbol('any')
|
| 100 |
+
num, den = sqrt(1/neg).as_numer_denom()
|
| 101 |
+
assert num == sqrt(-1)
|
| 102 |
+
assert den == sqrt(-neg)
|
| 103 |
+
num, den = sqrt(1/nonneg).as_numer_denom()
|
| 104 |
+
assert num == 1
|
| 105 |
+
assert den == sqrt(nonneg)
|
| 106 |
+
num, den = sqrt(1/any).as_numer_denom()
|
| 107 |
+
assert num == sqrt(1/any)
|
| 108 |
+
assert den == 1
|
| 109 |
+
|
| 110 |
+
def eqn(num, den, pow):
|
| 111 |
+
return (num/den)**pow
|
| 112 |
+
npos = 1
|
| 113 |
+
nneg = -1
|
| 114 |
+
dpos = 2 - sqrt(3)
|
| 115 |
+
dneg = 1 - sqrt(3)
|
| 116 |
+
assert dpos > 0 and dneg < 0 and npos > 0 and nneg < 0
|
| 117 |
+
# pos or neg integer
|
| 118 |
+
eq = eqn(npos, dpos, 2)
|
| 119 |
+
assert eq.is_Pow and eq.as_numer_denom() == (1, dpos**2)
|
| 120 |
+
eq = eqn(npos, dneg, 2)
|
| 121 |
+
assert eq.is_Pow and eq.as_numer_denom() == (1, dneg**2)
|
| 122 |
+
eq = eqn(nneg, dpos, 2)
|
| 123 |
+
assert eq.is_Pow and eq.as_numer_denom() == (1, dpos**2)
|
| 124 |
+
eq = eqn(nneg, dneg, 2)
|
| 125 |
+
assert eq.is_Pow and eq.as_numer_denom() == (1, dneg**2)
|
| 126 |
+
eq = eqn(npos, dpos, -2)
|
| 127 |
+
assert eq.is_Pow and eq.as_numer_denom() == (dpos**2, 1)
|
| 128 |
+
eq = eqn(npos, dneg, -2)
|
| 129 |
+
assert eq.is_Pow and eq.as_numer_denom() == (dneg**2, 1)
|
| 130 |
+
eq = eqn(nneg, dpos, -2)
|
| 131 |
+
assert eq.is_Pow and eq.as_numer_denom() == (dpos**2, 1)
|
| 132 |
+
eq = eqn(nneg, dneg, -2)
|
| 133 |
+
assert eq.is_Pow and eq.as_numer_denom() == (dneg**2, 1)
|
| 134 |
+
# pos or neg rational
|
| 135 |
+
pow = S.Half
|
| 136 |
+
eq = eqn(npos, dpos, pow)
|
| 137 |
+
assert eq.is_Pow and eq.as_numer_denom() == (npos**pow, dpos**pow)
|
| 138 |
+
eq = eqn(npos, dneg, pow)
|
| 139 |
+
assert eq.is_Pow is False and eq.as_numer_denom() == ((-npos)**pow, (-dneg)**pow)
|
| 140 |
+
eq = eqn(nneg, dpos, pow)
|
| 141 |
+
assert not eq.is_Pow or eq.as_numer_denom() == (nneg**pow, dpos**pow)
|
| 142 |
+
eq = eqn(nneg, dneg, pow)
|
| 143 |
+
assert eq.is_Pow and eq.as_numer_denom() == ((-nneg)**pow, (-dneg)**pow)
|
| 144 |
+
eq = eqn(npos, dpos, -pow)
|
| 145 |
+
assert eq.is_Pow and eq.as_numer_denom() == (dpos**pow, npos**pow)
|
| 146 |
+
eq = eqn(npos, dneg, -pow)
|
| 147 |
+
assert eq.is_Pow is False and eq.as_numer_denom() == (-(-npos)**pow*(-dneg)**pow, npos)
|
| 148 |
+
eq = eqn(nneg, dpos, -pow)
|
| 149 |
+
assert not eq.is_Pow or eq.as_numer_denom() == (dpos**pow, nneg**pow)
|
| 150 |
+
eq = eqn(nneg, dneg, -pow)
|
| 151 |
+
assert eq.is_Pow and eq.as_numer_denom() == ((-dneg)**pow, (-nneg)**pow)
|
| 152 |
+
# unknown exponent
|
| 153 |
+
pow = 2*any
|
| 154 |
+
eq = eqn(npos, dpos, pow)
|
| 155 |
+
assert eq.is_Pow and eq.as_numer_denom() == (npos**pow, dpos**pow)
|
| 156 |
+
eq = eqn(npos, dneg, pow)
|
| 157 |
+
assert eq.is_Pow and eq.as_numer_denom() == ((-npos)**pow, (-dneg)**pow)
|
| 158 |
+
eq = eqn(nneg, dpos, pow)
|
| 159 |
+
assert eq.is_Pow and eq.as_numer_denom() == (nneg**pow, dpos**pow)
|
| 160 |
+
eq = eqn(nneg, dneg, pow)
|
| 161 |
+
assert eq.is_Pow and eq.as_numer_denom() == ((-nneg)**pow, (-dneg)**pow)
|
| 162 |
+
eq = eqn(npos, dpos, -pow)
|
| 163 |
+
assert eq.as_numer_denom() == (dpos**pow, npos**pow)
|
| 164 |
+
eq = eqn(npos, dneg, -pow)
|
| 165 |
+
assert eq.is_Pow and eq.as_numer_denom() == ((-dneg)**pow, (-npos)**pow)
|
| 166 |
+
eq = eqn(nneg, dpos, -pow)
|
| 167 |
+
assert eq.is_Pow and eq.as_numer_denom() == (dpos**pow, nneg**pow)
|
| 168 |
+
eq = eqn(nneg, dneg, -pow)
|
| 169 |
+
assert eq.is_Pow and eq.as_numer_denom() == ((-dneg)**pow, (-nneg)**pow)
|
| 170 |
+
|
| 171 |
+
assert ((1/(1 + x/3))**(-S.One)).as_numer_denom() == (3 + x, 3)
|
| 172 |
+
notp = Symbol('notp', positive=False) # not positive does not imply real
|
| 173 |
+
b = ((1 + x/notp)**-2)
|
| 174 |
+
assert (b**(-y)).as_numer_denom() == (1, b**y)
|
| 175 |
+
assert (b**(-S.One)).as_numer_denom() == ((notp + x)**2, notp**2)
|
| 176 |
+
nonp = Symbol('nonp', nonpositive=True)
|
| 177 |
+
assert (((1 + x/nonp)**-2)**(-S.One)).as_numer_denom() == ((-nonp -
|
| 178 |
+
x)**2, nonp**2)
|
| 179 |
+
|
| 180 |
+
n = Symbol('n', negative=True)
|
| 181 |
+
assert (x**n).as_numer_denom() == (1, x**-n)
|
| 182 |
+
assert sqrt(1/n).as_numer_denom() == (S.ImaginaryUnit, sqrt(-n))
|
| 183 |
+
n = Symbol('0 or neg', nonpositive=True)
|
| 184 |
+
# if x and n are split up without negating each term and n is negative
|
| 185 |
+
# then the answer might be wrong; if n is 0 it won't matter since
|
| 186 |
+
# 1/oo and 1/zoo are both zero as is sqrt(0)/sqrt(-x) unless x is also
|
| 187 |
+
# zero (in which case the negative sign doesn't matter):
|
| 188 |
+
# 1/sqrt(1/-1) = -I but sqrt(-1)/sqrt(1) = I
|
| 189 |
+
assert (1/sqrt(x/n)).as_numer_denom() == (sqrt(-n), sqrt(-x))
|
| 190 |
+
c = Symbol('c', complex=True)
|
| 191 |
+
e = sqrt(1/c)
|
| 192 |
+
assert e.as_numer_denom() == (e, 1)
|
| 193 |
+
i = Symbol('i', integer=True)
|
| 194 |
+
assert ((1 + x/y)**i).as_numer_denom() == ((x + y)**i, y**i)
|
| 195 |
+
|
| 196 |
+
|
| 197 |
+
def test_Pow_Expr_args():
|
| 198 |
+
bases = [Basic(), Poly(x, x), FiniteSet(x)]
|
| 199 |
+
for base in bases:
|
| 200 |
+
# The cache can mess with the stacklevel test
|
| 201 |
+
with warns(SymPyDeprecationWarning, test_stacklevel=False):
|
| 202 |
+
Pow(base, S.One)
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
def test_Pow_signs():
|
| 206 |
+
"""Cf. issues 4595 and 5250"""
|
| 207 |
+
n = Symbol('n', even=True)
|
| 208 |
+
assert (3 - y)**2 != (y - 3)**2
|
| 209 |
+
assert (3 - y)**n != (y - 3)**n
|
| 210 |
+
assert (-3 + y - x)**2 != (3 - y + x)**2
|
| 211 |
+
assert (y - 3)**3 != -(3 - y)**3
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def test_power_with_noncommutative_mul_as_base():
|
| 215 |
+
x = Symbol('x', commutative=False)
|
| 216 |
+
y = Symbol('y', commutative=False)
|
| 217 |
+
assert not (x*y)**3 == x**3*y**3
|
| 218 |
+
assert (2*x*y)**3 == 8*(x*y)**3
|
| 219 |
+
|
| 220 |
+
|
| 221 |
+
@_both_exp_pow
|
| 222 |
+
def test_power_rewrite_exp():
|
| 223 |
+
assert (I**I).rewrite(exp) == exp(-pi/2)
|
| 224 |
+
|
| 225 |
+
expr = (2 + 3*I)**(4 + 5*I)
|
| 226 |
+
assert expr.rewrite(exp) == exp((4 + 5*I)*(log(sqrt(13)) + I*atan(Rational(3, 2))))
|
| 227 |
+
assert expr.rewrite(exp).expand() == \
|
| 228 |
+
169*exp(5*I*log(13)/2)*exp(4*I*atan(Rational(3, 2)))*exp(-5*atan(Rational(3, 2)))
|
| 229 |
+
|
| 230 |
+
assert ((6 + 7*I)**5).rewrite(exp) == 7225*sqrt(85)*exp(5*I*atan(Rational(7, 6)))
|
| 231 |
+
|
| 232 |
+
expr = 5**(6 + 7*I)
|
| 233 |
+
assert expr.rewrite(exp) == exp((6 + 7*I)*log(5))
|
| 234 |
+
assert expr.rewrite(exp).expand() == 15625*exp(7*I*log(5))
|
| 235 |
+
|
| 236 |
+
assert Pow(123, 789, evaluate=False).rewrite(exp) == 123**789
|
| 237 |
+
assert (1**I).rewrite(exp) == 1**I
|
| 238 |
+
assert (0**I).rewrite(exp) == 0**I
|
| 239 |
+
|
| 240 |
+
expr = (-2)**(2 + 5*I)
|
| 241 |
+
assert expr.rewrite(exp) == exp((2 + 5*I)*(log(2) + I*pi))
|
| 242 |
+
assert expr.rewrite(exp).expand() == 4*exp(-5*pi)*exp(5*I*log(2))
|
| 243 |
+
|
| 244 |
+
assert ((-2)**S(-5)).rewrite(exp) == (-2)**S(-5)
|
| 245 |
+
|
| 246 |
+
x, y = symbols('x y')
|
| 247 |
+
assert (x**y).rewrite(exp) == exp(y*log(x))
|
| 248 |
+
if global_parameters.exp_is_pow:
|
| 249 |
+
assert (7**x).rewrite(exp) == Pow(S.Exp1, x*log(7), evaluate=False)
|
| 250 |
+
else:
|
| 251 |
+
assert (7**x).rewrite(exp) == exp(x*log(7), evaluate=False)
|
| 252 |
+
assert ((2 + 3*I)**x).rewrite(exp) == exp(x*(log(sqrt(13)) + I*atan(Rational(3, 2))))
|
| 253 |
+
assert (y**(5 + 6*I)).rewrite(exp) == exp(log(y)*(5 + 6*I))
|
| 254 |
+
|
| 255 |
+
assert all((1/func(x)).rewrite(exp) == 1/(func(x).rewrite(exp)) for func in
|
| 256 |
+
(sin, cos, tan, sec, csc, sinh, cosh, tanh))
|
| 257 |
+
|
| 258 |
+
|
| 259 |
+
def test_zero():
|
| 260 |
+
assert 0**x != 0
|
| 261 |
+
assert 0**(2*x) == 0**x
|
| 262 |
+
assert 0**(1.0*x) == 0**x
|
| 263 |
+
assert 0**(2.0*x) == 0**x
|
| 264 |
+
assert (0**(2 - x)).as_base_exp() == (0, 2 - x)
|
| 265 |
+
assert 0**(x - 2) != S.Infinity**(2 - x)
|
| 266 |
+
assert 0**(2*x*y) == 0**(x*y)
|
| 267 |
+
assert 0**(-2*x*y) == S.ComplexInfinity**(x*y)
|
| 268 |
+
assert Float(0)**2 is not S.Zero
|
| 269 |
+
assert Float(0)**2 == 0.0
|
| 270 |
+
assert Float(0)**-2 is zoo
|
| 271 |
+
assert Float(0)**oo is S.Zero
|
| 272 |
+
|
| 273 |
+
#Test issue 19572
|
| 274 |
+
assert 0 ** -oo is zoo
|
| 275 |
+
assert power(0, -oo) is zoo
|
| 276 |
+
assert Float(0)**-oo is zoo
|
| 277 |
+
|
| 278 |
+
def test_pow_as_base_exp():
|
| 279 |
+
assert (S.Infinity**(2 - x)).as_base_exp() == (S.Infinity, 2 - x)
|
| 280 |
+
assert (S.Infinity**(x - 2)).as_base_exp() == (S.Infinity, x - 2)
|
| 281 |
+
p = S.Half**x
|
| 282 |
+
assert p.base, p.exp == p.as_base_exp() == (S(2), -x)
|
| 283 |
+
p = (S(3)/2)**x
|
| 284 |
+
assert p.base, p.exp == p.as_base_exp() == (3*S.Half, x)
|
| 285 |
+
p = (S(2)/3)**x
|
| 286 |
+
assert p.as_base_exp() == (S(2)/3, x)
|
| 287 |
+
assert p.base, p.exp == (S(2)/3, x)
|
| 288 |
+
# issue 8344:
|
| 289 |
+
assert Pow(1, 2, evaluate=False).as_base_exp() == (S.One, S(2))
|
| 290 |
+
|
| 291 |
+
|
| 292 |
+
def test_nseries():
|
| 293 |
+
assert sqrt(I*x - 1)._eval_nseries(x, 4, None, 1) == I + x/2 + I*x**2/8 - x**3/16 + O(x**4)
|
| 294 |
+
assert sqrt(I*x - 1)._eval_nseries(x, 4, None, -1) == -I - x/2 - I*x**2/8 + x**3/16 + O(x**4)
|
| 295 |
+
assert cbrt(I*x - 1)._eval_nseries(x, 4, None, 1) == (-1)**(S(1)/3) - (-1)**(S(5)/6)*x/3 + \
|
| 296 |
+
(-1)**(S(1)/3)*x**2/9 + 5*(-1)**(S(5)/6)*x**3/81 + O(x**4)
|
| 297 |
+
assert cbrt(I*x - 1)._eval_nseries(x, 4, None, -1) == -(-1)**(S(2)/3) - (-1)**(S(1)/6)*x/3 - \
|
| 298 |
+
(-1)**(S(2)/3)*x**2/9 + 5*(-1)**(S(1)/6)*x**3/81 + O(x**4)
|
| 299 |
+
assert (1 / (exp(-1/x) + 1/x))._eval_nseries(x, 2, None) == x + O(x**2)
|
| 300 |
+
# test issue 23752
|
| 301 |
+
assert sqrt(-I*x**2 + x - 3)._eval_nseries(x, 4, None, 1) == -sqrt(3)*I + sqrt(3)*I*x/6 - \
|
| 302 |
+
sqrt(3)*I*x**2*(-S(1)/72 + I/6) - sqrt(3)*I*x**3*(-S(1)/432 + I/36) + O(x**4)
|
| 303 |
+
assert sqrt(-I*x**2 + x - 3)._eval_nseries(x, 4, None, -1) == -sqrt(3)*I + sqrt(3)*I*x/6 - \
|
| 304 |
+
sqrt(3)*I*x**2*(-S(1)/72 + I/6) - sqrt(3)*I*x**3*(-S(1)/432 + I/36) + O(x**4)
|
| 305 |
+
assert cbrt(-I*x**2 + x - 3)._eval_nseries(x, 4, None, 1) == -(-1)**(S(2)/3)*3**(S(1)/3) + \
|
| 306 |
+
(-1)**(S(2)/3)*3**(S(1)/3)*x/9 - (-1)**(S(2)/3)*3**(S(1)/3)*x**2*(-S(1)/81 + I/9) - \
|
| 307 |
+
(-1)**(S(2)/3)*3**(S(1)/3)*x**3*(-S(5)/2187 + 2*I/81) + O(x**4)
|
| 308 |
+
assert cbrt(-I*x**2 + x - 3)._eval_nseries(x, 4, None, -1) == -(-1)**(S(2)/3)*3**(S(1)/3) + \
|
| 309 |
+
(-1)**(S(2)/3)*3**(S(1)/3)*x/9 - (-1)**(S(2)/3)*3**(S(1)/3)*x**2*(-S(1)/81 + I/9) - \
|
| 310 |
+
(-1)**(S(2)/3)*3**(S(1)/3)*x**3*(-S(5)/2187 + 2*I/81) + O(x**4)
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
def test_issue_6100_12942_4473():
|
| 314 |
+
assert x**1.0 != x
|
| 315 |
+
assert x != x**1.0
|
| 316 |
+
assert True != x**1.0
|
| 317 |
+
assert x**1.0 is not True
|
| 318 |
+
assert x is not True
|
| 319 |
+
assert x*y != (x*y)**1.0
|
| 320 |
+
# Pow != Symbol
|
| 321 |
+
assert (x**1.0)**1.0 != x
|
| 322 |
+
assert (x**1.0)**2.0 != x**2
|
| 323 |
+
b = Expr()
|
| 324 |
+
assert Pow(b, 1.0, evaluate=False) != b
|
| 325 |
+
# if the following gets distributed as a Mul (x**1.0*y**1.0 then
|
| 326 |
+
# __eq__ methods could be added to Symbol and Pow to detect the
|
| 327 |
+
# power-of-1.0 case.
|
| 328 |
+
assert ((x*y)**1.0).func is Pow
|
| 329 |
+
|
| 330 |
+
|
| 331 |
+
def test_issue_6208():
|
| 332 |
+
from sympy.functions.elementary.miscellaneous import root
|
| 333 |
+
assert sqrt(33**(I*9/10)) == -33**(I*9/20)
|
| 334 |
+
assert root((6*I)**(2*I), 3).as_base_exp()[1] == Rational(1, 3) # != 2*I/3
|
| 335 |
+
assert root((6*I)**(I/3), 3).as_base_exp()[1] == I/9
|
| 336 |
+
assert sqrt(exp(3*I)) == exp(3*I/2)
|
| 337 |
+
assert sqrt(-sqrt(3)*(1 + 2*I)) == sqrt(sqrt(3))*sqrt(-1 - 2*I)
|
| 338 |
+
assert sqrt(exp(5*I)) == -exp(5*I/2)
|
| 339 |
+
assert root(exp(5*I), 3).exp == Rational(1, 3)
|
| 340 |
+
|
| 341 |
+
|
| 342 |
+
def test_issue_6990():
|
| 343 |
+
assert (sqrt(a + b*x + x**2)).series(x, 0, 3).removeO() == \
|
| 344 |
+
sqrt(a)*x**2*(1/(2*a) - b**2/(8*a**2)) + sqrt(a) + b*x/(2*sqrt(a))
|
| 345 |
+
|
| 346 |
+
|
| 347 |
+
def test_issue_6068():
|
| 348 |
+
assert sqrt(sin(x)).series(x, 0, 7) == \
|
| 349 |
+
sqrt(x) - x**Rational(5, 2)/12 + x**Rational(9, 2)/1440 - \
|
| 350 |
+
x**Rational(13, 2)/24192 + O(x**7)
|
| 351 |
+
assert sqrt(sin(x)).series(x, 0, 9) == \
|
| 352 |
+
sqrt(x) - x**Rational(5, 2)/12 + x**Rational(9, 2)/1440 - \
|
| 353 |
+
x**Rational(13, 2)/24192 - 67*x**Rational(17, 2)/29030400 + O(x**9)
|
| 354 |
+
assert sqrt(sin(x**3)).series(x, 0, 19) == \
|
| 355 |
+
x**Rational(3, 2) - x**Rational(15, 2)/12 + x**Rational(27, 2)/1440 + O(x**19)
|
| 356 |
+
assert sqrt(sin(x**3)).series(x, 0, 20) == \
|
| 357 |
+
x**Rational(3, 2) - x**Rational(15, 2)/12 + x**Rational(27, 2)/1440 - \
|
| 358 |
+
x**Rational(39, 2)/24192 + O(x**20)
|
| 359 |
+
|
| 360 |
+
|
| 361 |
+
def test_issue_6782():
|
| 362 |
+
assert sqrt(sin(x**3)).series(x, 0, 7) == x**Rational(3, 2) + O(x**7)
|
| 363 |
+
assert sqrt(sin(x**4)).series(x, 0, 3) == x**2 + O(x**3)
|
| 364 |
+
|
| 365 |
+
|
| 366 |
+
def test_issue_6653():
|
| 367 |
+
assert (1 / sqrt(1 + sin(x**2))).series(x, 0, 3) == 1 - x**2/2 + O(x**3)
|
| 368 |
+
|
| 369 |
+
|
| 370 |
+
def test_issue_6429():
|
| 371 |
+
f = (c**2 + x)**(0.5)
|
| 372 |
+
assert f.series(x, x0=0, n=1) == (c**2)**0.5 + O(x)
|
| 373 |
+
assert f.taylor_term(0, x) == (c**2)**0.5
|
| 374 |
+
assert f.taylor_term(1, x) == 0.5*x*(c**2)**(-0.5)
|
| 375 |
+
assert f.taylor_term(2, x) == -0.125*x**2*(c**2)**(-1.5)
|
| 376 |
+
|
| 377 |
+
|
| 378 |
+
def test_issue_7638():
|
| 379 |
+
f = pi/log(sqrt(2))
|
| 380 |
+
assert ((1 + I)**(I*f/2))**0.3 == (1 + I)**(0.15*I*f)
|
| 381 |
+
# if 1/3 -> 1.0/3 this should fail since it cannot be shown that the
|
| 382 |
+
# sign will be +/-1; for the previous "small arg" case, it didn't matter
|
| 383 |
+
# that this could not be proved
|
| 384 |
+
assert (1 + I)**(4*I*f) == ((1 + I)**(12*I*f))**Rational(1, 3)
|
| 385 |
+
|
| 386 |
+
assert (((1 + I)**(I*(1 + 7*f)))**Rational(1, 3)).exp == Rational(1, 3)
|
| 387 |
+
r = symbols('r', real=True)
|
| 388 |
+
assert sqrt(r**2) == abs(r)
|
| 389 |
+
assert cbrt(r**3) != r
|
| 390 |
+
assert sqrt(Pow(2*I, 5*S.Half)) != (2*I)**Rational(5, 4)
|
| 391 |
+
p = symbols('p', positive=True)
|
| 392 |
+
assert cbrt(p**2) == p**Rational(2, 3)
|
| 393 |
+
assert NS(((0.2 + 0.7*I)**(0.7 + 1.0*I))**(0.5 - 0.1*I), 1) == '0.4 + 0.2*I'
|
| 394 |
+
assert sqrt(1/(1 + I)) == sqrt(1 - I)/sqrt(2) # or 1/sqrt(1 + I)
|
| 395 |
+
e = 1/(1 - sqrt(2))
|
| 396 |
+
assert sqrt(e) == I/sqrt(-1 + sqrt(2))
|
| 397 |
+
assert e**Rational(-1, 2) == -I*sqrt(-1 + sqrt(2))
|
| 398 |
+
assert sqrt((cos(1)**2 + sin(1)**2 - 1)**(3 + I)).exp in [S.Half,
|
| 399 |
+
Rational(3, 2) + I/2]
|
| 400 |
+
assert sqrt(r**Rational(4, 3)) != r**Rational(2, 3)
|
| 401 |
+
assert sqrt((p + I)**Rational(4, 3)) == (p + I)**Rational(2, 3)
|
| 402 |
+
|
| 403 |
+
for q in 1+I, 1-I:
|
| 404 |
+
assert sqrt(q**2) == q
|
| 405 |
+
for q in -1+I, -1-I:
|
| 406 |
+
assert sqrt(q**2) == -q
|
| 407 |
+
|
| 408 |
+
assert sqrt((p + r*I)**2) != p + r*I
|
| 409 |
+
e = (1 + I/5)
|
| 410 |
+
assert sqrt(e**5) == e**(5*S.Half)
|
| 411 |
+
assert sqrt(e**6) == e**3
|
| 412 |
+
assert sqrt((1 + I*r)**6) != (1 + I*r)**3
|
| 413 |
+
|
| 414 |
+
|
| 415 |
+
def test_issue_8582():
|
| 416 |
+
assert 1**oo is nan
|
| 417 |
+
assert 1**(-oo) is nan
|
| 418 |
+
assert 1**zoo is nan
|
| 419 |
+
assert 1**(oo + I) is nan
|
| 420 |
+
assert 1**(1 + I*oo) is nan
|
| 421 |
+
assert 1**(oo + I*oo) is nan
|
| 422 |
+
|
| 423 |
+
|
| 424 |
+
def test_issue_8650():
|
| 425 |
+
n = Symbol('n', integer=True, nonnegative=True)
|
| 426 |
+
assert (n**n).is_positive is True
|
| 427 |
+
x = 5*n + 5
|
| 428 |
+
assert (x**(5*(n + 1))).is_positive is True
|
| 429 |
+
|
| 430 |
+
|
| 431 |
+
def test_issue_13914():
|
| 432 |
+
b = Symbol('b')
|
| 433 |
+
assert (-1)**zoo is nan
|
| 434 |
+
assert 2**zoo is nan
|
| 435 |
+
assert (S.Half)**(1 + zoo) is nan
|
| 436 |
+
assert I**(zoo + I) is nan
|
| 437 |
+
assert b**(I + zoo) is nan
|
| 438 |
+
|
| 439 |
+
|
| 440 |
+
def test_better_sqrt():
|
| 441 |
+
n = Symbol('n', integer=True, nonnegative=True)
|
| 442 |
+
assert sqrt(3 + 4*I) == 2 + I
|
| 443 |
+
assert sqrt(3 - 4*I) == 2 - I
|
| 444 |
+
assert sqrt(-3 - 4*I) == 1 - 2*I
|
| 445 |
+
assert sqrt(-3 + 4*I) == 1 + 2*I
|
| 446 |
+
assert sqrt(32 + 24*I) == 6 + 2*I
|
| 447 |
+
assert sqrt(32 - 24*I) == 6 - 2*I
|
| 448 |
+
assert sqrt(-32 - 24*I) == 2 - 6*I
|
| 449 |
+
assert sqrt(-32 + 24*I) == 2 + 6*I
|
| 450 |
+
|
| 451 |
+
# triple (3, 4, 5):
|
| 452 |
+
# parity of 3 matches parity of 5 and
|
| 453 |
+
# den, 4, is a square
|
| 454 |
+
assert sqrt((3 + 4*I)/4) == 1 + I/2
|
| 455 |
+
# triple (8, 15, 17)
|
| 456 |
+
# parity of 8 doesn't match parity of 17 but
|
| 457 |
+
# den/2, 8/2, is a square
|
| 458 |
+
assert sqrt((8 + 15*I)/8) == (5 + 3*I)/4
|
| 459 |
+
# handle the denominator
|
| 460 |
+
assert sqrt((3 - 4*I)/25) == (2 - I)/5
|
| 461 |
+
assert sqrt((3 - 4*I)/26) == (2 - I)/sqrt(26)
|
| 462 |
+
# mul
|
| 463 |
+
# issue #12739
|
| 464 |
+
assert sqrt((3 + 4*I)/(3 - 4*I)) == (3 + 4*I)/5
|
| 465 |
+
assert sqrt(2/(3 + 4*I)) == sqrt(2)/5*(2 - I)
|
| 466 |
+
assert sqrt(n/(3 + 4*I)).subs(n, 2) == sqrt(2)/5*(2 - I)
|
| 467 |
+
assert sqrt(-2/(3 + 4*I)) == sqrt(2)/5*(1 + 2*I)
|
| 468 |
+
assert sqrt(-n/(3 + 4*I)).subs(n, 2) == sqrt(2)/5*(1 + 2*I)
|
| 469 |
+
# power
|
| 470 |
+
assert sqrt(1/(3 + I*4)) == (2 - I)/5
|
| 471 |
+
assert sqrt(1/(3 - I)) == sqrt(10)*sqrt(3 + I)/10
|
| 472 |
+
# symbolic
|
| 473 |
+
i = symbols('i', imaginary=True)
|
| 474 |
+
assert sqrt(3/i) == Mul(sqrt(3), 1/sqrt(i), evaluate=False)
|
| 475 |
+
# multiples of 1/2; don't make this too automatic
|
| 476 |
+
assert sqrt(3 + 4*I)**3 == (2 + I)**3
|
| 477 |
+
assert Pow(3 + 4*I, Rational(3, 2)) == 2 + 11*I
|
| 478 |
+
assert Pow(6 + 8*I, Rational(3, 2)) == 2*sqrt(2)*(2 + 11*I)
|
| 479 |
+
n, d = (3 + 4*I), (3 - 4*I)**3
|
| 480 |
+
a = n/d
|
| 481 |
+
assert a.args == (1/d, n)
|
| 482 |
+
eq = sqrt(a)
|
| 483 |
+
assert eq.args == (a, S.Half)
|
| 484 |
+
assert expand_multinomial(eq) == sqrt((-117 + 44*I)*(3 + 4*I))/125
|
| 485 |
+
assert eq.expand() == (7 - 24*I)/125
|
| 486 |
+
|
| 487 |
+
# issue 12775
|
| 488 |
+
# pos im part
|
| 489 |
+
assert sqrt(2*I) == (1 + I)
|
| 490 |
+
assert sqrt(2*9*I) == Mul(3, 1 + I, evaluate=False)
|
| 491 |
+
assert Pow(2*I, 3*S.Half) == (1 + I)**3
|
| 492 |
+
# neg im part
|
| 493 |
+
assert sqrt(-I/2) == Mul(S.Half, 1 - I, evaluate=False)
|
| 494 |
+
# fractional im part
|
| 495 |
+
assert Pow(Rational(-9, 2)*I, Rational(3, 2)) == 27*(1 - I)**3/8
|
| 496 |
+
|
| 497 |
+
|
| 498 |
+
def test_issue_2993():
|
| 499 |
+
assert str((2.3*x - 4)**0.3) == '(2.3*x - 4)**0.3'
|
| 500 |
+
assert str((2.3*x + 4)**0.3) == '(2.3*x + 4)**0.3'
|
| 501 |
+
assert str((-2.3*x + 4)**0.3) == '(4 - 2.3*x)**0.3'
|
| 502 |
+
assert str((-2.3*x - 4)**0.3) == '(-2.3*x - 4)**0.3'
|
| 503 |
+
assert str((2.3*x - 2)**0.3) == '(2.3*x - 2)**0.3'
|
| 504 |
+
assert str((-2.3*x - 2)**0.3) == '(-2.3*x - 2)**0.3'
|
| 505 |
+
assert str((-2.3*x + 2)**0.3) == '(2 - 2.3*x)**0.3'
|
| 506 |
+
assert str((2.3*x + 2)**0.3) == '(2.3*x + 2)**0.3'
|
| 507 |
+
assert str((2.3*x - 4)**Rational(1, 3)) == '(2.3*x - 4)**(1/3)'
|
| 508 |
+
eq = (2.3*x + 4)
|
| 509 |
+
assert str(eq**2) == '(2.3*x + 4)**2'
|
| 510 |
+
assert (1/eq).args == (eq, -1) # don't change trivial power
|
| 511 |
+
# issue 17735
|
| 512 |
+
q=.5*exp(x) - .5*exp(-x) + 0.1
|
| 513 |
+
assert int((q**2).subs(x, 1)) == 1
|
| 514 |
+
# issue 17756
|
| 515 |
+
y = Symbol('y')
|
| 516 |
+
assert len(sqrt(x/(x + y)**2 + Float('0.008', 30)).subs(y, pi.n(25)).atoms(Float)) == 2
|
| 517 |
+
# issue 17756
|
| 518 |
+
a, b, c, d, e, f, g = symbols('a:g')
|
| 519 |
+
expr = sqrt(1 + a*(c**4 + g*d - 2*g*e - f*(-g + d))**2/
|
| 520 |
+
(c**3*b**2*(d - 3*e + 2*f)**2))/2
|
| 521 |
+
r = [
|
| 522 |
+
(a, N('0.0170992456333788667034850458615', 30)),
|
| 523 |
+
(b, N('0.0966594956075474769169134801223', 30)),
|
| 524 |
+
(c, N('0.390911862903463913632151616184', 30)),
|
| 525 |
+
(d, N('0.152812084558656566271750185933', 30)),
|
| 526 |
+
(e, N('0.137562344465103337106561623432', 30)),
|
| 527 |
+
(f, N('0.174259178881496659302933610355', 30)),
|
| 528 |
+
(g, N('0.220745448491223779615401870086', 30))]
|
| 529 |
+
tru = expr.n(30, subs=dict(r))
|
| 530 |
+
seq = expr.subs(r)
|
| 531 |
+
# although `tru` is the right way to evaluate
|
| 532 |
+
# expr with numerical values, `seq` will have
|
| 533 |
+
# significant loss of precision if extraction of
|
| 534 |
+
# the largest coefficient of a power's base's terms
|
| 535 |
+
# is done improperly
|
| 536 |
+
assert seq == tru
|
| 537 |
+
|
| 538 |
+
def test_issue_17450():
|
| 539 |
+
assert (erf(cosh(1)**7)**I).is_real is None
|
| 540 |
+
assert (erf(cosh(1)**7)**I).is_imaginary is False
|
| 541 |
+
assert (Pow(exp(1+sqrt(2)), ((1-sqrt(2))*I*pi), evaluate=False)).is_real is None
|
| 542 |
+
assert ((-10)**(10*I*pi/3)).is_real is False
|
| 543 |
+
assert ((-5)**(4*I*pi)).is_real is False
|
| 544 |
+
|
| 545 |
+
|
| 546 |
+
def test_issue_18190():
|
| 547 |
+
assert sqrt(1 / tan(1 + I)) == 1 / sqrt(tan(1 + I))
|
| 548 |
+
|
| 549 |
+
|
| 550 |
+
def test_issue_14815():
|
| 551 |
+
x = Symbol('x', real=True)
|
| 552 |
+
assert sqrt(x).is_extended_negative is False
|
| 553 |
+
x = Symbol('x', real=False)
|
| 554 |
+
assert sqrt(x).is_extended_negative is None
|
| 555 |
+
x = Symbol('x', complex=True)
|
| 556 |
+
assert sqrt(x).is_extended_negative is False
|
| 557 |
+
x = Symbol('x', extended_real=True)
|
| 558 |
+
assert sqrt(x).is_extended_negative is False
|
| 559 |
+
assert sqrt(zoo, evaluate=False).is_extended_negative is False
|
| 560 |
+
assert sqrt(nan, evaluate=False).is_extended_negative is None
|
| 561 |
+
|
| 562 |
+
|
| 563 |
+
def test_issue_18509():
|
| 564 |
+
x = Symbol('x', prime=True)
|
| 565 |
+
assert x**oo is oo
|
| 566 |
+
assert (1/x)**oo is S.Zero
|
| 567 |
+
assert (-1/x)**oo is S.Zero
|
| 568 |
+
assert (-x)**oo is zoo
|
| 569 |
+
assert (-oo)**(-1 + I) is S.Zero
|
| 570 |
+
assert (-oo)**(1 + I) is zoo
|
| 571 |
+
assert (oo)**(-1 + I) is S.Zero
|
| 572 |
+
assert (oo)**(1 + I) is zoo
|
| 573 |
+
|
| 574 |
+
|
| 575 |
+
def test_issue_18762():
|
| 576 |
+
e, p = symbols('e p')
|
| 577 |
+
g0 = sqrt(1 + e**2 - 2*e*cos(p))
|
| 578 |
+
assert len(g0.series(e, 1, 3).args) == 4
|
| 579 |
+
|
| 580 |
+
|
| 581 |
+
def test_issue_21860():
|
| 582 |
+
e = 3*2**Rational(66666666667,200000000000)*3**Rational(16666666667,50000000000)*x**Rational(66666666667, 200000000000)
|
| 583 |
+
ans = Mul(Rational(3, 2),
|
| 584 |
+
Pow(Integer(2), Rational(33333333333, 100000000000)),
|
| 585 |
+
Pow(Integer(3), Rational(26666666667, 40000000000)))
|
| 586 |
+
assert e.xreplace({x: Rational(3,8)}) == ans
|
| 587 |
+
|
| 588 |
+
|
| 589 |
+
def test_issue_21647():
|
| 590 |
+
e = log((Integer(567)/500)**(811*(Integer(567)/500)**x/100))
|
| 591 |
+
ans = log(Mul(Rational(64701150190720499096094005280169087619821081527,
|
| 592 |
+
76293945312500000000000000000000000000000000000),
|
| 593 |
+
Pow(Integer(2), Rational(396204892125479941, 781250000000000000)),
|
| 594 |
+
Pow(Integer(3), Rational(385045107874520059, 390625000000000000)),
|
| 595 |
+
Pow(Integer(5), Rational(407364676376439823, 1562500000000000000)),
|
| 596 |
+
Pow(Integer(7), Rational(385045107874520059, 1562500000000000000))))
|
| 597 |
+
assert e.xreplace({x: 6}) == ans
|
| 598 |
+
|
| 599 |
+
|
| 600 |
+
def test_issue_21762():
|
| 601 |
+
e = (x**2 + 6)**(Integer(33333333333333333)/50000000000000000)
|
| 602 |
+
ans = Mul(Rational(5, 4),
|
| 603 |
+
Pow(Integer(2), Rational(16666666666666667, 25000000000000000)),
|
| 604 |
+
Pow(Integer(5), Rational(8333333333333333, 25000000000000000)))
|
| 605 |
+
assert e.xreplace({x: S.Half}) == ans
|
| 606 |
+
|
| 607 |
+
|
| 608 |
+
def test_issue_14704():
|
| 609 |
+
a = 144**144
|
| 610 |
+
x, xexact = integer_nthroot(a,a)
|
| 611 |
+
assert x == 1 and xexact is False
|
| 612 |
+
|
| 613 |
+
|
| 614 |
+
def test_rational_powers_larger_than_one():
|
| 615 |
+
assert Rational(2, 3)**Rational(3, 2) == 2*sqrt(6)/9
|
| 616 |
+
assert Rational(1, 6)**Rational(9, 4) == 6**Rational(3, 4)/216
|
| 617 |
+
assert Rational(3, 7)**Rational(7, 3) == 9*3**Rational(1, 3)*7**Rational(2, 3)/343
|
| 618 |
+
|
| 619 |
+
|
| 620 |
+
def test_power_dispatcher():
|
| 621 |
+
|
| 622 |
+
class NewBase(Expr):
|
| 623 |
+
pass
|
| 624 |
+
class NewPow(NewBase, Pow):
|
| 625 |
+
pass
|
| 626 |
+
a, b = Symbol('a'), NewBase()
|
| 627 |
+
|
| 628 |
+
@power.register(Expr, NewBase)
|
| 629 |
+
@power.register(NewBase, Expr)
|
| 630 |
+
@power.register(NewBase, NewBase)
|
| 631 |
+
def _(a, b):
|
| 632 |
+
return NewPow(a, b)
|
| 633 |
+
|
| 634 |
+
# Pow called as fallback
|
| 635 |
+
assert power(2, 3) == 8*S.One
|
| 636 |
+
assert power(a, 2) == Pow(a, 2)
|
| 637 |
+
assert power(a, a) == Pow(a, a)
|
| 638 |
+
|
| 639 |
+
# NewPow called by dispatch
|
| 640 |
+
assert power(a, b) == NewPow(a, b)
|
| 641 |
+
assert power(b, a) == NewPow(b, a)
|
| 642 |
+
assert power(b, b) == NewPow(b, b)
|
| 643 |
+
|
| 644 |
+
|
| 645 |
+
def test_powers_of_I():
|
| 646 |
+
assert [sqrt(I)**i for i in range(13)] == [
|
| 647 |
+
1, sqrt(I), I, sqrt(I)**3, -1, -sqrt(I), -I, -sqrt(I)**3,
|
| 648 |
+
1, sqrt(I), I, sqrt(I)**3, -1]
|
| 649 |
+
assert sqrt(I)**(S(9)/2) == -I**(S(1)/4)
|
| 650 |
+
|
| 651 |
+
|
| 652 |
+
def test_issue_23918():
|
| 653 |
+
b = S(2)/3
|
| 654 |
+
assert (b**x).as_base_exp() == (b, x)
|
| 655 |
+
|
| 656 |
+
|
| 657 |
+
def test_issue_26546():
|
| 658 |
+
x = Symbol('x', real=True)
|
| 659 |
+
assert x.is_extended_real is True
|
| 660 |
+
assert sqrt(x+I).is_extended_real is False
|
| 661 |
+
assert Pow(x+I, S.Half).is_extended_real is False
|
| 662 |
+
assert Pow(x+I, Rational(1,2)).is_extended_real is False
|
| 663 |
+
assert Pow(x+I, Rational(1,13)).is_extended_real is False
|
| 664 |
+
assert Pow(x+I, Rational(2,3)).is_extended_real is None
|
| 665 |
+
|
| 666 |
+
|
| 667 |
+
def test_issue_25165():
|
| 668 |
+
e1 = (1/sqrt(( - x + 1)**2 + (x - 0.23)**4)).series(x, 0, 2)
|
| 669 |
+
e2 = 0.998603724830355 + 1.02004923189934*x + O(x**2)
|
| 670 |
+
assert all_close(e1, e2)
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_priority.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.decorators import call_highest_priority
|
| 2 |
+
from sympy.core.expr import Expr
|
| 3 |
+
from sympy.core.mod import Mod
|
| 4 |
+
from sympy.core.numbers import Integer
|
| 5 |
+
from sympy.core.singleton import S
|
| 6 |
+
from sympy.core.symbol import Symbol
|
| 7 |
+
from sympy.functions.elementary.integers import floor
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class Higher(Integer):
|
| 11 |
+
'''
|
| 12 |
+
Integer of value 1 and _op_priority 20
|
| 13 |
+
|
| 14 |
+
Operations handled by this class return 1 and reverse operations return 2
|
| 15 |
+
'''
|
| 16 |
+
|
| 17 |
+
_op_priority = 20.0
|
| 18 |
+
result: Expr = S.One
|
| 19 |
+
|
| 20 |
+
def __new__(cls):
|
| 21 |
+
obj = Expr.__new__(cls)
|
| 22 |
+
obj.p = 1
|
| 23 |
+
return obj
|
| 24 |
+
|
| 25 |
+
@call_highest_priority('__rmul__')
|
| 26 |
+
def __mul__(self, other):
|
| 27 |
+
return self.result
|
| 28 |
+
|
| 29 |
+
@call_highest_priority('__mul__')
|
| 30 |
+
def __rmul__(self, other):
|
| 31 |
+
return 2*self.result
|
| 32 |
+
|
| 33 |
+
@call_highest_priority('__radd__')
|
| 34 |
+
def __add__(self, other):
|
| 35 |
+
return self.result
|
| 36 |
+
|
| 37 |
+
@call_highest_priority('__add__')
|
| 38 |
+
def __radd__(self, other):
|
| 39 |
+
return 2*self.result
|
| 40 |
+
|
| 41 |
+
@call_highest_priority('__rsub__')
|
| 42 |
+
def __sub__(self, other):
|
| 43 |
+
return self.result
|
| 44 |
+
|
| 45 |
+
@call_highest_priority('__sub__')
|
| 46 |
+
def __rsub__(self, other):
|
| 47 |
+
return 2*self.result
|
| 48 |
+
|
| 49 |
+
@call_highest_priority('__rpow__')
|
| 50 |
+
def __pow__(self, other):
|
| 51 |
+
return self.result
|
| 52 |
+
|
| 53 |
+
@call_highest_priority('__pow__')
|
| 54 |
+
def __rpow__(self, other):
|
| 55 |
+
return 2*self.result
|
| 56 |
+
|
| 57 |
+
@call_highest_priority('__rtruediv__')
|
| 58 |
+
def __truediv__(self, other):
|
| 59 |
+
return self.result
|
| 60 |
+
|
| 61 |
+
@call_highest_priority('__truediv__')
|
| 62 |
+
def __rtruediv__(self, other):
|
| 63 |
+
return 2*self.result
|
| 64 |
+
|
| 65 |
+
@call_highest_priority('__rmod__')
|
| 66 |
+
def __mod__(self, other):
|
| 67 |
+
return self.result
|
| 68 |
+
|
| 69 |
+
@call_highest_priority('__mod__')
|
| 70 |
+
def __rmod__(self, other):
|
| 71 |
+
return 2*self.result
|
| 72 |
+
|
| 73 |
+
@call_highest_priority('__rfloordiv__')
|
| 74 |
+
def __floordiv__(self, other):
|
| 75 |
+
return self.result
|
| 76 |
+
|
| 77 |
+
@call_highest_priority('__floordiv__')
|
| 78 |
+
def __rfloordiv__(self, other):
|
| 79 |
+
return 2*self.result
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
class Lower(Higher):
|
| 83 |
+
'''
|
| 84 |
+
Integer of value -1 and _op_priority 5
|
| 85 |
+
|
| 86 |
+
Operations handled by this class return -1 and reverse operations return -2
|
| 87 |
+
'''
|
| 88 |
+
|
| 89 |
+
_op_priority = 5.0
|
| 90 |
+
result: Expr = S.NegativeOne
|
| 91 |
+
|
| 92 |
+
def __new__(cls):
|
| 93 |
+
obj = Expr.__new__(cls)
|
| 94 |
+
obj.p = -1
|
| 95 |
+
return obj
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
x = Symbol('x')
|
| 99 |
+
h = Higher()
|
| 100 |
+
l = Lower()
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def test_mul():
|
| 104 |
+
assert h*l == h*x == 1
|
| 105 |
+
assert l*h == x*h == 2
|
| 106 |
+
assert x*l == l*x == -x
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def test_add():
|
| 110 |
+
assert h + l == h + x == 1
|
| 111 |
+
assert l + h == x + h == 2
|
| 112 |
+
assert x + l == l + x == x - 1
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def test_sub():
|
| 116 |
+
assert h - l == h - x == 1
|
| 117 |
+
assert l - h == x - h == 2
|
| 118 |
+
assert x - l == -(l - x) == x + 1
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
def test_pow():
|
| 122 |
+
assert h**l == h**x == 1
|
| 123 |
+
assert l**h == x**h == 2
|
| 124 |
+
assert (x**l).args == (1/x).args and (x**l).is_Pow
|
| 125 |
+
assert (l**x).args == ((-1)**x).args and (l**x).is_Pow
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
def test_div():
|
| 129 |
+
assert h/l == h/x == 1
|
| 130 |
+
assert l/h == x/h == 2
|
| 131 |
+
assert x/l == 1/(l/x) == -x
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def test_mod():
|
| 135 |
+
assert h%l == h%x == 1
|
| 136 |
+
assert l%h == x%h == 2
|
| 137 |
+
assert x%l == Mod(x, -1)
|
| 138 |
+
assert l%x == Mod(-1, x)
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def test_floordiv():
|
| 142 |
+
assert h//l == h//x == 1
|
| 143 |
+
assert l//h == x//h == 2
|
| 144 |
+
assert x//l == floor(-x)
|
| 145 |
+
assert l//x == floor(-1/x)
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_random.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import random
|
| 2 |
+
from sympy.core.random import random as rand, seed, shuffle, _assumptions_shuffle
|
| 3 |
+
from sympy.core.symbol import Symbol, symbols
|
| 4 |
+
from sympy.functions.elementary.trigonometric import sin, acos
|
| 5 |
+
from sympy.abc import x
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def test_random():
|
| 9 |
+
random.seed(42)
|
| 10 |
+
a = random.random()
|
| 11 |
+
random.seed(42)
|
| 12 |
+
Symbol('z').is_finite
|
| 13 |
+
b = random.random()
|
| 14 |
+
assert a == b
|
| 15 |
+
|
| 16 |
+
got = set()
|
| 17 |
+
for i in range(2):
|
| 18 |
+
random.seed(28)
|
| 19 |
+
m0, m1 = symbols('m_0 m_1', real=True)
|
| 20 |
+
_ = acos(-m0/m1)
|
| 21 |
+
got.add(random.uniform(0,1))
|
| 22 |
+
assert len(got) == 1
|
| 23 |
+
|
| 24 |
+
random.seed(10)
|
| 25 |
+
y = 0
|
| 26 |
+
for i in range(4):
|
| 27 |
+
y += sin(random.uniform(-10,10) * x)
|
| 28 |
+
random.seed(10)
|
| 29 |
+
z = 0
|
| 30 |
+
for i in range(4):
|
| 31 |
+
z += sin(random.uniform(-10,10) * x)
|
| 32 |
+
assert y == z
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def test_seed():
|
| 36 |
+
assert rand() < 1
|
| 37 |
+
seed(1)
|
| 38 |
+
a = rand()
|
| 39 |
+
b = rand()
|
| 40 |
+
seed(1)
|
| 41 |
+
c = rand()
|
| 42 |
+
d = rand()
|
| 43 |
+
assert a == c
|
| 44 |
+
if not c == d:
|
| 45 |
+
assert a != b
|
| 46 |
+
else:
|
| 47 |
+
assert a == b
|
| 48 |
+
|
| 49 |
+
abc = 'abc'
|
| 50 |
+
first = list(abc)
|
| 51 |
+
second = list(abc)
|
| 52 |
+
third = list(abc)
|
| 53 |
+
|
| 54 |
+
seed(123)
|
| 55 |
+
shuffle(first)
|
| 56 |
+
|
| 57 |
+
seed(123)
|
| 58 |
+
shuffle(second)
|
| 59 |
+
_assumptions_shuffle(third)
|
| 60 |
+
|
| 61 |
+
assert first == second == third
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_relational.py
ADDED
|
@@ -0,0 +1,1271 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.logic import fuzzy_and
|
| 2 |
+
from sympy.core.sympify import _sympify
|
| 3 |
+
from sympy.multipledispatch import dispatch
|
| 4 |
+
from sympy.testing.pytest import XFAIL, raises
|
| 5 |
+
from sympy.assumptions.ask import Q
|
| 6 |
+
from sympy.core.add import Add
|
| 7 |
+
from sympy.core.basic import Basic
|
| 8 |
+
from sympy.core.expr import Expr, unchanged
|
| 9 |
+
from sympy.core.function import Function
|
| 10 |
+
from sympy.core.mul import Mul
|
| 11 |
+
from sympy.core.numbers import (Float, I, Rational, nan, oo, pi, zoo)
|
| 12 |
+
from sympy.core.power import Pow
|
| 13 |
+
from sympy.core.singleton import S
|
| 14 |
+
from sympy.core.symbol import (Symbol, symbols)
|
| 15 |
+
from sympy.functions.elementary.complexes import sign, Abs
|
| 16 |
+
from sympy.functions.elementary.piecewise import Piecewise
|
| 17 |
+
from sympy.functions.elementary.exponential import (exp, exp_polar, log)
|
| 18 |
+
from sympy.functions.elementary.integers import (ceiling, floor)
|
| 19 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 20 |
+
from sympy.functions.elementary.trigonometric import (cos, sin)
|
| 21 |
+
from sympy.logic.boolalg import (And, Implies, Not, Or, Xor)
|
| 22 |
+
from sympy.sets import Reals
|
| 23 |
+
from sympy.simplify.simplify import simplify
|
| 24 |
+
from sympy.simplify.trigsimp import trigsimp
|
| 25 |
+
from sympy.core.relational import (Relational, Equality, Unequality,
|
| 26 |
+
GreaterThan, LessThan, StrictGreaterThan,
|
| 27 |
+
StrictLessThan, Rel, Eq, Lt, Le,
|
| 28 |
+
Gt, Ge, Ne, is_le, is_gt, is_ge, is_lt, is_eq, is_neq)
|
| 29 |
+
from sympy.sets.sets import Interval, FiniteSet
|
| 30 |
+
|
| 31 |
+
from itertools import combinations
|
| 32 |
+
|
| 33 |
+
x, y, z, t = symbols('x,y,z,t')
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def rel_check(a, b):
|
| 37 |
+
from sympy.testing.pytest import raises
|
| 38 |
+
assert a.is_number and b.is_number
|
| 39 |
+
for do in range(len({type(a), type(b)})):
|
| 40 |
+
if S.NaN in (a, b):
|
| 41 |
+
v = [(a == b), (a != b)]
|
| 42 |
+
assert len(set(v)) == 1 and v[0] == False
|
| 43 |
+
assert not (a != b) and not (a == b)
|
| 44 |
+
assert raises(TypeError, lambda: a < b)
|
| 45 |
+
assert raises(TypeError, lambda: a <= b)
|
| 46 |
+
assert raises(TypeError, lambda: a > b)
|
| 47 |
+
assert raises(TypeError, lambda: a >= b)
|
| 48 |
+
else:
|
| 49 |
+
E = [(a == b), (a != b)]
|
| 50 |
+
assert len(set(E)) == 2
|
| 51 |
+
v = [
|
| 52 |
+
(a < b), (a <= b), (a > b), (a >= b)]
|
| 53 |
+
i = [
|
| 54 |
+
[True, True, False, False],
|
| 55 |
+
[False, True, False, True], # <-- i == 1
|
| 56 |
+
[False, False, True, True]].index(v)
|
| 57 |
+
if i == 1:
|
| 58 |
+
assert E[0] or (a.is_Float != b.is_Float) # ugh
|
| 59 |
+
else:
|
| 60 |
+
assert E[1]
|
| 61 |
+
a, b = b, a
|
| 62 |
+
return True
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def test_rel_ne():
|
| 66 |
+
assert Relational(x, y, '!=') == Ne(x, y)
|
| 67 |
+
|
| 68 |
+
# issue 6116
|
| 69 |
+
p = Symbol('p', positive=True)
|
| 70 |
+
assert Ne(p, 0) is S.true
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def test_rel_subs():
|
| 74 |
+
e = Relational(x, y, '==')
|
| 75 |
+
e = e.subs(x, z)
|
| 76 |
+
|
| 77 |
+
assert isinstance(e, Equality)
|
| 78 |
+
assert e.lhs == z
|
| 79 |
+
assert e.rhs == y
|
| 80 |
+
|
| 81 |
+
e = Relational(x, y, '>=')
|
| 82 |
+
e = e.subs(x, z)
|
| 83 |
+
|
| 84 |
+
assert isinstance(e, GreaterThan)
|
| 85 |
+
assert e.lhs == z
|
| 86 |
+
assert e.rhs == y
|
| 87 |
+
|
| 88 |
+
e = Relational(x, y, '<=')
|
| 89 |
+
e = e.subs(x, z)
|
| 90 |
+
|
| 91 |
+
assert isinstance(e, LessThan)
|
| 92 |
+
assert e.lhs == z
|
| 93 |
+
assert e.rhs == y
|
| 94 |
+
|
| 95 |
+
e = Relational(x, y, '>')
|
| 96 |
+
e = e.subs(x, z)
|
| 97 |
+
|
| 98 |
+
assert isinstance(e, StrictGreaterThan)
|
| 99 |
+
assert e.lhs == z
|
| 100 |
+
assert e.rhs == y
|
| 101 |
+
|
| 102 |
+
e = Relational(x, y, '<')
|
| 103 |
+
e = e.subs(x, z)
|
| 104 |
+
|
| 105 |
+
assert isinstance(e, StrictLessThan)
|
| 106 |
+
assert e.lhs == z
|
| 107 |
+
assert e.rhs == y
|
| 108 |
+
|
| 109 |
+
e = Eq(x, 0)
|
| 110 |
+
assert e.subs(x, 0) is S.true
|
| 111 |
+
assert e.subs(x, 1) is S.false
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
def test_wrappers():
|
| 115 |
+
e = x + x**2
|
| 116 |
+
|
| 117 |
+
res = Relational(y, e, '==')
|
| 118 |
+
assert Rel(y, x + x**2, '==') == res
|
| 119 |
+
assert Eq(y, x + x**2) == res
|
| 120 |
+
|
| 121 |
+
res = Relational(y, e, '<')
|
| 122 |
+
assert Lt(y, x + x**2) == res
|
| 123 |
+
|
| 124 |
+
res = Relational(y, e, '<=')
|
| 125 |
+
assert Le(y, x + x**2) == res
|
| 126 |
+
|
| 127 |
+
res = Relational(y, e, '>')
|
| 128 |
+
assert Gt(y, x + x**2) == res
|
| 129 |
+
|
| 130 |
+
res = Relational(y, e, '>=')
|
| 131 |
+
assert Ge(y, x + x**2) == res
|
| 132 |
+
|
| 133 |
+
res = Relational(y, e, '!=')
|
| 134 |
+
assert Ne(y, x + x**2) == res
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
def test_Eq_Ne():
|
| 138 |
+
|
| 139 |
+
assert Eq(x, x) # issue 5719
|
| 140 |
+
|
| 141 |
+
# issue 6116
|
| 142 |
+
p = Symbol('p', positive=True)
|
| 143 |
+
assert Eq(p, 0) is S.false
|
| 144 |
+
|
| 145 |
+
# issue 13348; 19048
|
| 146 |
+
# SymPy is strict about 0 and 1 not being
|
| 147 |
+
# interpreted as Booleans
|
| 148 |
+
assert Eq(True, 1) is S.false
|
| 149 |
+
assert Eq(False, 0) is S.false
|
| 150 |
+
assert Eq(~x, 0) is S.false
|
| 151 |
+
assert Eq(~x, 1) is S.false
|
| 152 |
+
assert Ne(True, 1) is S.true
|
| 153 |
+
assert Ne(False, 0) is S.true
|
| 154 |
+
assert Ne(~x, 0) is S.true
|
| 155 |
+
assert Ne(~x, 1) is S.true
|
| 156 |
+
|
| 157 |
+
assert Eq((), 1) is S.false
|
| 158 |
+
assert Ne((), 1) is S.true
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
def test_as_poly():
|
| 162 |
+
from sympy.polys.polytools import Poly
|
| 163 |
+
# Only Eq should have an as_poly method:
|
| 164 |
+
assert Eq(x, 1).as_poly() == Poly(x - 1, x, domain='ZZ')
|
| 165 |
+
raises(AttributeError, lambda: Ne(x, 1).as_poly())
|
| 166 |
+
raises(AttributeError, lambda: Ge(x, 1).as_poly())
|
| 167 |
+
raises(AttributeError, lambda: Gt(x, 1).as_poly())
|
| 168 |
+
raises(AttributeError, lambda: Le(x, 1).as_poly())
|
| 169 |
+
raises(AttributeError, lambda: Lt(x, 1).as_poly())
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def test_rel_Infinity():
|
| 173 |
+
# NOTE: All of these are actually handled by sympy.core.Number, and do
|
| 174 |
+
# not create Relational objects.
|
| 175 |
+
assert (oo > oo) is S.false
|
| 176 |
+
assert (oo > -oo) is S.true
|
| 177 |
+
assert (oo > 1) is S.true
|
| 178 |
+
assert (oo < oo) is S.false
|
| 179 |
+
assert (oo < -oo) is S.false
|
| 180 |
+
assert (oo < 1) is S.false
|
| 181 |
+
assert (oo >= oo) is S.true
|
| 182 |
+
assert (oo >= -oo) is S.true
|
| 183 |
+
assert (oo >= 1) is S.true
|
| 184 |
+
assert (oo <= oo) is S.true
|
| 185 |
+
assert (oo <= -oo) is S.false
|
| 186 |
+
assert (oo <= 1) is S.false
|
| 187 |
+
assert (-oo > oo) is S.false
|
| 188 |
+
assert (-oo > -oo) is S.false
|
| 189 |
+
assert (-oo > 1) is S.false
|
| 190 |
+
assert (-oo < oo) is S.true
|
| 191 |
+
assert (-oo < -oo) is S.false
|
| 192 |
+
assert (-oo < 1) is S.true
|
| 193 |
+
assert (-oo >= oo) is S.false
|
| 194 |
+
assert (-oo >= -oo) is S.true
|
| 195 |
+
assert (-oo >= 1) is S.false
|
| 196 |
+
assert (-oo <= oo) is S.true
|
| 197 |
+
assert (-oo <= -oo) is S.true
|
| 198 |
+
assert (-oo <= 1) is S.true
|
| 199 |
+
|
| 200 |
+
|
| 201 |
+
def test_infinite_symbol_inequalities():
|
| 202 |
+
x = Symbol('x', extended_positive=True, infinite=True)
|
| 203 |
+
y = Symbol('y', extended_positive=True, infinite=True)
|
| 204 |
+
z = Symbol('z', extended_negative=True, infinite=True)
|
| 205 |
+
w = Symbol('w', extended_negative=True, infinite=True)
|
| 206 |
+
|
| 207 |
+
inf_set = (x, y, oo)
|
| 208 |
+
ninf_set = (z, w, -oo)
|
| 209 |
+
|
| 210 |
+
for inf1 in inf_set:
|
| 211 |
+
assert (inf1 < 1) is S.false
|
| 212 |
+
assert (inf1 > 1) is S.true
|
| 213 |
+
assert (inf1 <= 1) is S.false
|
| 214 |
+
assert (inf1 >= 1) is S.true
|
| 215 |
+
|
| 216 |
+
for inf2 in inf_set:
|
| 217 |
+
assert (inf1 < inf2) is S.false
|
| 218 |
+
assert (inf1 > inf2) is S.false
|
| 219 |
+
assert (inf1 <= inf2) is S.true
|
| 220 |
+
assert (inf1 >= inf2) is S.true
|
| 221 |
+
|
| 222 |
+
for ninf1 in ninf_set:
|
| 223 |
+
assert (inf1 < ninf1) is S.false
|
| 224 |
+
assert (inf1 > ninf1) is S.true
|
| 225 |
+
assert (inf1 <= ninf1) is S.false
|
| 226 |
+
assert (inf1 >= ninf1) is S.true
|
| 227 |
+
assert (ninf1 < inf1) is S.true
|
| 228 |
+
assert (ninf1 > inf1) is S.false
|
| 229 |
+
assert (ninf1 <= inf1) is S.true
|
| 230 |
+
assert (ninf1 >= inf1) is S.false
|
| 231 |
+
|
| 232 |
+
for ninf1 in ninf_set:
|
| 233 |
+
assert (ninf1 < 1) is S.true
|
| 234 |
+
assert (ninf1 > 1) is S.false
|
| 235 |
+
assert (ninf1 <= 1) is S.true
|
| 236 |
+
assert (ninf1 >= 1) is S.false
|
| 237 |
+
|
| 238 |
+
for ninf2 in ninf_set:
|
| 239 |
+
assert (ninf1 < ninf2) is S.false
|
| 240 |
+
assert (ninf1 > ninf2) is S.false
|
| 241 |
+
assert (ninf1 <= ninf2) is S.true
|
| 242 |
+
assert (ninf1 >= ninf2) is S.true
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
def test_bool():
|
| 246 |
+
assert Eq(0, 0) is S.true
|
| 247 |
+
assert Eq(1, 0) is S.false
|
| 248 |
+
assert Ne(0, 0) is S.false
|
| 249 |
+
assert Ne(1, 0) is S.true
|
| 250 |
+
assert Lt(0, 1) is S.true
|
| 251 |
+
assert Lt(1, 0) is S.false
|
| 252 |
+
assert Le(0, 1) is S.true
|
| 253 |
+
assert Le(1, 0) is S.false
|
| 254 |
+
assert Le(0, 0) is S.true
|
| 255 |
+
assert Gt(1, 0) is S.true
|
| 256 |
+
assert Gt(0, 1) is S.false
|
| 257 |
+
assert Ge(1, 0) is S.true
|
| 258 |
+
assert Ge(0, 1) is S.false
|
| 259 |
+
assert Ge(1, 1) is S.true
|
| 260 |
+
assert Eq(I, 2) is S.false
|
| 261 |
+
assert Ne(I, 2) is S.true
|
| 262 |
+
raises(TypeError, lambda: Gt(I, 2))
|
| 263 |
+
raises(TypeError, lambda: Ge(I, 2))
|
| 264 |
+
raises(TypeError, lambda: Lt(I, 2))
|
| 265 |
+
raises(TypeError, lambda: Le(I, 2))
|
| 266 |
+
a = Float('.000000000000000000001', '')
|
| 267 |
+
b = Float('.0000000000000000000001', '')
|
| 268 |
+
assert Eq(pi + a, pi + b) is S.false
|
| 269 |
+
|
| 270 |
+
|
| 271 |
+
def test_rich_cmp():
|
| 272 |
+
assert (x < y) == Lt(x, y)
|
| 273 |
+
assert (x <= y) == Le(x, y)
|
| 274 |
+
assert (x > y) == Gt(x, y)
|
| 275 |
+
assert (x >= y) == Ge(x, y)
|
| 276 |
+
|
| 277 |
+
|
| 278 |
+
def test_doit():
|
| 279 |
+
from sympy.core.symbol import Symbol
|
| 280 |
+
p = Symbol('p', positive=True)
|
| 281 |
+
n = Symbol('n', negative=True)
|
| 282 |
+
np = Symbol('np', nonpositive=True)
|
| 283 |
+
nn = Symbol('nn', nonnegative=True)
|
| 284 |
+
|
| 285 |
+
assert Gt(p, 0).doit() is S.true
|
| 286 |
+
assert Gt(p, 1).doit() == Gt(p, 1)
|
| 287 |
+
assert Ge(p, 0).doit() is S.true
|
| 288 |
+
assert Le(p, 0).doit() is S.false
|
| 289 |
+
assert Lt(n, 0).doit() is S.true
|
| 290 |
+
assert Le(np, 0).doit() is S.true
|
| 291 |
+
assert Gt(nn, 0).doit() == Gt(nn, 0)
|
| 292 |
+
assert Lt(nn, 0).doit() is S.false
|
| 293 |
+
|
| 294 |
+
assert Eq(x, 0).doit() == Eq(x, 0)
|
| 295 |
+
|
| 296 |
+
|
| 297 |
+
def test_new_relational():
|
| 298 |
+
x = Symbol('x')
|
| 299 |
+
|
| 300 |
+
assert Eq(x, 0) == Relational(x, 0) # None ==> Equality
|
| 301 |
+
assert Eq(x, 0) == Relational(x, 0, '==')
|
| 302 |
+
assert Eq(x, 0) == Relational(x, 0, 'eq')
|
| 303 |
+
assert Eq(x, 0) == Equality(x, 0)
|
| 304 |
+
|
| 305 |
+
assert Eq(x, 0) != Relational(x, 1) # None ==> Equality
|
| 306 |
+
assert Eq(x, 0) != Relational(x, 1, '==')
|
| 307 |
+
assert Eq(x, 0) != Relational(x, 1, 'eq')
|
| 308 |
+
assert Eq(x, 0) != Equality(x, 1)
|
| 309 |
+
|
| 310 |
+
assert Eq(x, -1) == Relational(x, -1) # None ==> Equality
|
| 311 |
+
assert Eq(x, -1) == Relational(x, -1, '==')
|
| 312 |
+
assert Eq(x, -1) == Relational(x, -1, 'eq')
|
| 313 |
+
assert Eq(x, -1) == Equality(x, -1)
|
| 314 |
+
assert Eq(x, -1) != Relational(x, 1) # None ==> Equality
|
| 315 |
+
assert Eq(x, -1) != Relational(x, 1, '==')
|
| 316 |
+
assert Eq(x, -1) != Relational(x, 1, 'eq')
|
| 317 |
+
assert Eq(x, -1) != Equality(x, 1)
|
| 318 |
+
|
| 319 |
+
assert Ne(x, 0) == Relational(x, 0, '!=')
|
| 320 |
+
assert Ne(x, 0) == Relational(x, 0, '<>')
|
| 321 |
+
assert Ne(x, 0) == Relational(x, 0, 'ne')
|
| 322 |
+
assert Ne(x, 0) == Unequality(x, 0)
|
| 323 |
+
assert Ne(x, 0) != Relational(x, 1, '!=')
|
| 324 |
+
assert Ne(x, 0) != Relational(x, 1, '<>')
|
| 325 |
+
assert Ne(x, 0) != Relational(x, 1, 'ne')
|
| 326 |
+
assert Ne(x, 0) != Unequality(x, 1)
|
| 327 |
+
|
| 328 |
+
assert Ge(x, 0) == Relational(x, 0, '>=')
|
| 329 |
+
assert Ge(x, 0) == Relational(x, 0, 'ge')
|
| 330 |
+
assert Ge(x, 0) == GreaterThan(x, 0)
|
| 331 |
+
assert Ge(x, 1) != Relational(x, 0, '>=')
|
| 332 |
+
assert Ge(x, 1) != Relational(x, 0, 'ge')
|
| 333 |
+
assert Ge(x, 1) != GreaterThan(x, 0)
|
| 334 |
+
assert (x >= 1) == Relational(x, 1, '>=')
|
| 335 |
+
assert (x >= 1) == Relational(x, 1, 'ge')
|
| 336 |
+
assert (x >= 1) == GreaterThan(x, 1)
|
| 337 |
+
assert (x >= 0) != Relational(x, 1, '>=')
|
| 338 |
+
assert (x >= 0) != Relational(x, 1, 'ge')
|
| 339 |
+
assert (x >= 0) != GreaterThan(x, 1)
|
| 340 |
+
|
| 341 |
+
assert Le(x, 0) == Relational(x, 0, '<=')
|
| 342 |
+
assert Le(x, 0) == Relational(x, 0, 'le')
|
| 343 |
+
assert Le(x, 0) == LessThan(x, 0)
|
| 344 |
+
assert Le(x, 1) != Relational(x, 0, '<=')
|
| 345 |
+
assert Le(x, 1) != Relational(x, 0, 'le')
|
| 346 |
+
assert Le(x, 1) != LessThan(x, 0)
|
| 347 |
+
assert (x <= 1) == Relational(x, 1, '<=')
|
| 348 |
+
assert (x <= 1) == Relational(x, 1, 'le')
|
| 349 |
+
assert (x <= 1) == LessThan(x, 1)
|
| 350 |
+
assert (x <= 0) != Relational(x, 1, '<=')
|
| 351 |
+
assert (x <= 0) != Relational(x, 1, 'le')
|
| 352 |
+
assert (x <= 0) != LessThan(x, 1)
|
| 353 |
+
|
| 354 |
+
assert Gt(x, 0) == Relational(x, 0, '>')
|
| 355 |
+
assert Gt(x, 0) == Relational(x, 0, 'gt')
|
| 356 |
+
assert Gt(x, 0) == StrictGreaterThan(x, 0)
|
| 357 |
+
assert Gt(x, 1) != Relational(x, 0, '>')
|
| 358 |
+
assert Gt(x, 1) != Relational(x, 0, 'gt')
|
| 359 |
+
assert Gt(x, 1) != StrictGreaterThan(x, 0)
|
| 360 |
+
assert (x > 1) == Relational(x, 1, '>')
|
| 361 |
+
assert (x > 1) == Relational(x, 1, 'gt')
|
| 362 |
+
assert (x > 1) == StrictGreaterThan(x, 1)
|
| 363 |
+
assert (x > 0) != Relational(x, 1, '>')
|
| 364 |
+
assert (x > 0) != Relational(x, 1, 'gt')
|
| 365 |
+
assert (x > 0) != StrictGreaterThan(x, 1)
|
| 366 |
+
|
| 367 |
+
assert Lt(x, 0) == Relational(x, 0, '<')
|
| 368 |
+
assert Lt(x, 0) == Relational(x, 0, 'lt')
|
| 369 |
+
assert Lt(x, 0) == StrictLessThan(x, 0)
|
| 370 |
+
assert Lt(x, 1) != Relational(x, 0, '<')
|
| 371 |
+
assert Lt(x, 1) != Relational(x, 0, 'lt')
|
| 372 |
+
assert Lt(x, 1) != StrictLessThan(x, 0)
|
| 373 |
+
assert (x < 1) == Relational(x, 1, '<')
|
| 374 |
+
assert (x < 1) == Relational(x, 1, 'lt')
|
| 375 |
+
assert (x < 1) == StrictLessThan(x, 1)
|
| 376 |
+
assert (x < 0) != Relational(x, 1, '<')
|
| 377 |
+
assert (x < 0) != Relational(x, 1, 'lt')
|
| 378 |
+
assert (x < 0) != StrictLessThan(x, 1)
|
| 379 |
+
|
| 380 |
+
# finally, some fuzz testing
|
| 381 |
+
from sympy.core.random import randint
|
| 382 |
+
for i in range(100):
|
| 383 |
+
while 1:
|
| 384 |
+
strtype, length = (chr, 65535) if randint(0, 1) else (chr, 255)
|
| 385 |
+
relation_type = strtype(randint(0, length))
|
| 386 |
+
if randint(0, 1):
|
| 387 |
+
relation_type += strtype(randint(0, length))
|
| 388 |
+
if relation_type not in ('==', 'eq', '!=', '<>', 'ne', '>=', 'ge',
|
| 389 |
+
'<=', 'le', '>', 'gt', '<', 'lt', ':=',
|
| 390 |
+
'+=', '-=', '*=', '/=', '%='):
|
| 391 |
+
break
|
| 392 |
+
|
| 393 |
+
raises(ValueError, lambda: Relational(x, 1, relation_type))
|
| 394 |
+
assert all(Relational(x, 0, op).rel_op == '==' for op in ('eq', '=='))
|
| 395 |
+
assert all(Relational(x, 0, op).rel_op == '!='
|
| 396 |
+
for op in ('ne', '<>', '!='))
|
| 397 |
+
assert all(Relational(x, 0, op).rel_op == '>' for op in ('gt', '>'))
|
| 398 |
+
assert all(Relational(x, 0, op).rel_op == '<' for op in ('lt', '<'))
|
| 399 |
+
assert all(Relational(x, 0, op).rel_op == '>=' for op in ('ge', '>='))
|
| 400 |
+
assert all(Relational(x, 0, op).rel_op == '<=' for op in ('le', '<='))
|
| 401 |
+
|
| 402 |
+
|
| 403 |
+
def test_relational_arithmetic():
|
| 404 |
+
for cls in [Eq, Ne, Le, Lt, Ge, Gt]:
|
| 405 |
+
rel = cls(x, y)
|
| 406 |
+
raises(TypeError, lambda: 0+rel)
|
| 407 |
+
raises(TypeError, lambda: 1*rel)
|
| 408 |
+
raises(TypeError, lambda: 1**rel)
|
| 409 |
+
raises(TypeError, lambda: rel**1)
|
| 410 |
+
raises(TypeError, lambda: Add(0, rel))
|
| 411 |
+
raises(TypeError, lambda: Mul(1, rel))
|
| 412 |
+
raises(TypeError, lambda: Pow(1, rel))
|
| 413 |
+
raises(TypeError, lambda: Pow(rel, 1))
|
| 414 |
+
|
| 415 |
+
|
| 416 |
+
def test_relational_bool_output():
|
| 417 |
+
# https://github.com/sympy/sympy/issues/5931
|
| 418 |
+
raises(TypeError, lambda: bool(x > 3))
|
| 419 |
+
raises(TypeError, lambda: bool(x >= 3))
|
| 420 |
+
raises(TypeError, lambda: bool(x < 3))
|
| 421 |
+
raises(TypeError, lambda: bool(x <= 3))
|
| 422 |
+
raises(TypeError, lambda: bool(Eq(x, 3)))
|
| 423 |
+
raises(TypeError, lambda: bool(Ne(x, 3)))
|
| 424 |
+
|
| 425 |
+
|
| 426 |
+
def test_relational_logic_symbols():
|
| 427 |
+
# See issue 6204
|
| 428 |
+
assert (x < y) & (z < t) == And(x < y, z < t)
|
| 429 |
+
assert (x < y) | (z < t) == Or(x < y, z < t)
|
| 430 |
+
assert ~(x < y) == Not(x < y)
|
| 431 |
+
assert (x < y) >> (z < t) == Implies(x < y, z < t)
|
| 432 |
+
assert (x < y) << (z < t) == Implies(z < t, x < y)
|
| 433 |
+
assert (x < y) ^ (z < t) == Xor(x < y, z < t)
|
| 434 |
+
|
| 435 |
+
assert isinstance((x < y) & (z < t), And)
|
| 436 |
+
assert isinstance((x < y) | (z < t), Or)
|
| 437 |
+
assert isinstance(~(x < y), GreaterThan)
|
| 438 |
+
assert isinstance((x < y) >> (z < t), Implies)
|
| 439 |
+
assert isinstance((x < y) << (z < t), Implies)
|
| 440 |
+
assert isinstance((x < y) ^ (z < t), (Or, Xor))
|
| 441 |
+
|
| 442 |
+
|
| 443 |
+
def test_univariate_relational_as_set():
|
| 444 |
+
assert (x > 0).as_set() == Interval(0, oo, True, True)
|
| 445 |
+
assert (x >= 0).as_set() == Interval(0, oo)
|
| 446 |
+
assert (x < 0).as_set() == Interval(-oo, 0, True, True)
|
| 447 |
+
assert (x <= 0).as_set() == Interval(-oo, 0)
|
| 448 |
+
assert Eq(x, 0).as_set() == FiniteSet(0)
|
| 449 |
+
assert Ne(x, 0).as_set() == Interval(-oo, 0, True, True) + \
|
| 450 |
+
Interval(0, oo, True, True)
|
| 451 |
+
|
| 452 |
+
assert (x**2 >= 4).as_set() == Interval(-oo, -2) + Interval(2, oo)
|
| 453 |
+
|
| 454 |
+
|
| 455 |
+
@XFAIL
|
| 456 |
+
def test_multivariate_relational_as_set():
|
| 457 |
+
assert (x*y >= 0).as_set() == Interval(0, oo)*Interval(0, oo) + \
|
| 458 |
+
Interval(-oo, 0)*Interval(-oo, 0)
|
| 459 |
+
|
| 460 |
+
|
| 461 |
+
def test_Not():
|
| 462 |
+
assert Not(Equality(x, y)) == Unequality(x, y)
|
| 463 |
+
assert Not(Unequality(x, y)) == Equality(x, y)
|
| 464 |
+
assert Not(StrictGreaterThan(x, y)) == LessThan(x, y)
|
| 465 |
+
assert Not(StrictLessThan(x, y)) == GreaterThan(x, y)
|
| 466 |
+
assert Not(GreaterThan(x, y)) == StrictLessThan(x, y)
|
| 467 |
+
assert Not(LessThan(x, y)) == StrictGreaterThan(x, y)
|
| 468 |
+
|
| 469 |
+
|
| 470 |
+
def test_evaluate():
|
| 471 |
+
assert str(Eq(x, x, evaluate=False)) == 'Eq(x, x)'
|
| 472 |
+
assert Eq(x, x, evaluate=False).doit() == S.true
|
| 473 |
+
assert str(Ne(x, x, evaluate=False)) == 'Ne(x, x)'
|
| 474 |
+
assert Ne(x, x, evaluate=False).doit() == S.false
|
| 475 |
+
|
| 476 |
+
assert str(Ge(x, x, evaluate=False)) == 'x >= x'
|
| 477 |
+
assert str(Le(x, x, evaluate=False)) == 'x <= x'
|
| 478 |
+
assert str(Gt(x, x, evaluate=False)) == 'x > x'
|
| 479 |
+
assert str(Lt(x, x, evaluate=False)) == 'x < x'
|
| 480 |
+
|
| 481 |
+
|
| 482 |
+
def assert_all_ineq_raise_TypeError(a, b):
|
| 483 |
+
raises(TypeError, lambda: a > b)
|
| 484 |
+
raises(TypeError, lambda: a >= b)
|
| 485 |
+
raises(TypeError, lambda: a < b)
|
| 486 |
+
raises(TypeError, lambda: a <= b)
|
| 487 |
+
raises(TypeError, lambda: b > a)
|
| 488 |
+
raises(TypeError, lambda: b >= a)
|
| 489 |
+
raises(TypeError, lambda: b < a)
|
| 490 |
+
raises(TypeError, lambda: b <= a)
|
| 491 |
+
|
| 492 |
+
|
| 493 |
+
def assert_all_ineq_give_class_Inequality(a, b):
|
| 494 |
+
"""All inequality operations on `a` and `b` result in class Inequality."""
|
| 495 |
+
from sympy.core.relational import _Inequality as Inequality
|
| 496 |
+
assert isinstance(a > b, Inequality)
|
| 497 |
+
assert isinstance(a >= b, Inequality)
|
| 498 |
+
assert isinstance(a < b, Inequality)
|
| 499 |
+
assert isinstance(a <= b, Inequality)
|
| 500 |
+
assert isinstance(b > a, Inequality)
|
| 501 |
+
assert isinstance(b >= a, Inequality)
|
| 502 |
+
assert isinstance(b < a, Inequality)
|
| 503 |
+
assert isinstance(b <= a, Inequality)
|
| 504 |
+
|
| 505 |
+
|
| 506 |
+
def test_imaginary_compare_raises_TypeError():
|
| 507 |
+
# See issue #5724
|
| 508 |
+
assert_all_ineq_raise_TypeError(I, x)
|
| 509 |
+
|
| 510 |
+
|
| 511 |
+
def test_complex_compare_not_real():
|
| 512 |
+
# two cases which are not real
|
| 513 |
+
y = Symbol('y', imaginary=True)
|
| 514 |
+
z = Symbol('z', complex=True, extended_real=False)
|
| 515 |
+
for w in (y, z):
|
| 516 |
+
assert_all_ineq_raise_TypeError(2, w)
|
| 517 |
+
# some cases which should remain un-evaluated
|
| 518 |
+
t = Symbol('t')
|
| 519 |
+
x = Symbol('x', real=True)
|
| 520 |
+
z = Symbol('z', complex=True)
|
| 521 |
+
for w in (x, z, t):
|
| 522 |
+
assert_all_ineq_give_class_Inequality(2, w)
|
| 523 |
+
|
| 524 |
+
|
| 525 |
+
def test_imaginary_and_inf_compare_raises_TypeError():
|
| 526 |
+
# See pull request #7835
|
| 527 |
+
y = Symbol('y', imaginary=True)
|
| 528 |
+
assert_all_ineq_raise_TypeError(oo, y)
|
| 529 |
+
assert_all_ineq_raise_TypeError(-oo, y)
|
| 530 |
+
|
| 531 |
+
|
| 532 |
+
def test_complex_pure_imag_not_ordered():
|
| 533 |
+
raises(TypeError, lambda: 2*I < 3*I)
|
| 534 |
+
|
| 535 |
+
# more generally
|
| 536 |
+
x = Symbol('x', real=True, nonzero=True)
|
| 537 |
+
y = Symbol('y', imaginary=True)
|
| 538 |
+
z = Symbol('z', complex=True)
|
| 539 |
+
assert_all_ineq_raise_TypeError(I, y)
|
| 540 |
+
|
| 541 |
+
t = I*x # an imaginary number, should raise errors
|
| 542 |
+
assert_all_ineq_raise_TypeError(2, t)
|
| 543 |
+
|
| 544 |
+
t = -I*y # a real number, so no errors
|
| 545 |
+
assert_all_ineq_give_class_Inequality(2, t)
|
| 546 |
+
|
| 547 |
+
t = I*z # unknown, should be unevaluated
|
| 548 |
+
assert_all_ineq_give_class_Inequality(2, t)
|
| 549 |
+
|
| 550 |
+
|
| 551 |
+
def test_x_minus_y_not_same_as_x_lt_y():
|
| 552 |
+
"""
|
| 553 |
+
A consequence of pull request #7792 is that `x - y < 0` and `x < y`
|
| 554 |
+
are not synonymous.
|
| 555 |
+
"""
|
| 556 |
+
x = I + 2
|
| 557 |
+
y = I + 3
|
| 558 |
+
raises(TypeError, lambda: x < y)
|
| 559 |
+
assert x - y < 0
|
| 560 |
+
|
| 561 |
+
ineq = Lt(x, y, evaluate=False)
|
| 562 |
+
raises(TypeError, lambda: ineq.doit())
|
| 563 |
+
assert ineq.lhs - ineq.rhs < 0
|
| 564 |
+
|
| 565 |
+
t = Symbol('t', imaginary=True)
|
| 566 |
+
x = 2 + t
|
| 567 |
+
y = 3 + t
|
| 568 |
+
ineq = Lt(x, y, evaluate=False)
|
| 569 |
+
raises(TypeError, lambda: ineq.doit())
|
| 570 |
+
assert ineq.lhs - ineq.rhs < 0
|
| 571 |
+
|
| 572 |
+
# this one should give error either way
|
| 573 |
+
x = I + 2
|
| 574 |
+
y = 2*I + 3
|
| 575 |
+
raises(TypeError, lambda: x < y)
|
| 576 |
+
raises(TypeError, lambda: x - y < 0)
|
| 577 |
+
|
| 578 |
+
|
| 579 |
+
def test_nan_equality_exceptions():
|
| 580 |
+
# See issue #7774
|
| 581 |
+
import random
|
| 582 |
+
assert Equality(nan, nan) is S.false
|
| 583 |
+
assert Unequality(nan, nan) is S.true
|
| 584 |
+
|
| 585 |
+
# See issue #7773
|
| 586 |
+
A = (x, S.Zero, S.One/3, pi, oo, -oo)
|
| 587 |
+
assert Equality(nan, random.choice(A)) is S.false
|
| 588 |
+
assert Equality(random.choice(A), nan) is S.false
|
| 589 |
+
assert Unequality(nan, random.choice(A)) is S.true
|
| 590 |
+
assert Unequality(random.choice(A), nan) is S.true
|
| 591 |
+
|
| 592 |
+
|
| 593 |
+
def test_nan_inequality_raise_errors():
|
| 594 |
+
# See discussion in pull request #7776. We test inequalities with
|
| 595 |
+
# a set including examples of various classes.
|
| 596 |
+
for q in (x, S.Zero, S(10), S.One/3, pi, S(1.3), oo, -oo, nan):
|
| 597 |
+
assert_all_ineq_raise_TypeError(q, nan)
|
| 598 |
+
|
| 599 |
+
|
| 600 |
+
def test_nan_complex_inequalities():
|
| 601 |
+
# Comparisons of NaN with non-real raise errors, we're not too
|
| 602 |
+
# fussy whether its the NaN error or complex error.
|
| 603 |
+
for r in (I, zoo, Symbol('z', imaginary=True)):
|
| 604 |
+
assert_all_ineq_raise_TypeError(r, nan)
|
| 605 |
+
|
| 606 |
+
|
| 607 |
+
def test_complex_infinity_inequalities():
|
| 608 |
+
raises(TypeError, lambda: zoo > 0)
|
| 609 |
+
raises(TypeError, lambda: zoo >= 0)
|
| 610 |
+
raises(TypeError, lambda: zoo < 0)
|
| 611 |
+
raises(TypeError, lambda: zoo <= 0)
|
| 612 |
+
|
| 613 |
+
|
| 614 |
+
def test_inequalities_symbol_name_same():
|
| 615 |
+
"""Using the operator and functional forms should give same results."""
|
| 616 |
+
# We test all combinations from a set
|
| 617 |
+
# FIXME: could replace with random selection after test passes
|
| 618 |
+
A = (x, y, S.Zero, S.One/3, pi, oo, -oo)
|
| 619 |
+
for a in A:
|
| 620 |
+
for b in A:
|
| 621 |
+
assert Gt(a, b) == (a > b)
|
| 622 |
+
assert Lt(a, b) == (a < b)
|
| 623 |
+
assert Ge(a, b) == (a >= b)
|
| 624 |
+
assert Le(a, b) == (a <= b)
|
| 625 |
+
|
| 626 |
+
for b in (y, S.Zero, S.One/3, pi, oo, -oo):
|
| 627 |
+
assert Gt(x, b, evaluate=False) == (x > b)
|
| 628 |
+
assert Lt(x, b, evaluate=False) == (x < b)
|
| 629 |
+
assert Ge(x, b, evaluate=False) == (x >= b)
|
| 630 |
+
assert Le(x, b, evaluate=False) == (x <= b)
|
| 631 |
+
|
| 632 |
+
for b in (y, S.Zero, S.One/3, pi, oo, -oo):
|
| 633 |
+
assert Gt(b, x, evaluate=False) == (b > x)
|
| 634 |
+
assert Lt(b, x, evaluate=False) == (b < x)
|
| 635 |
+
assert Ge(b, x, evaluate=False) == (b >= x)
|
| 636 |
+
assert Le(b, x, evaluate=False) == (b <= x)
|
| 637 |
+
|
| 638 |
+
|
| 639 |
+
def test_inequalities_symbol_name_same_complex():
|
| 640 |
+
"""Using the operator and functional forms should give same results.
|
| 641 |
+
With complex non-real numbers, both should raise errors.
|
| 642 |
+
"""
|
| 643 |
+
# FIXME: could replace with random selection after test passes
|
| 644 |
+
for a in (x, S.Zero, S.One/3, pi, oo, Rational(1, 3)):
|
| 645 |
+
raises(TypeError, lambda: Gt(a, I))
|
| 646 |
+
raises(TypeError, lambda: a > I)
|
| 647 |
+
raises(TypeError, lambda: Lt(a, I))
|
| 648 |
+
raises(TypeError, lambda: a < I)
|
| 649 |
+
raises(TypeError, lambda: Ge(a, I))
|
| 650 |
+
raises(TypeError, lambda: a >= I)
|
| 651 |
+
raises(TypeError, lambda: Le(a, I))
|
| 652 |
+
raises(TypeError, lambda: a <= I)
|
| 653 |
+
|
| 654 |
+
|
| 655 |
+
def test_inequalities_cant_sympify_other():
|
| 656 |
+
# see issue 7833
|
| 657 |
+
from operator import gt, lt, ge, le
|
| 658 |
+
|
| 659 |
+
bar = "foo"
|
| 660 |
+
|
| 661 |
+
for a in (x, S.Zero, S.One/3, pi, I, zoo, oo, -oo, nan, Rational(1, 3)):
|
| 662 |
+
for op in (lt, gt, le, ge):
|
| 663 |
+
raises(TypeError, lambda: op(a, bar))
|
| 664 |
+
|
| 665 |
+
|
| 666 |
+
def test_ineq_avoid_wild_symbol_flip():
|
| 667 |
+
# see issue #7951, we try to avoid this internally, e.g., by using
|
| 668 |
+
# __lt__ instead of "<".
|
| 669 |
+
from sympy.core.symbol import Wild
|
| 670 |
+
p = symbols('p', cls=Wild)
|
| 671 |
+
# x > p might flip, but Gt should not:
|
| 672 |
+
assert Gt(x, p) == Gt(x, p, evaluate=False)
|
| 673 |
+
# Previously failed as 'p > x':
|
| 674 |
+
e = Lt(x, y).subs({y: p})
|
| 675 |
+
assert e == Lt(x, p, evaluate=False)
|
| 676 |
+
# Previously failed as 'p <= x':
|
| 677 |
+
e = Ge(x, p).doit()
|
| 678 |
+
assert e == Ge(x, p, evaluate=False)
|
| 679 |
+
|
| 680 |
+
|
| 681 |
+
def test_issue_8245():
|
| 682 |
+
a = S("6506833320952669167898688709329/5070602400912917605986812821504")
|
| 683 |
+
assert rel_check(a, a.n(10))
|
| 684 |
+
assert rel_check(a, a.n(20))
|
| 685 |
+
assert rel_check(a, a.n())
|
| 686 |
+
# prec of 31 is enough to fully capture a as mpf
|
| 687 |
+
assert Float(a, 31) == Float(str(a.p), '')/Float(str(a.q), '')
|
| 688 |
+
for i in range(31):
|
| 689 |
+
r = Rational(Float(a, i))
|
| 690 |
+
f = Float(r)
|
| 691 |
+
assert (f < a) == (Rational(f) < a)
|
| 692 |
+
# test sign handling
|
| 693 |
+
assert (-f < -a) == (Rational(-f) < -a)
|
| 694 |
+
# test equivalence handling
|
| 695 |
+
isa = Float(a.p,'')/Float(a.q,'')
|
| 696 |
+
assert isa <= a
|
| 697 |
+
assert not isa < a
|
| 698 |
+
assert isa >= a
|
| 699 |
+
assert not isa > a
|
| 700 |
+
assert isa > 0
|
| 701 |
+
|
| 702 |
+
a = sqrt(2)
|
| 703 |
+
r = Rational(str(a.n(30)))
|
| 704 |
+
assert rel_check(a, r)
|
| 705 |
+
|
| 706 |
+
a = sqrt(2)
|
| 707 |
+
r = Rational(str(a.n(29)))
|
| 708 |
+
assert rel_check(a, r)
|
| 709 |
+
|
| 710 |
+
assert Eq(log(cos(2)**2 + sin(2)**2), 0) is S.true
|
| 711 |
+
|
| 712 |
+
|
| 713 |
+
def test_issue_8449():
|
| 714 |
+
p = Symbol('p', nonnegative=True)
|
| 715 |
+
assert Lt(-oo, p)
|
| 716 |
+
assert Ge(-oo, p) is S.false
|
| 717 |
+
assert Gt(oo, -p)
|
| 718 |
+
assert Le(oo, -p) is S.false
|
| 719 |
+
|
| 720 |
+
|
| 721 |
+
def test_simplify_relational():
|
| 722 |
+
assert simplify(x*(y + 1) - x*y - x + 1 < x) == (x > 1)
|
| 723 |
+
assert simplify(x*(y + 1) - x*y - x - 1 < x) == (x > -1)
|
| 724 |
+
assert simplify(x < x*(y + 1) - x*y - x + 1) == (x < 1)
|
| 725 |
+
q, r = symbols("q r")
|
| 726 |
+
assert (((-q + r) - (q - r)) <= 0).simplify() == (q >= r)
|
| 727 |
+
root2 = sqrt(2)
|
| 728 |
+
equation = ((root2 * (-q + r) - root2 * (q - r)) <= 0).simplify()
|
| 729 |
+
assert equation == (q >= r)
|
| 730 |
+
r = S.One < x
|
| 731 |
+
# canonical operations are not the same as simplification,
|
| 732 |
+
# so if there is no simplification, canonicalization will
|
| 733 |
+
# be done unless the measure forbids it
|
| 734 |
+
assert simplify(r) == r.canonical
|
| 735 |
+
assert simplify(r, ratio=0) != r.canonical
|
| 736 |
+
# this is not a random test; in _eval_simplify
|
| 737 |
+
# this will simplify to S.false and that is the
|
| 738 |
+
# reason for the 'if r.is_Relational' in Relational's
|
| 739 |
+
# _eval_simplify routine
|
| 740 |
+
assert simplify(-(2**(pi*Rational(3, 2)) + 6**pi)**(1/pi) +
|
| 741 |
+
2*(2**(pi/2) + 3**pi)**(1/pi) < 0) is S.false
|
| 742 |
+
# canonical at least
|
| 743 |
+
assert Eq(y, x).simplify() == Eq(x, y)
|
| 744 |
+
assert Eq(x - 1, 0).simplify() == Eq(x, 1)
|
| 745 |
+
assert Eq(x - 1, x).simplify() == S.false
|
| 746 |
+
assert Eq(2*x - 1, x).simplify() == Eq(x, 1)
|
| 747 |
+
assert Eq(2*x, 4).simplify() == Eq(x, 2)
|
| 748 |
+
z = cos(1)**2 + sin(1)**2 - 1 # z.is_zero is None
|
| 749 |
+
assert Eq(z*x, 0).simplify() == S.true
|
| 750 |
+
|
| 751 |
+
assert Ne(y, x).simplify() == Ne(x, y)
|
| 752 |
+
assert Ne(x - 1, 0).simplify() == Ne(x, 1)
|
| 753 |
+
assert Ne(x - 1, x).simplify() == S.true
|
| 754 |
+
assert Ne(2*x - 1, x).simplify() == Ne(x, 1)
|
| 755 |
+
assert Ne(2*x, 4).simplify() == Ne(x, 2)
|
| 756 |
+
assert Ne(z*x, 0).simplify() == S.false
|
| 757 |
+
|
| 758 |
+
# No real-valued assumptions
|
| 759 |
+
assert Ge(y, x).simplify() == Le(x, y)
|
| 760 |
+
assert Ge(x - 1, 0).simplify() == Ge(x, 1)
|
| 761 |
+
assert Ge(x - 1, x).simplify() == S.false
|
| 762 |
+
assert Ge(2*x - 1, x).simplify() == Ge(x, 1)
|
| 763 |
+
assert Ge(2*x, 4).simplify() == Ge(x, 2)
|
| 764 |
+
assert Ge(z*x, 0).simplify() == S.true
|
| 765 |
+
assert Ge(x, -2).simplify() == Ge(x, -2)
|
| 766 |
+
assert Ge(-x, -2).simplify() == Le(x, 2)
|
| 767 |
+
assert Ge(x, 2).simplify() == Ge(x, 2)
|
| 768 |
+
assert Ge(-x, 2).simplify() == Le(x, -2)
|
| 769 |
+
|
| 770 |
+
assert Le(y, x).simplify() == Ge(x, y)
|
| 771 |
+
assert Le(x - 1, 0).simplify() == Le(x, 1)
|
| 772 |
+
assert Le(x - 1, x).simplify() == S.true
|
| 773 |
+
assert Le(2*x - 1, x).simplify() == Le(x, 1)
|
| 774 |
+
assert Le(2*x, 4).simplify() == Le(x, 2)
|
| 775 |
+
assert Le(z*x, 0).simplify() == S.true
|
| 776 |
+
assert Le(x, -2).simplify() == Le(x, -2)
|
| 777 |
+
assert Le(-x, -2).simplify() == Ge(x, 2)
|
| 778 |
+
assert Le(x, 2).simplify() == Le(x, 2)
|
| 779 |
+
assert Le(-x, 2).simplify() == Ge(x, -2)
|
| 780 |
+
|
| 781 |
+
assert Gt(y, x).simplify() == Lt(x, y)
|
| 782 |
+
assert Gt(x - 1, 0).simplify() == Gt(x, 1)
|
| 783 |
+
assert Gt(x - 1, x).simplify() == S.false
|
| 784 |
+
assert Gt(2*x - 1, x).simplify() == Gt(x, 1)
|
| 785 |
+
assert Gt(2*x, 4).simplify() == Gt(x, 2)
|
| 786 |
+
assert Gt(z*x, 0).simplify() == S.false
|
| 787 |
+
assert Gt(x, -2).simplify() == Gt(x, -2)
|
| 788 |
+
assert Gt(-x, -2).simplify() == Lt(x, 2)
|
| 789 |
+
assert Gt(x, 2).simplify() == Gt(x, 2)
|
| 790 |
+
assert Gt(-x, 2).simplify() == Lt(x, -2)
|
| 791 |
+
|
| 792 |
+
assert Lt(y, x).simplify() == Gt(x, y)
|
| 793 |
+
assert Lt(x - 1, 0).simplify() == Lt(x, 1)
|
| 794 |
+
assert Lt(x - 1, x).simplify() == S.true
|
| 795 |
+
assert Lt(2*x - 1, x).simplify() == Lt(x, 1)
|
| 796 |
+
assert Lt(2*x, 4).simplify() == Lt(x, 2)
|
| 797 |
+
assert Lt(z*x, 0).simplify() == S.false
|
| 798 |
+
assert Lt(x, -2).simplify() == Lt(x, -2)
|
| 799 |
+
assert Lt(-x, -2).simplify() == Gt(x, 2)
|
| 800 |
+
assert Lt(x, 2).simplify() == Lt(x, 2)
|
| 801 |
+
assert Lt(-x, 2).simplify() == Gt(x, -2)
|
| 802 |
+
|
| 803 |
+
# Test particular branches of _eval_simplify
|
| 804 |
+
m = exp(1) - exp_polar(1)
|
| 805 |
+
assert simplify(m*x > 1) is S.false
|
| 806 |
+
# These two test the same branch
|
| 807 |
+
assert simplify(m*x + 2*m*y > 1) is S.false
|
| 808 |
+
assert simplify(m*x + y > 1 + y) is S.false
|
| 809 |
+
|
| 810 |
+
|
| 811 |
+
def test_equals():
|
| 812 |
+
w, x, y, z = symbols('w:z')
|
| 813 |
+
f = Function('f')
|
| 814 |
+
assert Eq(x, 1).equals(Eq(x*(y + 1) - x*y - x + 1, x))
|
| 815 |
+
assert Eq(x, y).equals(x < y, True) == False
|
| 816 |
+
assert Eq(x, f(1)).equals(Eq(x, f(2)), True) == f(1) - f(2)
|
| 817 |
+
assert Eq(f(1), y).equals(Eq(f(2), y), True) == f(1) - f(2)
|
| 818 |
+
assert Eq(x, f(1)).equals(Eq(f(2), x), True) == f(1) - f(2)
|
| 819 |
+
assert Eq(f(1), x).equals(Eq(x, f(2)), True) == f(1) - f(2)
|
| 820 |
+
assert Eq(w, x).equals(Eq(y, z), True) == False
|
| 821 |
+
assert Eq(f(1), f(2)).equals(Eq(f(3), f(4)), True) == f(1) - f(3)
|
| 822 |
+
assert (x < y).equals(y > x, True) == True
|
| 823 |
+
assert (x < y).equals(y >= x, True) == False
|
| 824 |
+
assert (x < y).equals(z < y, True) == False
|
| 825 |
+
assert (x < y).equals(x < z, True) == False
|
| 826 |
+
assert (x < f(1)).equals(x < f(2), True) == f(1) - f(2)
|
| 827 |
+
assert (f(1) < x).equals(f(2) < x, True) == f(1) - f(2)
|
| 828 |
+
|
| 829 |
+
|
| 830 |
+
def test_reversed():
|
| 831 |
+
assert (x < y).reversed == (y > x)
|
| 832 |
+
assert (x <= y).reversed == (y >= x)
|
| 833 |
+
assert Eq(x, y, evaluate=False).reversed == Eq(y, x, evaluate=False)
|
| 834 |
+
assert Ne(x, y, evaluate=False).reversed == Ne(y, x, evaluate=False)
|
| 835 |
+
assert (x >= y).reversed == (y <= x)
|
| 836 |
+
assert (x > y).reversed == (y < x)
|
| 837 |
+
|
| 838 |
+
|
| 839 |
+
def test_canonical():
|
| 840 |
+
c = [i.canonical for i in (
|
| 841 |
+
x + y < z,
|
| 842 |
+
x + 2 > 3,
|
| 843 |
+
x < 2,
|
| 844 |
+
S(2) > x,
|
| 845 |
+
x**2 > -x/y,
|
| 846 |
+
Gt(3, 2, evaluate=False)
|
| 847 |
+
)]
|
| 848 |
+
assert [i.canonical for i in c] == c
|
| 849 |
+
assert [i.reversed.canonical for i in c] == c
|
| 850 |
+
assert not any(i.lhs.is_Number and not i.rhs.is_Number for i in c)
|
| 851 |
+
|
| 852 |
+
c = [i.reversed.func(i.rhs, i.lhs, evaluate=False).canonical for i in c]
|
| 853 |
+
assert [i.canonical for i in c] == c
|
| 854 |
+
assert [i.reversed.canonical for i in c] == c
|
| 855 |
+
assert not any(i.lhs.is_Number and not i.rhs.is_Number for i in c)
|
| 856 |
+
assert Eq(y < x, x > y).canonical is S.true
|
| 857 |
+
|
| 858 |
+
|
| 859 |
+
@XFAIL
|
| 860 |
+
def test_issue_8444_nonworkingtests():
|
| 861 |
+
x = symbols('x', real=True)
|
| 862 |
+
assert (x <= oo) == (x >= -oo) == True
|
| 863 |
+
|
| 864 |
+
x = symbols('x')
|
| 865 |
+
assert x >= floor(x)
|
| 866 |
+
assert (x < floor(x)) == False
|
| 867 |
+
assert x <= ceiling(x)
|
| 868 |
+
assert (x > ceiling(x)) == False
|
| 869 |
+
|
| 870 |
+
|
| 871 |
+
def test_issue_8444_workingtests():
|
| 872 |
+
x = symbols('x')
|
| 873 |
+
assert Gt(x, floor(x)) == Gt(x, floor(x), evaluate=False)
|
| 874 |
+
assert Ge(x, floor(x)) == Ge(x, floor(x), evaluate=False)
|
| 875 |
+
assert Lt(x, ceiling(x)) == Lt(x, ceiling(x), evaluate=False)
|
| 876 |
+
assert Le(x, ceiling(x)) == Le(x, ceiling(x), evaluate=False)
|
| 877 |
+
i = symbols('i', integer=True)
|
| 878 |
+
assert (i > floor(i)) == False
|
| 879 |
+
assert (i < ceiling(i)) == False
|
| 880 |
+
|
| 881 |
+
|
| 882 |
+
def test_issue_10304():
|
| 883 |
+
d = cos(1)**2 + sin(1)**2 - 1
|
| 884 |
+
assert d.is_comparable is False # if this fails, find a new d
|
| 885 |
+
e = 1 + d*I
|
| 886 |
+
assert simplify(Eq(e, 0)) is S.false
|
| 887 |
+
|
| 888 |
+
|
| 889 |
+
def test_issue_18412():
|
| 890 |
+
d = (Rational(1, 6) + z / 4 / y)
|
| 891 |
+
assert Eq(x, pi * y**3 * d).replace(y**3, z) == Eq(x, pi * z * d)
|
| 892 |
+
|
| 893 |
+
|
| 894 |
+
def test_issue_10401():
|
| 895 |
+
x = symbols('x')
|
| 896 |
+
fin = symbols('inf', finite=True)
|
| 897 |
+
inf = symbols('inf', infinite=True)
|
| 898 |
+
inf2 = symbols('inf2', infinite=True)
|
| 899 |
+
infx = symbols('infx', infinite=True, extended_real=True)
|
| 900 |
+
# Used in the commented tests below:
|
| 901 |
+
#infx2 = symbols('infx2', infinite=True, extended_real=True)
|
| 902 |
+
infnx = symbols('inf~x', infinite=True, extended_real=False)
|
| 903 |
+
infnx2 = symbols('inf~x2', infinite=True, extended_real=False)
|
| 904 |
+
infp = symbols('infp', infinite=True, extended_positive=True)
|
| 905 |
+
infp1 = symbols('infp1', infinite=True, extended_positive=True)
|
| 906 |
+
infn = symbols('infn', infinite=True, extended_negative=True)
|
| 907 |
+
zero = symbols('z', zero=True)
|
| 908 |
+
nonzero = symbols('nz', zero=False, finite=True)
|
| 909 |
+
|
| 910 |
+
assert Eq(1/(1/x + 1), 1).func is Eq
|
| 911 |
+
assert Eq(1/(1/x + 1), 1).subs(x, S.ComplexInfinity) is S.true
|
| 912 |
+
assert Eq(1/(1/fin + 1), 1) is S.false
|
| 913 |
+
|
| 914 |
+
T, F = S.true, S.false
|
| 915 |
+
assert Eq(fin, inf) is F
|
| 916 |
+
assert Eq(inf, inf2) not in (T, F) and inf != inf2
|
| 917 |
+
assert Eq(1 + inf, 2 + inf2) not in (T, F) and inf != inf2
|
| 918 |
+
assert Eq(infp, infp1) is T
|
| 919 |
+
assert Eq(infp, infn) is F
|
| 920 |
+
assert Eq(1 + I*oo, I*oo) is F
|
| 921 |
+
assert Eq(I*oo, 1 + I*oo) is F
|
| 922 |
+
assert Eq(1 + I*oo, 2 + I*oo) is F
|
| 923 |
+
assert Eq(1 + I*oo, 2 + I*infx) is F
|
| 924 |
+
assert Eq(1 + I*oo, 2 + infx) is F
|
| 925 |
+
# FIXME: The test below fails because (-infx).is_extended_positive is True
|
| 926 |
+
# (should be None)
|
| 927 |
+
#assert Eq(1 + I*infx, 1 + I*infx2) not in (T, F) and infx != infx2
|
| 928 |
+
#
|
| 929 |
+
assert Eq(zoo, sqrt(2) + I*oo) is F
|
| 930 |
+
assert Eq(zoo, oo) is F
|
| 931 |
+
r = Symbol('r', real=True)
|
| 932 |
+
i = Symbol('i', imaginary=True)
|
| 933 |
+
assert Eq(i*I, r) not in (T, F)
|
| 934 |
+
assert Eq(infx, infnx) is F
|
| 935 |
+
assert Eq(infnx, infnx2) not in (T, F) and infnx != infnx2
|
| 936 |
+
assert Eq(zoo, oo) is F
|
| 937 |
+
assert Eq(inf/inf2, 0) is F
|
| 938 |
+
assert Eq(inf/fin, 0) is F
|
| 939 |
+
assert Eq(fin/inf, 0) is T
|
| 940 |
+
assert Eq(zero/nonzero, 0) is T and ((zero/nonzero) != 0)
|
| 941 |
+
# The commented out test below is incorrect because:
|
| 942 |
+
assert zoo == -zoo
|
| 943 |
+
assert Eq(zoo, -zoo) is T
|
| 944 |
+
assert Eq(oo, -oo) is F
|
| 945 |
+
assert Eq(inf, -inf) not in (T, F)
|
| 946 |
+
|
| 947 |
+
assert Eq(fin/(fin + 1), 1) is S.false
|
| 948 |
+
|
| 949 |
+
o = symbols('o', odd=True)
|
| 950 |
+
assert Eq(o, 2*o) is S.false
|
| 951 |
+
|
| 952 |
+
p = symbols('p', positive=True)
|
| 953 |
+
assert Eq(p/(p - 1), 1) is F
|
| 954 |
+
|
| 955 |
+
|
| 956 |
+
def test_issue_10633():
|
| 957 |
+
assert Eq(True, False) == False
|
| 958 |
+
assert Eq(False, True) == False
|
| 959 |
+
assert Eq(True, True) == True
|
| 960 |
+
assert Eq(False, False) == True
|
| 961 |
+
|
| 962 |
+
|
| 963 |
+
def test_issue_10927():
|
| 964 |
+
x = symbols('x')
|
| 965 |
+
assert str(Eq(x, oo)) == 'Eq(x, oo)'
|
| 966 |
+
assert str(Eq(x, -oo)) == 'Eq(x, -oo)'
|
| 967 |
+
|
| 968 |
+
|
| 969 |
+
def test_issues_13081_12583_12534():
|
| 970 |
+
# 13081
|
| 971 |
+
r = Rational('905502432259640373/288230376151711744')
|
| 972 |
+
assert (r < pi) is S.false
|
| 973 |
+
assert (r > pi) is S.true
|
| 974 |
+
# 12583
|
| 975 |
+
v = sqrt(2)
|
| 976 |
+
u = sqrt(v) + 2/sqrt(10 - 8/sqrt(2 - v) + 4*v*(1/sqrt(2 - v) - 1))
|
| 977 |
+
assert (u >= 0) is S.true
|
| 978 |
+
# 12534; Rational vs NumberSymbol
|
| 979 |
+
# here are some precisions for which Rational forms
|
| 980 |
+
# at a lower and higher precision bracket the value of pi
|
| 981 |
+
# e.g. for p = 20:
|
| 982 |
+
# Rational(pi.n(p + 1)).n(25) = 3.14159265358979323846 2834
|
| 983 |
+
# pi.n(25) = 3.14159265358979323846 2643
|
| 984 |
+
# Rational(pi.n(p )).n(25) = 3.14159265358979323846 1987
|
| 985 |
+
assert [p for p in range(20, 50) if
|
| 986 |
+
(Rational(pi.n(p)) < pi) and
|
| 987 |
+
(pi < Rational(pi.n(p + 1)))] == [20, 24, 27, 33, 37, 43, 48]
|
| 988 |
+
# pick one such precision and affirm that the reversed operation
|
| 989 |
+
# gives the opposite result, i.e. if x < y is true then x > y
|
| 990 |
+
# must be false
|
| 991 |
+
for i in (20, 21):
|
| 992 |
+
v = pi.n(i)
|
| 993 |
+
assert rel_check(Rational(v), pi)
|
| 994 |
+
assert rel_check(v, pi)
|
| 995 |
+
assert rel_check(pi.n(20), pi.n(21))
|
| 996 |
+
# Float vs Rational
|
| 997 |
+
# the rational form is less than the floating representation
|
| 998 |
+
# at the same precision
|
| 999 |
+
assert [i for i in range(15, 50) if Rational(pi.n(i)) > pi.n(i)] == []
|
| 1000 |
+
# this should be the same if we reverse the relational
|
| 1001 |
+
assert [i for i in range(15, 50) if pi.n(i) < Rational(pi.n(i))] == []
|
| 1002 |
+
|
| 1003 |
+
def test_issue_18188():
|
| 1004 |
+
from sympy.sets.conditionset import ConditionSet
|
| 1005 |
+
result1 = Eq(x*cos(x) - 3*sin(x), 0)
|
| 1006 |
+
assert result1.as_set() == ConditionSet(x, Eq(x*cos(x) - 3*sin(x), 0), Reals)
|
| 1007 |
+
|
| 1008 |
+
result2 = Eq(x**2 + sqrt(x*2) + sin(x), 0)
|
| 1009 |
+
assert result2.as_set() == ConditionSet(x, Eq(sqrt(2)*sqrt(x) + x**2 + sin(x), 0), Reals)
|
| 1010 |
+
|
| 1011 |
+
def test_binary_symbols():
|
| 1012 |
+
ans = {x}
|
| 1013 |
+
for f in Eq, Ne:
|
| 1014 |
+
for t in S.true, S.false:
|
| 1015 |
+
eq = f(x, S.true)
|
| 1016 |
+
assert eq.binary_symbols == ans
|
| 1017 |
+
assert eq.reversed.binary_symbols == ans
|
| 1018 |
+
assert f(x, 1).binary_symbols == set()
|
| 1019 |
+
|
| 1020 |
+
|
| 1021 |
+
def test_rel_args():
|
| 1022 |
+
# can't have Boolean args; this is automatic for True/False
|
| 1023 |
+
# with Python 3 and we confirm that SymPy does the same
|
| 1024 |
+
# for true/false
|
| 1025 |
+
for op in ['<', '<=', '>', '>=']:
|
| 1026 |
+
for b in (S.true, x < 1, And(x, y)):
|
| 1027 |
+
for v in (0.1, 1, 2**32, t, S.One):
|
| 1028 |
+
raises(TypeError, lambda: Relational(b, v, op))
|
| 1029 |
+
|
| 1030 |
+
|
| 1031 |
+
def test_nothing_happens_to_Eq_condition_during_simplify():
|
| 1032 |
+
# issue 25701
|
| 1033 |
+
r = symbols('r', real=True)
|
| 1034 |
+
assert Eq(2*sign(r + 3)/(5*Abs(r + 3)**Rational(3, 5)), 0
|
| 1035 |
+
).simplify() == Eq(Piecewise(
|
| 1036 |
+
(0, Eq(r, -3)), ((r + 3)/(5*Abs((r + 3)**Rational(8, 5)))*2, True)), 0)
|
| 1037 |
+
|
| 1038 |
+
|
| 1039 |
+
def test_issue_15847():
|
| 1040 |
+
a = Ne(x*(x + y), x**2 + x*y)
|
| 1041 |
+
assert simplify(a) == False
|
| 1042 |
+
|
| 1043 |
+
|
| 1044 |
+
def test_negated_property():
|
| 1045 |
+
eq = Eq(x, y)
|
| 1046 |
+
assert eq.negated == Ne(x, y)
|
| 1047 |
+
|
| 1048 |
+
eq = Ne(x, y)
|
| 1049 |
+
assert eq.negated == Eq(x, y)
|
| 1050 |
+
|
| 1051 |
+
eq = Ge(x + y, y - x)
|
| 1052 |
+
assert eq.negated == Lt(x + y, y - x)
|
| 1053 |
+
|
| 1054 |
+
for f in (Eq, Ne, Ge, Gt, Le, Lt):
|
| 1055 |
+
assert f(x, y).negated.negated == f(x, y)
|
| 1056 |
+
|
| 1057 |
+
|
| 1058 |
+
def test_reversedsign_property():
|
| 1059 |
+
eq = Eq(x, y)
|
| 1060 |
+
assert eq.reversedsign == Eq(-x, -y)
|
| 1061 |
+
|
| 1062 |
+
eq = Ne(x, y)
|
| 1063 |
+
assert eq.reversedsign == Ne(-x, -y)
|
| 1064 |
+
|
| 1065 |
+
eq = Ge(x + y, y - x)
|
| 1066 |
+
assert eq.reversedsign == Le(-x - y, x - y)
|
| 1067 |
+
|
| 1068 |
+
for f in (Eq, Ne, Ge, Gt, Le, Lt):
|
| 1069 |
+
assert f(x, y).reversedsign.reversedsign == f(x, y)
|
| 1070 |
+
|
| 1071 |
+
for f in (Eq, Ne, Ge, Gt, Le, Lt):
|
| 1072 |
+
assert f(-x, y).reversedsign.reversedsign == f(-x, y)
|
| 1073 |
+
|
| 1074 |
+
for f in (Eq, Ne, Ge, Gt, Le, Lt):
|
| 1075 |
+
assert f(x, -y).reversedsign.reversedsign == f(x, -y)
|
| 1076 |
+
|
| 1077 |
+
for f in (Eq, Ne, Ge, Gt, Le, Lt):
|
| 1078 |
+
assert f(-x, -y).reversedsign.reversedsign == f(-x, -y)
|
| 1079 |
+
|
| 1080 |
+
|
| 1081 |
+
def test_reversed_reversedsign_property():
|
| 1082 |
+
for f in (Eq, Ne, Ge, Gt, Le, Lt):
|
| 1083 |
+
assert f(x, y).reversed.reversedsign == f(x, y).reversedsign.reversed
|
| 1084 |
+
|
| 1085 |
+
for f in (Eq, Ne, Ge, Gt, Le, Lt):
|
| 1086 |
+
assert f(-x, y).reversed.reversedsign == f(-x, y).reversedsign.reversed
|
| 1087 |
+
|
| 1088 |
+
for f in (Eq, Ne, Ge, Gt, Le, Lt):
|
| 1089 |
+
assert f(x, -y).reversed.reversedsign == f(x, -y).reversedsign.reversed
|
| 1090 |
+
|
| 1091 |
+
for f in (Eq, Ne, Ge, Gt, Le, Lt):
|
| 1092 |
+
assert f(-x, -y).reversed.reversedsign == \
|
| 1093 |
+
f(-x, -y).reversedsign.reversed
|
| 1094 |
+
|
| 1095 |
+
|
| 1096 |
+
def test_improved_canonical():
|
| 1097 |
+
def test_different_forms(listofforms):
|
| 1098 |
+
for form1, form2 in combinations(listofforms, 2):
|
| 1099 |
+
assert form1.canonical == form2.canonical
|
| 1100 |
+
|
| 1101 |
+
def generate_forms(expr):
|
| 1102 |
+
return [expr, expr.reversed, expr.reversedsign,
|
| 1103 |
+
expr.reversed.reversedsign]
|
| 1104 |
+
|
| 1105 |
+
test_different_forms(generate_forms(x > -y))
|
| 1106 |
+
test_different_forms(generate_forms(x >= -y))
|
| 1107 |
+
test_different_forms(generate_forms(Eq(x, -y)))
|
| 1108 |
+
test_different_forms(generate_forms(Ne(x, -y)))
|
| 1109 |
+
test_different_forms(generate_forms(pi < x))
|
| 1110 |
+
test_different_forms(generate_forms(pi - 5*y < -x + 2*y**2 - 7))
|
| 1111 |
+
|
| 1112 |
+
assert (pi >= x).canonical == (x <= pi)
|
| 1113 |
+
|
| 1114 |
+
|
| 1115 |
+
def test_set_equality_canonical():
|
| 1116 |
+
a, b, c = symbols('a b c')
|
| 1117 |
+
|
| 1118 |
+
A = Eq(FiniteSet(a, b, c), FiniteSet(1, 2, 3))
|
| 1119 |
+
B = Ne(FiniteSet(a, b, c), FiniteSet(4, 5, 6))
|
| 1120 |
+
|
| 1121 |
+
assert A.canonical == A.reversed
|
| 1122 |
+
assert B.canonical == B.reversed
|
| 1123 |
+
|
| 1124 |
+
|
| 1125 |
+
def test_trigsimp():
|
| 1126 |
+
# issue 16736
|
| 1127 |
+
s, c = sin(2*x), cos(2*x)
|
| 1128 |
+
eq = Eq(s, c)
|
| 1129 |
+
assert trigsimp(eq) == eq # no rearrangement of sides
|
| 1130 |
+
# simplification of sides might result in
|
| 1131 |
+
# an unevaluated Eq
|
| 1132 |
+
changed = trigsimp(Eq(s + c, sqrt(2)))
|
| 1133 |
+
assert isinstance(changed, Eq)
|
| 1134 |
+
assert changed.subs(x, pi/8) is S.true
|
| 1135 |
+
# or an evaluated one
|
| 1136 |
+
assert trigsimp(Eq(cos(x)**2 + sin(x)**2, 1)) is S.true
|
| 1137 |
+
|
| 1138 |
+
|
| 1139 |
+
def test_polynomial_relation_simplification():
|
| 1140 |
+
assert Ge(3*x*(x + 1) + 4, 3*x).simplify() in [Ge(x**2, -Rational(4,3)), Le(-x**2, Rational(4, 3))]
|
| 1141 |
+
assert Le(-(3*x*(x + 1) + 4), -3*x).simplify() in [Ge(x**2, -Rational(4,3)), Le(-x**2, Rational(4, 3))]
|
| 1142 |
+
assert ((x**2+3)*(x**2-1)+3*x >= 2*x**2).simplify() in [(x**4 + 3*x >= 3), (-x**4 - 3*x <= -3)]
|
| 1143 |
+
|
| 1144 |
+
|
| 1145 |
+
def test_multivariate_linear_function_simplification():
|
| 1146 |
+
assert Ge(x + y, x - y).simplify() == Ge(y, 0)
|
| 1147 |
+
assert Le(-x + y, -x - y).simplify() == Le(y, 0)
|
| 1148 |
+
assert Eq(2*x + y, 2*x + y - 3).simplify() == False
|
| 1149 |
+
assert (2*x + y > 2*x + y - 3).simplify() == True
|
| 1150 |
+
assert (2*x + y < 2*x + y - 3).simplify() == False
|
| 1151 |
+
assert (2*x + y < 2*x + y + 3).simplify() == True
|
| 1152 |
+
a, b, c, d, e, f, g = symbols('a b c d e f g')
|
| 1153 |
+
assert Lt(a + b + c + 2*d, 3*d - f + g). simplify() == Lt(a, -b - c + d - f + g)
|
| 1154 |
+
|
| 1155 |
+
|
| 1156 |
+
def test_nonpolymonial_relations():
|
| 1157 |
+
assert Eq(cos(x), 0).simplify() == Eq(cos(x), 0)
|
| 1158 |
+
|
| 1159 |
+
def test_18778():
|
| 1160 |
+
raises(TypeError, lambda: is_le(Basic(), Basic()))
|
| 1161 |
+
raises(TypeError, lambda: is_gt(Basic(), Basic()))
|
| 1162 |
+
raises(TypeError, lambda: is_ge(Basic(), Basic()))
|
| 1163 |
+
raises(TypeError, lambda: is_lt(Basic(), Basic()))
|
| 1164 |
+
|
| 1165 |
+
def test_EvalEq():
|
| 1166 |
+
"""
|
| 1167 |
+
|
| 1168 |
+
This test exists to ensure backwards compatibility.
|
| 1169 |
+
The method to use is _eval_is_eq
|
| 1170 |
+
"""
|
| 1171 |
+
from sympy.core.expr import Expr
|
| 1172 |
+
|
| 1173 |
+
class PowTest(Expr):
|
| 1174 |
+
def __new__(cls, base, exp):
|
| 1175 |
+
return Basic.__new__(PowTest, _sympify(base), _sympify(exp))
|
| 1176 |
+
|
| 1177 |
+
def _eval_Eq(lhs, rhs):
|
| 1178 |
+
if type(lhs) == PowTest and type(rhs) == PowTest:
|
| 1179 |
+
return lhs.args[0] == rhs.args[0] and lhs.args[1] == rhs.args[1]
|
| 1180 |
+
|
| 1181 |
+
assert is_eq(PowTest(3, 4), PowTest(3,4))
|
| 1182 |
+
assert is_eq(PowTest(3, 4), _sympify(4)) is None
|
| 1183 |
+
assert is_neq(PowTest(3, 4), PowTest(3,7))
|
| 1184 |
+
|
| 1185 |
+
|
| 1186 |
+
def test_is_eq():
|
| 1187 |
+
# test assumptions
|
| 1188 |
+
assert is_eq(x, y, Q.infinite(x) & Q.finite(y)) is False
|
| 1189 |
+
assert is_eq(x, y, Q.infinite(x) & Q.infinite(y) & Q.extended_real(x) & ~Q.extended_real(y)) is False
|
| 1190 |
+
assert is_eq(x, y, Q.infinite(x) & Q.infinite(y) & Q.extended_positive(x) & Q.extended_negative(y)) is False
|
| 1191 |
+
|
| 1192 |
+
assert is_eq(x+I, y+I, Q.infinite(x) & Q.finite(y)) is False
|
| 1193 |
+
assert is_eq(1+x*I, 1+y*I, Q.infinite(x) & Q.finite(y)) is False
|
| 1194 |
+
|
| 1195 |
+
assert is_eq(x, S(0), assumptions=Q.zero(x))
|
| 1196 |
+
assert is_eq(x, S(0), assumptions=~Q.zero(x)) is False
|
| 1197 |
+
assert is_eq(x, S(0), assumptions=Q.nonzero(x)) is False
|
| 1198 |
+
assert is_neq(x, S(0), assumptions=Q.zero(x)) is False
|
| 1199 |
+
assert is_neq(x, S(0), assumptions=~Q.zero(x))
|
| 1200 |
+
assert is_neq(x, S(0), assumptions=Q.nonzero(x))
|
| 1201 |
+
|
| 1202 |
+
# test registration
|
| 1203 |
+
class PowTest(Expr):
|
| 1204 |
+
def __new__(cls, base, exp):
|
| 1205 |
+
return Basic.__new__(cls, _sympify(base), _sympify(exp))
|
| 1206 |
+
|
| 1207 |
+
@dispatch(PowTest, PowTest)
|
| 1208 |
+
def _eval_is_eq(lhs, rhs):
|
| 1209 |
+
if type(lhs) == PowTest and type(rhs) == PowTest:
|
| 1210 |
+
return fuzzy_and([is_eq(lhs.args[0], rhs.args[0]), is_eq(lhs.args[1], rhs.args[1])])
|
| 1211 |
+
|
| 1212 |
+
assert is_eq(PowTest(3, 4), PowTest(3,4))
|
| 1213 |
+
assert is_eq(PowTest(3, 4), _sympify(4)) is None
|
| 1214 |
+
assert is_neq(PowTest(3, 4), PowTest(3,7))
|
| 1215 |
+
|
| 1216 |
+
|
| 1217 |
+
def test_is_ge_le():
|
| 1218 |
+
# test assumptions
|
| 1219 |
+
assert is_ge(x, S(0), Q.nonnegative(x)) is True
|
| 1220 |
+
assert is_ge(x, S(0), Q.negative(x)) is False
|
| 1221 |
+
|
| 1222 |
+
# test registration
|
| 1223 |
+
class PowTest(Expr):
|
| 1224 |
+
def __new__(cls, base, exp):
|
| 1225 |
+
return Basic.__new__(cls, _sympify(base), _sympify(exp))
|
| 1226 |
+
|
| 1227 |
+
@dispatch(PowTest, PowTest)
|
| 1228 |
+
def _eval_is_ge(lhs, rhs):
|
| 1229 |
+
if type(lhs) == PowTest and type(rhs) == PowTest:
|
| 1230 |
+
return fuzzy_and([is_ge(lhs.args[0], rhs.args[0]), is_ge(lhs.args[1], rhs.args[1])])
|
| 1231 |
+
|
| 1232 |
+
assert is_ge(PowTest(3, 9), PowTest(3,2))
|
| 1233 |
+
assert is_gt(PowTest(3, 9), PowTest(3,2))
|
| 1234 |
+
assert is_le(PowTest(3, 2), PowTest(3,9))
|
| 1235 |
+
assert is_lt(PowTest(3, 2), PowTest(3,9))
|
| 1236 |
+
|
| 1237 |
+
|
| 1238 |
+
def test_weak_strict():
|
| 1239 |
+
for func in (Eq, Ne):
|
| 1240 |
+
eq = func(x, 1)
|
| 1241 |
+
assert eq.strict == eq.weak == eq
|
| 1242 |
+
eq = Gt(x, 1)
|
| 1243 |
+
assert eq.weak == Ge(x, 1)
|
| 1244 |
+
assert eq.strict == eq
|
| 1245 |
+
eq = Lt(x, 1)
|
| 1246 |
+
assert eq.weak == Le(x, 1)
|
| 1247 |
+
assert eq.strict == eq
|
| 1248 |
+
eq = Ge(x, 1)
|
| 1249 |
+
assert eq.strict == Gt(x, 1)
|
| 1250 |
+
assert eq.weak == eq
|
| 1251 |
+
eq = Le(x, 1)
|
| 1252 |
+
assert eq.strict == Lt(x, 1)
|
| 1253 |
+
assert eq.weak == eq
|
| 1254 |
+
|
| 1255 |
+
|
| 1256 |
+
def test_issue_23731():
|
| 1257 |
+
i = symbols('i', integer=True)
|
| 1258 |
+
assert unchanged(Eq, i, 1.0)
|
| 1259 |
+
assert unchanged(Eq, i/2, 0.5)
|
| 1260 |
+
ni = symbols('ni', integer=False)
|
| 1261 |
+
assert Eq(ni, 1) == False
|
| 1262 |
+
assert unchanged(Eq, ni, .1)
|
| 1263 |
+
assert Eq(ni, 1.0) == False
|
| 1264 |
+
nr = symbols('nr', rational=False)
|
| 1265 |
+
assert Eq(nr, .1) == False
|
| 1266 |
+
|
| 1267 |
+
|
| 1268 |
+
def test_rewrite_Add():
|
| 1269 |
+
from sympy.testing.pytest import warns_deprecated_sympy
|
| 1270 |
+
with warns_deprecated_sympy():
|
| 1271 |
+
assert Eq(x, y).rewrite(Add) == x - y
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_rules.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.rules import Transform
|
| 2 |
+
|
| 3 |
+
from sympy.testing.pytest import raises
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def test_Transform():
|
| 7 |
+
add1 = Transform(lambda x: x + 1, lambda x: x % 2 == 1)
|
| 8 |
+
assert add1[1] == 2
|
| 9 |
+
assert (1 in add1) is True
|
| 10 |
+
assert add1.get(1) == 2
|
| 11 |
+
|
| 12 |
+
raises(KeyError, lambda: add1[2])
|
| 13 |
+
assert (2 in add1) is False
|
| 14 |
+
assert add1.get(2) is None
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_sorting.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.sorting import default_sort_key, ordered
|
| 2 |
+
from sympy.testing.pytest import raises
|
| 3 |
+
|
| 4 |
+
from sympy.abc import x
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def test_default_sort_key():
|
| 8 |
+
func = lambda x: x
|
| 9 |
+
assert sorted([func, x, func], key=default_sort_key) == [func, func, x]
|
| 10 |
+
|
| 11 |
+
class C:
|
| 12 |
+
def __repr__(self):
|
| 13 |
+
return 'x.y'
|
| 14 |
+
func = C()
|
| 15 |
+
assert sorted([x, func], key=default_sort_key) == [func, x]
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def test_ordered():
|
| 19 |
+
# Issue 7210 - this had been failing with python2/3 problems
|
| 20 |
+
assert (list(ordered([{1:3, 2:4, 9:10}, {1:3}])) == \
|
| 21 |
+
[{1: 3}, {1: 3, 2: 4, 9: 10}])
|
| 22 |
+
# warnings should not be raised for identical items
|
| 23 |
+
l = [1, 1]
|
| 24 |
+
assert list(ordered(l, warn=True)) == l
|
| 25 |
+
l = [[1], [2], [1]]
|
| 26 |
+
assert list(ordered(l, warn=True)) == [[1], [1], [2]]
|
| 27 |
+
raises(ValueError, lambda: list(ordered(['a', 'ab'], keys=[lambda x: x[0]],
|
| 28 |
+
default=False, warn=True)))
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_subs.py
ADDED
|
@@ -0,0 +1,895 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.calculus.accumulationbounds import AccumBounds
|
| 2 |
+
from sympy.core.add import Add
|
| 3 |
+
from sympy.core.basic import Basic
|
| 4 |
+
from sympy.core.containers import (Dict, Tuple)
|
| 5 |
+
from sympy.core.function import (Derivative, Function, Lambda, Subs)
|
| 6 |
+
from sympy.core.mul import Mul
|
| 7 |
+
from sympy.core.numbers import (Float, I, Integer, Rational, oo, pi, zoo)
|
| 8 |
+
from sympy.core.relational import Eq
|
| 9 |
+
from sympy.core.singleton import S
|
| 10 |
+
from sympy.core.symbol import (Symbol, Wild, symbols)
|
| 11 |
+
from sympy.core.sympify import SympifyError
|
| 12 |
+
from sympy.functions.elementary.exponential import (exp, log)
|
| 13 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 14 |
+
from sympy.functions.elementary.piecewise import Piecewise
|
| 15 |
+
from sympy.functions.elementary.trigonometric import (atan2, cos, cot, sin, tan)
|
| 16 |
+
from sympy.matrices.dense import (Matrix, zeros)
|
| 17 |
+
from sympy.matrices.expressions.special import ZeroMatrix
|
| 18 |
+
from sympy.polys.polytools import factor
|
| 19 |
+
from sympy.polys.rootoftools import RootOf
|
| 20 |
+
from sympy.simplify.cse_main import cse
|
| 21 |
+
from sympy.simplify.simplify import nsimplify
|
| 22 |
+
from sympy.core.basic import _aresame
|
| 23 |
+
from sympy.testing.pytest import XFAIL, raises
|
| 24 |
+
from sympy.abc import a, x, y, z, t
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def test_subs():
|
| 28 |
+
n3 = Rational(3)
|
| 29 |
+
e = x
|
| 30 |
+
e = e.subs(x, n3)
|
| 31 |
+
assert e == Rational(3)
|
| 32 |
+
|
| 33 |
+
e = 2*x
|
| 34 |
+
assert e == 2*x
|
| 35 |
+
e = e.subs(x, n3)
|
| 36 |
+
assert e == Rational(6)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def test_subs_Matrix():
|
| 40 |
+
z = zeros(2)
|
| 41 |
+
z1 = ZeroMatrix(2, 2)
|
| 42 |
+
assert (x*y).subs({x:z, y:0}) in [z, z1]
|
| 43 |
+
assert (x*y).subs({y:z, x:0}) == 0
|
| 44 |
+
assert (x*y).subs({y:z, x:0}, simultaneous=True) in [z, z1]
|
| 45 |
+
assert (x + y).subs({x: z, y: z}, simultaneous=True) in [z, z1]
|
| 46 |
+
assert (x + y).subs({x: z, y: z}) in [z, z1]
|
| 47 |
+
|
| 48 |
+
# Issue #15528
|
| 49 |
+
assert Mul(Matrix([[3]]), x).subs(x, 2.0) == Matrix([[6.0]])
|
| 50 |
+
# Does not raise a TypeError, see comment on the MatAdd postprocessor
|
| 51 |
+
assert Add(Matrix([[3]]), x).subs(x, 2.0) == Add(Matrix([[3]]), 2.0)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def test_subs_AccumBounds():
|
| 55 |
+
e = x
|
| 56 |
+
e = e.subs(x, AccumBounds(1, 3))
|
| 57 |
+
assert e == AccumBounds(1, 3)
|
| 58 |
+
|
| 59 |
+
e = 2*x
|
| 60 |
+
e = e.subs(x, AccumBounds(1, 3))
|
| 61 |
+
assert e == AccumBounds(2, 6)
|
| 62 |
+
|
| 63 |
+
e = x + x**2
|
| 64 |
+
e = e.subs(x, AccumBounds(-1, 1))
|
| 65 |
+
assert e == AccumBounds(-1, 2)
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def test_trigonometric():
|
| 69 |
+
n3 = Rational(3)
|
| 70 |
+
e = (sin(x)**2).diff(x)
|
| 71 |
+
assert e == 2*sin(x)*cos(x)
|
| 72 |
+
e = e.subs(x, n3)
|
| 73 |
+
assert e == 2*cos(n3)*sin(n3)
|
| 74 |
+
|
| 75 |
+
e = (sin(x)**2).diff(x)
|
| 76 |
+
assert e == 2*sin(x)*cos(x)
|
| 77 |
+
e = e.subs(sin(x), cos(x))
|
| 78 |
+
assert e == 2*cos(x)**2
|
| 79 |
+
|
| 80 |
+
assert exp(pi).subs(exp, sin) == 0
|
| 81 |
+
assert cos(exp(pi)).subs(exp, sin) == 1
|
| 82 |
+
|
| 83 |
+
i = Symbol('i', integer=True)
|
| 84 |
+
zoo = S.ComplexInfinity
|
| 85 |
+
assert tan(x).subs(x, pi/2) is zoo
|
| 86 |
+
assert cot(x).subs(x, pi) is zoo
|
| 87 |
+
assert cot(i*x).subs(x, pi) is zoo
|
| 88 |
+
assert tan(i*x).subs(x, pi/2) == tan(i*pi/2)
|
| 89 |
+
assert tan(i*x).subs(x, pi/2).subs(i, 1) is zoo
|
| 90 |
+
o = Symbol('o', odd=True)
|
| 91 |
+
assert tan(o*x).subs(x, pi/2) == tan(o*pi/2)
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
def test_powers():
|
| 95 |
+
assert sqrt(1 - sqrt(x)).subs(x, 4) == I
|
| 96 |
+
assert (sqrt(1 - x**2)**3).subs(x, 2) == - 3*I*sqrt(3)
|
| 97 |
+
assert (x**Rational(1, 3)).subs(x, 27) == 3
|
| 98 |
+
assert (x**Rational(1, 3)).subs(x, -27) == 3*(-1)**Rational(1, 3)
|
| 99 |
+
assert ((-x)**Rational(1, 3)).subs(x, 27) == 3*(-1)**Rational(1, 3)
|
| 100 |
+
n = Symbol('n', negative=True)
|
| 101 |
+
assert (x**n).subs(x, 0) is S.ComplexInfinity
|
| 102 |
+
assert exp(-1).subs(S.Exp1, 0) is S.ComplexInfinity
|
| 103 |
+
assert (x**(4.0*y)).subs(x**(2.0*y), n) == n**2.0
|
| 104 |
+
assert (2**(x + 2)).subs(2, 3) == 3**(x + 3)
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def test_logexppow(): # no eval()
|
| 108 |
+
x = Symbol('x', real=True)
|
| 109 |
+
w = Symbol('w')
|
| 110 |
+
e = (3**(1 + x) + 2**(1 + x))/(3**x + 2**x)
|
| 111 |
+
assert e.subs(2**x, w) != e
|
| 112 |
+
assert e.subs(exp(x*log(Rational(2))), w) != e
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def test_bug():
|
| 116 |
+
x1 = Symbol('x1')
|
| 117 |
+
x2 = Symbol('x2')
|
| 118 |
+
y = x1*x2
|
| 119 |
+
assert y.subs(x1, Float(3.0)) == Float(3.0)*x2
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def test_subbug1():
|
| 123 |
+
# see that they don't fail
|
| 124 |
+
(x**x).subs(x, 1)
|
| 125 |
+
(x**x).subs(x, 1.0)
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
def test_subbug2():
|
| 129 |
+
# Ensure this does not cause infinite recursion
|
| 130 |
+
assert Float(7.7).epsilon_eq(abs(x).subs(x, -7.7))
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
def test_dict_set():
|
| 134 |
+
a, b, c = map(Wild, 'abc')
|
| 135 |
+
|
| 136 |
+
f = 3*cos(4*x)
|
| 137 |
+
r = f.match(a*cos(b*x))
|
| 138 |
+
assert r == {a: 3, b: 4}
|
| 139 |
+
e = a/b*sin(b*x)
|
| 140 |
+
assert e.subs(r) == r[a]/r[b]*sin(r[b]*x)
|
| 141 |
+
assert e.subs(r) == 3*sin(4*x) / 4
|
| 142 |
+
s = set(r.items())
|
| 143 |
+
assert e.subs(s) == r[a]/r[b]*sin(r[b]*x)
|
| 144 |
+
assert e.subs(s) == 3*sin(4*x) / 4
|
| 145 |
+
|
| 146 |
+
assert e.subs(r) == r[a]/r[b]*sin(r[b]*x)
|
| 147 |
+
assert e.subs(r) == 3*sin(4*x) / 4
|
| 148 |
+
assert x.subs(Dict((x, 1))) == 1
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
def test_dict_ambigous(): # see issue 3566
|
| 152 |
+
f = x*exp(x)
|
| 153 |
+
g = z*exp(z)
|
| 154 |
+
|
| 155 |
+
df = {x: y, exp(x): y}
|
| 156 |
+
dg = {z: y, exp(z): y}
|
| 157 |
+
|
| 158 |
+
assert f.subs(df) == y**2
|
| 159 |
+
assert g.subs(dg) == y**2
|
| 160 |
+
|
| 161 |
+
# and this is how order can affect the result
|
| 162 |
+
assert f.subs(x, y).subs(exp(x), y) == y*exp(y)
|
| 163 |
+
assert f.subs(exp(x), y).subs(x, y) == y**2
|
| 164 |
+
|
| 165 |
+
# length of args and count_ops are the same so
|
| 166 |
+
# default_sort_key resolves ordering...if one
|
| 167 |
+
# doesn't want this result then an unordered
|
| 168 |
+
# sequence should not be used.
|
| 169 |
+
e = 1 + x*y
|
| 170 |
+
assert e.subs({x: y, y: 2}) == 5
|
| 171 |
+
# here, there are no obviously clashing keys or values
|
| 172 |
+
# but the results depend on the order
|
| 173 |
+
assert exp(x/2 + y).subs({exp(y + 1): 2, x: 2}) == exp(y + 1)
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
def test_deriv_sub_bug3():
|
| 177 |
+
f = Function('f')
|
| 178 |
+
pat = Derivative(f(x), x, x)
|
| 179 |
+
assert pat.subs(y, y**2) == Derivative(f(x), x, x)
|
| 180 |
+
assert pat.subs(y, y**2) != Derivative(f(x), x)
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
def test_equality_subs1():
|
| 184 |
+
f = Function('f')
|
| 185 |
+
eq = Eq(f(x)**2, x)
|
| 186 |
+
res = Eq(Integer(16), x)
|
| 187 |
+
assert eq.subs(f(x), 4) == res
|
| 188 |
+
|
| 189 |
+
|
| 190 |
+
def test_equality_subs2():
|
| 191 |
+
f = Function('f')
|
| 192 |
+
eq = Eq(f(x)**2, 16)
|
| 193 |
+
assert bool(eq.subs(f(x), 3)) is False
|
| 194 |
+
assert bool(eq.subs(f(x), 4)) is True
|
| 195 |
+
|
| 196 |
+
|
| 197 |
+
def test_issue_3742():
|
| 198 |
+
e = sqrt(x)*exp(y)
|
| 199 |
+
assert e.subs(sqrt(x), 1) == exp(y)
|
| 200 |
+
|
| 201 |
+
|
| 202 |
+
def test_subs_dict1():
|
| 203 |
+
assert (1 + x*y).subs(x, pi) == 1 + pi*y
|
| 204 |
+
assert (1 + x*y).subs({x: pi, y: 2}) == 1 + 2*pi
|
| 205 |
+
|
| 206 |
+
c2, c3, q1p, q2p, c1, s1, s2, s3 = symbols('c2 c3 q1p q2p c1 s1 s2 s3')
|
| 207 |
+
test = (c2**2*q2p*c3 + c1**2*s2**2*q2p*c3 + s1**2*s2**2*q2p*c3
|
| 208 |
+
- c1**2*q1p*c2*s3 - s1**2*q1p*c2*s3)
|
| 209 |
+
assert (test.subs({c1**2: 1 - s1**2, c2**2: 1 - s2**2, c3**3: 1 - s3**2})
|
| 210 |
+
== c3*q2p*(1 - s2**2) + c3*q2p*s2**2*(1 - s1**2)
|
| 211 |
+
- c2*q1p*s3*(1 - s1**2) + c3*q2p*s1**2*s2**2 - c2*q1p*s3*s1**2)
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def test_mul():
|
| 215 |
+
x, y, z, a, b, c = symbols('x y z a b c')
|
| 216 |
+
A, B, C = symbols('A B C', commutative=0)
|
| 217 |
+
assert (x*y*z).subs(z*x, y) == y**2
|
| 218 |
+
assert (z*x).subs(1/x, z) == 1
|
| 219 |
+
assert (x*y/z).subs(1/z, a) == a*x*y
|
| 220 |
+
assert (x*y/z).subs(x/z, a) == a*y
|
| 221 |
+
assert (x*y/z).subs(y/z, a) == a*x
|
| 222 |
+
assert (x*y/z).subs(x/z, 1/a) == y/a
|
| 223 |
+
assert (x*y/z).subs(x, 1/a) == y/(z*a)
|
| 224 |
+
assert (2*x*y).subs(5*x*y, z) != z*Rational(2, 5)
|
| 225 |
+
assert (x*y*A).subs(x*y, a) == a*A
|
| 226 |
+
assert (x**2*y**(x*Rational(3, 2))).subs(x*y**(x/2), 2) == 4*y**(x/2)
|
| 227 |
+
assert (x*exp(x*2)).subs(x*exp(x), 2) == 2*exp(x)
|
| 228 |
+
assert ((x**(2*y))**3).subs(x**y, 2) == 64
|
| 229 |
+
assert (x*A*B).subs(x*A, y) == y*B
|
| 230 |
+
assert (x*y*(1 + x)*(1 + x*y)).subs(x*y, 2) == 6*(1 + x)
|
| 231 |
+
assert ((1 + A*B)*A*B).subs(A*B, x*A*B)
|
| 232 |
+
assert (x*a/z).subs(x/z, A) == a*A
|
| 233 |
+
assert (x**3*A).subs(x**2*A, a) == a*x
|
| 234 |
+
assert (x**2*A*B).subs(x**2*B, a) == a*A
|
| 235 |
+
assert (x**2*A*B).subs(x**2*A, a) == a*B
|
| 236 |
+
assert (b*A**3/(a**3*c**3)).subs(a**4*c**3*A**3/b**4, z) == \
|
| 237 |
+
b*A**3/(a**3*c**3)
|
| 238 |
+
assert (6*x).subs(2*x, y) == 3*y
|
| 239 |
+
assert (y*exp(x*Rational(3, 2))).subs(y*exp(x), 2) == 2*exp(x/2)
|
| 240 |
+
assert (y*exp(x*Rational(3, 2))).subs(y*exp(x), 2) == 2*exp(x/2)
|
| 241 |
+
assert (A**2*B*A**2*B*A**2).subs(A*B*A, C) == A*C**2*A
|
| 242 |
+
assert (x*A**3).subs(x*A, y) == y*A**2
|
| 243 |
+
assert (x**2*A**3).subs(x*A, y) == y**2*A
|
| 244 |
+
assert (x*A**3).subs(x*A, B) == B*A**2
|
| 245 |
+
assert (x*A*B*A*exp(x*A*B)).subs(x*A, B) == B**2*A*exp(B*B)
|
| 246 |
+
assert (x**2*A*B*A*exp(x*A*B)).subs(x*A, B) == B**3*exp(B**2)
|
| 247 |
+
assert (x**3*A*exp(x*A*B)*A*exp(x*A*B)).subs(x*A, B) == \
|
| 248 |
+
x*B*exp(B**2)*B*exp(B**2)
|
| 249 |
+
assert (x*A*B*C*A*B).subs(x*A*B, C) == C**2*A*B
|
| 250 |
+
assert (-I*a*b).subs(a*b, 2) == -2*I
|
| 251 |
+
|
| 252 |
+
# issue 6361
|
| 253 |
+
assert (-8*I*a).subs(-2*a, 1) == 4*I
|
| 254 |
+
assert (-I*a).subs(-a, 1) == I
|
| 255 |
+
|
| 256 |
+
# issue 6441
|
| 257 |
+
assert (4*x**2).subs(2*x, y) == y**2
|
| 258 |
+
assert (2*4*x**2).subs(2*x, y) == 2*y**2
|
| 259 |
+
assert (-x**3/9).subs(-x/3, z) == -z**2*x
|
| 260 |
+
assert (-x**3/9).subs(x/3, z) == -z**2*x
|
| 261 |
+
assert (-2*x**3/9).subs(x/3, z) == -2*x*z**2
|
| 262 |
+
assert (-2*x**3/9).subs(-x/3, z) == -2*x*z**2
|
| 263 |
+
assert (-2*x**3/9).subs(-2*x, z) == z*x**2/9
|
| 264 |
+
assert (-2*x**3/9).subs(2*x, z) == -z*x**2/9
|
| 265 |
+
assert (2*(3*x/5/7)**2).subs(3*x/5, z) == 2*(Rational(1, 7))**2*z**2
|
| 266 |
+
assert (4*x).subs(-2*x, z) == 4*x # try keep subs literal
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
def test_subs_simple():
|
| 270 |
+
a = symbols('a', commutative=True)
|
| 271 |
+
x = symbols('x', commutative=False)
|
| 272 |
+
|
| 273 |
+
assert (2*a).subs(1, 3) == 2*a
|
| 274 |
+
assert (2*a).subs(2, 3) == 3*a
|
| 275 |
+
assert (2*a).subs(a, 3) == 6
|
| 276 |
+
assert sin(2).subs(1, 3) == sin(2)
|
| 277 |
+
assert sin(2).subs(2, 3) == sin(3)
|
| 278 |
+
assert sin(a).subs(a, 3) == sin(3)
|
| 279 |
+
|
| 280 |
+
assert (2*x).subs(1, 3) == 2*x
|
| 281 |
+
assert (2*x).subs(2, 3) == 3*x
|
| 282 |
+
assert (2*x).subs(x, 3) == 6
|
| 283 |
+
assert sin(x).subs(x, 3) == sin(3)
|
| 284 |
+
|
| 285 |
+
|
| 286 |
+
def test_subs_constants():
|
| 287 |
+
a, b = symbols('a b', commutative=True)
|
| 288 |
+
x, y = symbols('x y', commutative=False)
|
| 289 |
+
|
| 290 |
+
assert (a*b).subs(2*a, 1) == a*b
|
| 291 |
+
assert (1.5*a*b).subs(a, 1) == 1.5*b
|
| 292 |
+
assert (2*a*b).subs(2*a, 1) == b
|
| 293 |
+
assert (2*a*b).subs(4*a, 1) == 2*a*b
|
| 294 |
+
|
| 295 |
+
assert (x*y).subs(2*x, 1) == x*y
|
| 296 |
+
assert (1.5*x*y).subs(x, 1) == 1.5*y
|
| 297 |
+
assert (2*x*y).subs(2*x, 1) == y
|
| 298 |
+
assert (2*x*y).subs(4*x, 1) == 2*x*y
|
| 299 |
+
|
| 300 |
+
|
| 301 |
+
def test_subs_commutative():
|
| 302 |
+
a, b, c, d, K = symbols('a b c d K', commutative=True)
|
| 303 |
+
|
| 304 |
+
assert (a*b).subs(a*b, K) == K
|
| 305 |
+
assert (a*b*a*b).subs(a*b, K) == K**2
|
| 306 |
+
assert (a*a*b*b).subs(a*b, K) == K**2
|
| 307 |
+
assert (a*b*c*d).subs(a*b*c, K) == d*K
|
| 308 |
+
assert (a*b**c).subs(a, K) == K*b**c
|
| 309 |
+
assert (a*b**c).subs(b, K) == a*K**c
|
| 310 |
+
assert (a*b**c).subs(c, K) == a*b**K
|
| 311 |
+
assert (a*b*c*b*a).subs(a*b, K) == c*K**2
|
| 312 |
+
assert (a**3*b**2*a).subs(a*b, K) == a**2*K**2
|
| 313 |
+
|
| 314 |
+
|
| 315 |
+
def test_subs_noncommutative():
|
| 316 |
+
w, x, y, z, L = symbols('w x y z L', commutative=False)
|
| 317 |
+
alpha = symbols('alpha', commutative=True)
|
| 318 |
+
someint = symbols('someint', commutative=True, integer=True)
|
| 319 |
+
|
| 320 |
+
assert (x*y).subs(x*y, L) == L
|
| 321 |
+
assert (w*y*x).subs(x*y, L) == w*y*x
|
| 322 |
+
assert (w*x*y*z).subs(x*y, L) == w*L*z
|
| 323 |
+
assert (x*y*x*y).subs(x*y, L) == L**2
|
| 324 |
+
assert (x*x*y).subs(x*y, L) == x*L
|
| 325 |
+
assert (x*x*y*y).subs(x*y, L) == x*L*y
|
| 326 |
+
assert (w*x*y).subs(x*y*z, L) == w*x*y
|
| 327 |
+
assert (x*y**z).subs(x, L) == L*y**z
|
| 328 |
+
assert (x*y**z).subs(y, L) == x*L**z
|
| 329 |
+
assert (x*y**z).subs(z, L) == x*y**L
|
| 330 |
+
assert (w*x*y*z*x*y).subs(x*y*z, L) == w*L*x*y
|
| 331 |
+
assert (w*x*y*y*w*x*x*y*x*y*y*x*y).subs(x*y, L) == w*L*y*w*x*L**2*y*L
|
| 332 |
+
|
| 333 |
+
# Check fractional power substitutions. It should not do
|
| 334 |
+
# substitutions that choose a value for noncommutative log,
|
| 335 |
+
# or inverses that don't already appear in the expressions.
|
| 336 |
+
assert (x*x*x).subs(x*x, L) == L*x
|
| 337 |
+
assert (x*x*x*y*x*x*x*x).subs(x*x, L) == L*x*y*L**2
|
| 338 |
+
for p in range(1, 5):
|
| 339 |
+
for k in range(10):
|
| 340 |
+
assert (y * x**k).subs(x**p, L) == y * L**(k//p) * x**(k % p)
|
| 341 |
+
assert (x**Rational(3, 2)).subs(x**S.Half, L) == x**Rational(3, 2)
|
| 342 |
+
assert (x**S.Half).subs(x**S.Half, L) == L
|
| 343 |
+
assert (x**Rational(-1, 2)).subs(x**S.Half, L) == x**Rational(-1, 2)
|
| 344 |
+
assert (x**Rational(-1, 2)).subs(x**Rational(-1, 2), L) == L
|
| 345 |
+
|
| 346 |
+
assert (x**(2*someint)).subs(x**someint, L) == L**2
|
| 347 |
+
assert (x**(2*someint + 3)).subs(x**someint, L) == L**2*x**3
|
| 348 |
+
assert (x**(3*someint + 3)).subs(x**someint, L) == L**3*x**3
|
| 349 |
+
assert (x**(3*someint)).subs(x**(2*someint), L) == L * x**someint
|
| 350 |
+
assert (x**(4*someint)).subs(x**(2*someint), L) == L**2
|
| 351 |
+
assert (x**(4*someint + 1)).subs(x**(2*someint), L) == L**2 * x
|
| 352 |
+
assert (x**(4*someint)).subs(x**(3*someint), L) == L * x**someint
|
| 353 |
+
assert (x**(4*someint + 1)).subs(x**(3*someint), L) == L * x**(someint + 1)
|
| 354 |
+
|
| 355 |
+
assert (x**(2*alpha)).subs(x**alpha, L) == x**(2*alpha)
|
| 356 |
+
assert (x**(2*alpha + 2)).subs(x**2, L) == x**(2*alpha + 2)
|
| 357 |
+
assert ((2*z)**alpha).subs(z**alpha, y) == (2*z)**alpha
|
| 358 |
+
assert (x**(2*someint*alpha)).subs(x**someint, L) == x**(2*someint*alpha)
|
| 359 |
+
assert (x**(2*someint + alpha)).subs(x**someint, L) == x**(2*someint + alpha)
|
| 360 |
+
|
| 361 |
+
# This could in principle be substituted, but is not currently
|
| 362 |
+
# because it requires recognizing that someint**2 is divisible by
|
| 363 |
+
# someint.
|
| 364 |
+
assert (x**(someint**2 + 3)).subs(x**someint, L) == x**(someint**2 + 3)
|
| 365 |
+
|
| 366 |
+
# alpha**z := exp(log(alpha) z) is usually well-defined
|
| 367 |
+
assert (4**z).subs(2**z, y) == y**2
|
| 368 |
+
|
| 369 |
+
# Negative powers
|
| 370 |
+
assert (x**(-1)).subs(x**3, L) == x**(-1)
|
| 371 |
+
assert (x**(-2)).subs(x**3, L) == x**(-2)
|
| 372 |
+
assert (x**(-3)).subs(x**3, L) == L**(-1)
|
| 373 |
+
assert (x**(-4)).subs(x**3, L) == L**(-1) * x**(-1)
|
| 374 |
+
assert (x**(-5)).subs(x**3, L) == L**(-1) * x**(-2)
|
| 375 |
+
|
| 376 |
+
assert (x**(-1)).subs(x**(-3), L) == x**(-1)
|
| 377 |
+
assert (x**(-2)).subs(x**(-3), L) == x**(-2)
|
| 378 |
+
assert (x**(-3)).subs(x**(-3), L) == L
|
| 379 |
+
assert (x**(-4)).subs(x**(-3), L) == L * x**(-1)
|
| 380 |
+
assert (x**(-5)).subs(x**(-3), L) == L * x**(-2)
|
| 381 |
+
|
| 382 |
+
assert (x**1).subs(x**(-3), L) == x
|
| 383 |
+
assert (x**2).subs(x**(-3), L) == x**2
|
| 384 |
+
assert (x**3).subs(x**(-3), L) == L**(-1)
|
| 385 |
+
assert (x**4).subs(x**(-3), L) == L**(-1) * x
|
| 386 |
+
assert (x**5).subs(x**(-3), L) == L**(-1) * x**2
|
| 387 |
+
|
| 388 |
+
|
| 389 |
+
def test_subs_basic_funcs():
|
| 390 |
+
a, b, c, d, K = symbols('a b c d K', commutative=True)
|
| 391 |
+
w, x, y, z, L = symbols('w x y z L', commutative=False)
|
| 392 |
+
|
| 393 |
+
assert (x + y).subs(x + y, L) == L
|
| 394 |
+
assert (x - y).subs(x - y, L) == L
|
| 395 |
+
assert (x/y).subs(x, L) == L/y
|
| 396 |
+
assert (x**y).subs(x, L) == L**y
|
| 397 |
+
assert (x**y).subs(y, L) == x**L
|
| 398 |
+
assert ((a - c)/b).subs(b, K) == (a - c)/K
|
| 399 |
+
assert (exp(x*y - z)).subs(x*y, L) == exp(L - z)
|
| 400 |
+
assert (a*exp(x*y - w*z) + b*exp(x*y + w*z)).subs(z, 0) == \
|
| 401 |
+
a*exp(x*y) + b*exp(x*y)
|
| 402 |
+
assert ((a - b)/(c*d - a*b)).subs(c*d - a*b, K) == (a - b)/K
|
| 403 |
+
assert (w*exp(a*b - c)*x*y/4).subs(x*y, L) == w*exp(a*b - c)*L/4
|
| 404 |
+
|
| 405 |
+
|
| 406 |
+
def test_subs_wild():
|
| 407 |
+
R, S, T, U = symbols('R S T U', cls=Wild)
|
| 408 |
+
|
| 409 |
+
assert (R*S).subs(R*S, T) == T
|
| 410 |
+
assert (S*R).subs(R*S, T) == T
|
| 411 |
+
assert (R + S).subs(R + S, T) == T
|
| 412 |
+
assert (R**S).subs(R, T) == T**S
|
| 413 |
+
assert (R**S).subs(S, T) == R**T
|
| 414 |
+
assert (R*S**T).subs(R, U) == U*S**T
|
| 415 |
+
assert (R*S**T).subs(S, U) == R*U**T
|
| 416 |
+
assert (R*S**T).subs(T, U) == R*S**U
|
| 417 |
+
|
| 418 |
+
|
| 419 |
+
def test_subs_mixed():
|
| 420 |
+
a, b, c, d, K = symbols('a b c d K', commutative=True)
|
| 421 |
+
w, x, y, z, L = symbols('w x y z L', commutative=False)
|
| 422 |
+
R, S, T, U = symbols('R S T U', cls=Wild)
|
| 423 |
+
|
| 424 |
+
assert (a*x*y).subs(x*y, L) == a*L
|
| 425 |
+
assert (a*b*x*y*x).subs(x*y, L) == a*b*L*x
|
| 426 |
+
assert (R*x*y*exp(x*y)).subs(x*y, L) == R*L*exp(L)
|
| 427 |
+
assert (a*x*y*y*x - x*y*z*exp(a*b)).subs(x*y, L) == a*L*y*x - L*z*exp(a*b)
|
| 428 |
+
e = c*y*x*y*x**(R*S - a*b) - T*(a*R*b*S)
|
| 429 |
+
assert e.subs(x*y, L).subs(a*b, K).subs(R*S, U) == \
|
| 430 |
+
c*y*L*x**(U - K) - T*(U*K)
|
| 431 |
+
|
| 432 |
+
|
| 433 |
+
def test_division():
|
| 434 |
+
a, b, c = symbols('a b c', commutative=True)
|
| 435 |
+
x, y, z = symbols('x y z', commutative=True)
|
| 436 |
+
|
| 437 |
+
assert (1/a).subs(a, c) == 1/c
|
| 438 |
+
assert (1/a**2).subs(a, c) == 1/c**2
|
| 439 |
+
assert (1/a**2).subs(a, -2) == Rational(1, 4)
|
| 440 |
+
assert (-(1/a**2)).subs(a, -2) == Rational(-1, 4)
|
| 441 |
+
|
| 442 |
+
assert (1/x).subs(x, z) == 1/z
|
| 443 |
+
assert (1/x**2).subs(x, z) == 1/z**2
|
| 444 |
+
assert (1/x**2).subs(x, -2) == Rational(1, 4)
|
| 445 |
+
assert (-(1/x**2)).subs(x, -2) == Rational(-1, 4)
|
| 446 |
+
|
| 447 |
+
#issue 5360
|
| 448 |
+
assert (1/x).subs(x, 0) == 1/S.Zero
|
| 449 |
+
|
| 450 |
+
|
| 451 |
+
def test_add():
|
| 452 |
+
a, b, c, d, x, y, t = symbols('a b c d x y t')
|
| 453 |
+
|
| 454 |
+
assert (a**2 - b - c).subs(a**2 - b, d) in [d - c, a**2 - b - c]
|
| 455 |
+
assert (a**2 - c).subs(a**2 - c, d) == d
|
| 456 |
+
assert (a**2 - b - c).subs(a**2 - c, d) in [d - b, a**2 - b - c]
|
| 457 |
+
assert (a**2 - x - c).subs(a**2 - c, d) in [d - x, a**2 - x - c]
|
| 458 |
+
assert (a**2 - b - sqrt(a)).subs(a**2 - sqrt(a), c) == c - b
|
| 459 |
+
assert (a + b + exp(a + b)).subs(a + b, c) == c + exp(c)
|
| 460 |
+
assert (c + b + exp(c + b)).subs(c + b, a) == a + exp(a)
|
| 461 |
+
assert (a + b + c + d).subs(b + c, x) == a + d + x
|
| 462 |
+
assert (a + b + c + d).subs(-b - c, x) == a + d - x
|
| 463 |
+
assert ((x + 1)*y).subs(x + 1, t) == t*y
|
| 464 |
+
assert ((-x - 1)*y).subs(x + 1, t) == -t*y
|
| 465 |
+
assert ((x - 1)*y).subs(x + 1, t) == y*(t - 2)
|
| 466 |
+
assert ((-x + 1)*y).subs(x + 1, t) == y*(-t + 2)
|
| 467 |
+
|
| 468 |
+
# this should work every time:
|
| 469 |
+
e = a**2 - b - c
|
| 470 |
+
assert e.subs(Add(*e.args[:2]), d) == d + e.args[2]
|
| 471 |
+
assert e.subs(a**2 - c, d) == d - b
|
| 472 |
+
|
| 473 |
+
# the fallback should recognize when a change has
|
| 474 |
+
# been made; while .1 == Rational(1, 10) they are not the same
|
| 475 |
+
# and the change should be made
|
| 476 |
+
assert (0.1 + a).subs(0.1, Rational(1, 10)) == Rational(1, 10) + a
|
| 477 |
+
|
| 478 |
+
e = (-x*(-y + 1) - y*(y - 1))
|
| 479 |
+
ans = (-x*(x) - y*(-x)).expand()
|
| 480 |
+
assert e.subs(-y + 1, x) == ans
|
| 481 |
+
|
| 482 |
+
#Test issue 18747
|
| 483 |
+
assert (exp(x) + cos(x)).subs(x, oo) == oo
|
| 484 |
+
assert Add(*[AccumBounds(-1, 1), oo]) == oo
|
| 485 |
+
assert Add(*[oo, AccumBounds(-1, 1)]) == oo
|
| 486 |
+
|
| 487 |
+
|
| 488 |
+
def test_subs_issue_4009():
|
| 489 |
+
assert (I*Symbol('a')).subs(1, 2) == I*Symbol('a')
|
| 490 |
+
|
| 491 |
+
|
| 492 |
+
def test_functions_subs():
|
| 493 |
+
f, g = symbols('f g', cls=Function)
|
| 494 |
+
l = Lambda((x, y), sin(x) + y)
|
| 495 |
+
assert (g(y, x) + cos(x)).subs(g, l) == sin(y) + x + cos(x)
|
| 496 |
+
assert (f(x)**2).subs(f, sin) == sin(x)**2
|
| 497 |
+
assert (f(x, y)).subs(f, log) == log(x, y)
|
| 498 |
+
assert (f(x, y)).subs(f, sin) == f(x, y)
|
| 499 |
+
assert (sin(x) + atan2(x, y)).subs([[atan2, f], [sin, g]]) == \
|
| 500 |
+
f(x, y) + g(x)
|
| 501 |
+
assert (g(f(x + y, x))).subs([[f, l], [g, exp]]) == exp(x + sin(x + y))
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
def test_derivative_subs():
|
| 505 |
+
f = Function('f')
|
| 506 |
+
g = Function('g')
|
| 507 |
+
assert Derivative(f(x), x).subs(f(x), y) != 0
|
| 508 |
+
# need xreplace to put the function back, see #13803
|
| 509 |
+
assert Derivative(f(x), x).subs(f(x), y).xreplace({y: f(x)}) == \
|
| 510 |
+
Derivative(f(x), x)
|
| 511 |
+
# issues 5085, 5037
|
| 512 |
+
assert cse(Derivative(f(x), x) + f(x))[1][0].has(Derivative)
|
| 513 |
+
assert cse(Derivative(f(x, y), x) +
|
| 514 |
+
Derivative(f(x, y), y))[1][0].has(Derivative)
|
| 515 |
+
eq = Derivative(g(x), g(x))
|
| 516 |
+
assert eq.subs(g, f) == Derivative(f(x), f(x))
|
| 517 |
+
assert eq.subs(g(x), f(x)) == Derivative(f(x), f(x))
|
| 518 |
+
assert eq.subs(g, cos) == Subs(Derivative(y, y), y, cos(x))
|
| 519 |
+
|
| 520 |
+
|
| 521 |
+
def test_derivative_subs2():
|
| 522 |
+
f_func, g_func = symbols('f g', cls=Function)
|
| 523 |
+
f, g = f_func(x, y, z), g_func(x, y, z)
|
| 524 |
+
assert Derivative(f, x, y).subs(Derivative(f, x, y), g) == g
|
| 525 |
+
assert Derivative(f, y, x).subs(Derivative(f, x, y), g) == g
|
| 526 |
+
assert Derivative(f, x, y).subs(Derivative(f, x), g) == Derivative(g, y)
|
| 527 |
+
assert Derivative(f, x, y).subs(Derivative(f, y), g) == Derivative(g, x)
|
| 528 |
+
assert (Derivative(f, x, y, z).subs(
|
| 529 |
+
Derivative(f, x, z), g) == Derivative(g, y))
|
| 530 |
+
assert (Derivative(f, x, y, z).subs(
|
| 531 |
+
Derivative(f, z, y), g) == Derivative(g, x))
|
| 532 |
+
assert (Derivative(f, x, y, z).subs(
|
| 533 |
+
Derivative(f, z, y, x), g) == g)
|
| 534 |
+
|
| 535 |
+
# Issue 9135
|
| 536 |
+
assert (Derivative(f, x, x, y).subs(
|
| 537 |
+
Derivative(f, y, y), g) == Derivative(f, x, x, y))
|
| 538 |
+
assert (Derivative(f, x, y, y, z).subs(
|
| 539 |
+
Derivative(f, x, y, y, y), g) == Derivative(f, x, y, y, z))
|
| 540 |
+
|
| 541 |
+
assert Derivative(f, x, y).subs(Derivative(f_func(x), x, y), g) == Derivative(f, x, y)
|
| 542 |
+
|
| 543 |
+
|
| 544 |
+
def test_derivative_subs3():
|
| 545 |
+
dex = Derivative(exp(x), x)
|
| 546 |
+
assert Derivative(dex, x).subs(dex, exp(x)) == dex
|
| 547 |
+
assert dex.subs(exp(x), dex) == Derivative(exp(x), x, x)
|
| 548 |
+
|
| 549 |
+
|
| 550 |
+
def test_issue_5284():
|
| 551 |
+
A, B = symbols('A B', commutative=False)
|
| 552 |
+
assert (x*A).subs(x**2*A, B) == x*A
|
| 553 |
+
assert (A**2).subs(A**3, B) == A**2
|
| 554 |
+
assert (A**6).subs(A**3, B) == B**2
|
| 555 |
+
|
| 556 |
+
|
| 557 |
+
def test_subs_iter():
|
| 558 |
+
assert x.subs(reversed([[x, y]])) == y
|
| 559 |
+
it = iter([[x, y]])
|
| 560 |
+
assert x.subs(it) == y
|
| 561 |
+
assert x.subs(Tuple((x, y))) == y
|
| 562 |
+
|
| 563 |
+
|
| 564 |
+
def test_subs_dict():
|
| 565 |
+
a, b, c, d, e = symbols('a b c d e')
|
| 566 |
+
|
| 567 |
+
assert (2*x + y + z).subs({"x": 1, "y": 2}) == 4 + z
|
| 568 |
+
|
| 569 |
+
l = [(sin(x), 2), (x, 1)]
|
| 570 |
+
assert (sin(x)).subs(l) == \
|
| 571 |
+
(sin(x)).subs(dict(l)) == 2
|
| 572 |
+
assert sin(x).subs(reversed(l)) == sin(1)
|
| 573 |
+
|
| 574 |
+
expr = sin(2*x) + sqrt(sin(2*x))*cos(2*x)*sin(exp(x)*x)
|
| 575 |
+
reps = {sin(2*x): c,
|
| 576 |
+
sqrt(sin(2*x)): a,
|
| 577 |
+
cos(2*x): b,
|
| 578 |
+
exp(x): e,
|
| 579 |
+
x: d,}
|
| 580 |
+
assert expr.subs(reps) == c + a*b*sin(d*e)
|
| 581 |
+
|
| 582 |
+
l = [(x, 3), (y, x**2)]
|
| 583 |
+
assert (x + y).subs(l) == 3 + x**2
|
| 584 |
+
assert (x + y).subs(reversed(l)) == 12
|
| 585 |
+
|
| 586 |
+
# If changes are made to convert lists into dictionaries and do
|
| 587 |
+
# a dictionary-lookup replacement, these tests will help to catch
|
| 588 |
+
# some logical errors that might occur
|
| 589 |
+
l = [(y, z + 2), (1 + z, 5), (z, 2)]
|
| 590 |
+
assert (y - 1 + 3*x).subs(l) == 5 + 3*x
|
| 591 |
+
l = [(y, z + 2), (z, 3)]
|
| 592 |
+
assert (y - 2).subs(l) == 3
|
| 593 |
+
|
| 594 |
+
|
| 595 |
+
def test_no_arith_subs_on_floats():
|
| 596 |
+
assert (x + 3).subs(x + 3, a) == a
|
| 597 |
+
assert (x + 3).subs(x + 2, a) == a + 1
|
| 598 |
+
|
| 599 |
+
assert (x + y + 3).subs(x + 3, a) == a + y
|
| 600 |
+
assert (x + y + 3).subs(x + 2, a) == a + y + 1
|
| 601 |
+
|
| 602 |
+
assert (x + 3.0).subs(x + 3.0, a) == a
|
| 603 |
+
assert (x + 3.0).subs(x + 2.0, a) == x + 3.0
|
| 604 |
+
|
| 605 |
+
assert (x + y + 3.0).subs(x + 3.0, a) == a + y
|
| 606 |
+
assert (x + y + 3.0).subs(x + 2.0, a) == x + y + 3.0
|
| 607 |
+
|
| 608 |
+
|
| 609 |
+
def test_issue_5651():
|
| 610 |
+
a, b, c, K = symbols('a b c K', commutative=True)
|
| 611 |
+
assert (a/(b*c)).subs(b*c, K) == a/K
|
| 612 |
+
assert (a/(b**2*c**3)).subs(b*c, K) == a/(c*K**2)
|
| 613 |
+
assert (1/(x*y)).subs(x*y, 2) == S.Half
|
| 614 |
+
assert ((1 + x*y)/(x*y)).subs(x*y, 1) == 2
|
| 615 |
+
assert (x*y*z).subs(x*y, 2) == 2*z
|
| 616 |
+
assert ((1 + x*y)/(x*y)/z).subs(x*y, 1) == 2/z
|
| 617 |
+
|
| 618 |
+
|
| 619 |
+
def test_issue_6075():
|
| 620 |
+
assert Tuple(1, True).subs(1, 2) == Tuple(2, True)
|
| 621 |
+
|
| 622 |
+
|
| 623 |
+
def test_issue_6079():
|
| 624 |
+
# since x + 2.0 == x + 2 we can't do a simple equality test
|
| 625 |
+
assert _aresame((x + 2.0).subs(2, 3), x + 2.0)
|
| 626 |
+
assert _aresame((x + 2.0).subs(2.0, 3), x + 3)
|
| 627 |
+
assert not _aresame(x + 2, x + 2.0)
|
| 628 |
+
assert not _aresame(Basic(cos(x), S(1)), Basic(cos(x), S(1.)))
|
| 629 |
+
assert _aresame(cos, cos)
|
| 630 |
+
assert not _aresame(1, S.One)
|
| 631 |
+
assert not _aresame(x, symbols('x', positive=True))
|
| 632 |
+
|
| 633 |
+
|
| 634 |
+
def test_issue_4680():
|
| 635 |
+
N = Symbol('N')
|
| 636 |
+
assert N.subs({"N": 3}) == 3
|
| 637 |
+
|
| 638 |
+
|
| 639 |
+
def test_issue_6158():
|
| 640 |
+
assert (x - 1).subs(1, y) == x - y
|
| 641 |
+
assert (x - 1).subs(-1, y) == x + y
|
| 642 |
+
assert (x - oo).subs(oo, y) == x - y
|
| 643 |
+
assert (x - oo).subs(-oo, y) == x + y
|
| 644 |
+
|
| 645 |
+
|
| 646 |
+
def test_Function_subs():
|
| 647 |
+
f, g, h, i = symbols('f g h i', cls=Function)
|
| 648 |
+
p = Piecewise((g(f(x, y)), x < -1), (g(x), x <= 1))
|
| 649 |
+
assert p.subs(g, h) == Piecewise((h(f(x, y)), x < -1), (h(x), x <= 1))
|
| 650 |
+
assert (f(y) + g(x)).subs({f: h, g: i}) == i(x) + h(y)
|
| 651 |
+
|
| 652 |
+
|
| 653 |
+
def test_simultaneous_subs():
|
| 654 |
+
reps = {x: 0, y: 0}
|
| 655 |
+
assert (x/y).subs(reps) != (y/x).subs(reps)
|
| 656 |
+
assert (x/y).subs(reps, simultaneous=True) == \
|
| 657 |
+
(y/x).subs(reps, simultaneous=True)
|
| 658 |
+
reps = reps.items()
|
| 659 |
+
assert (x/y).subs(reps) != (y/x).subs(reps)
|
| 660 |
+
assert (x/y).subs(reps, simultaneous=True) == \
|
| 661 |
+
(y/x).subs(reps, simultaneous=True)
|
| 662 |
+
assert Derivative(x, y, z).subs(reps, simultaneous=True) == \
|
| 663 |
+
Subs(Derivative(0, y, z), y, 0)
|
| 664 |
+
|
| 665 |
+
|
| 666 |
+
def test_issue_6419_6421():
|
| 667 |
+
assert (1/(1 + x/y)).subs(x/y, x) == 1/(1 + x)
|
| 668 |
+
assert (-2*I).subs(2*I, x) == -x
|
| 669 |
+
assert (-I*x).subs(I*x, x) == -x
|
| 670 |
+
assert (-3*I*y**4).subs(3*I*y**2, x) == -x*y**2
|
| 671 |
+
|
| 672 |
+
|
| 673 |
+
def test_issue_6559():
|
| 674 |
+
assert (-12*x + y).subs(-x, 1) == 12 + y
|
| 675 |
+
# though this involves cse it generated a failure in Mul._eval_subs
|
| 676 |
+
x0, x1 = symbols('x0 x1')
|
| 677 |
+
e = -log(-12*sqrt(2) + 17)/24 - log(-2*sqrt(2) + 3)/12 + sqrt(2)/3
|
| 678 |
+
# XXX modify cse so x1 is eliminated and x0 = -sqrt(2)?
|
| 679 |
+
assert cse(e) == (
|
| 680 |
+
[(x0, sqrt(2))], [x0/3 - log(-12*x0 + 17)/24 - log(-2*x0 + 3)/12])
|
| 681 |
+
|
| 682 |
+
|
| 683 |
+
def test_issue_5261():
|
| 684 |
+
x = symbols('x', real=True)
|
| 685 |
+
e = I*x
|
| 686 |
+
assert exp(e).subs(exp(x), y) == y**I
|
| 687 |
+
assert (2**e).subs(2**x, y) == y**I
|
| 688 |
+
eq = (-2)**e
|
| 689 |
+
assert eq.subs((-2)**x, y) == eq
|
| 690 |
+
|
| 691 |
+
|
| 692 |
+
def test_issue_6923():
|
| 693 |
+
assert (-2*x*sqrt(2)).subs(2*x, y) == -sqrt(2)*y
|
| 694 |
+
|
| 695 |
+
|
| 696 |
+
def test_2arg_hack():
|
| 697 |
+
N = Symbol('N', commutative=False)
|
| 698 |
+
ans = Mul(2, y + 1, evaluate=False)
|
| 699 |
+
assert (2*x*(y + 1)).subs(x, 1, hack2=True) == ans
|
| 700 |
+
assert (2*(y + 1 + N)).subs(N, 0, hack2=True) == ans
|
| 701 |
+
|
| 702 |
+
|
| 703 |
+
@XFAIL
|
| 704 |
+
def test_mul2():
|
| 705 |
+
"""When this fails, remove things labelled "2-arg hack"
|
| 706 |
+
1) remove special handling in the fallback of subs that
|
| 707 |
+
was added in the same commit as this test
|
| 708 |
+
2) remove the special handling in Mul.flatten
|
| 709 |
+
"""
|
| 710 |
+
assert (2*(x + 1)).is_Mul
|
| 711 |
+
|
| 712 |
+
|
| 713 |
+
def test_noncommutative_subs():
|
| 714 |
+
x,y = symbols('x,y', commutative=False)
|
| 715 |
+
assert (x*y*x).subs([(x, x*y), (y, x)], simultaneous=True) == (x*y*x**2*y)
|
| 716 |
+
|
| 717 |
+
|
| 718 |
+
def test_issue_2877():
|
| 719 |
+
f = Float(2.0)
|
| 720 |
+
assert (x + f).subs({f: 2}) == x + 2
|
| 721 |
+
|
| 722 |
+
def r(a, b, c):
|
| 723 |
+
return factor(a*x**2 + b*x + c)
|
| 724 |
+
e = r(5.0/6, 10, 5)
|
| 725 |
+
assert nsimplify(e) == 5*x**2/6 + 10*x + 5
|
| 726 |
+
|
| 727 |
+
|
| 728 |
+
def test_issue_5910():
|
| 729 |
+
t = Symbol('t')
|
| 730 |
+
assert (1/(1 - t)).subs(t, 1) is zoo
|
| 731 |
+
n = t
|
| 732 |
+
d = t - 1
|
| 733 |
+
assert (n/d).subs(t, 1) is zoo
|
| 734 |
+
assert (-n/-d).subs(t, 1) is zoo
|
| 735 |
+
|
| 736 |
+
|
| 737 |
+
def test_issue_5217():
|
| 738 |
+
s = Symbol('s')
|
| 739 |
+
z = (1 - 2*x*x)
|
| 740 |
+
w = (1 + 2*x*x)
|
| 741 |
+
q = 2*x*x*2*y*y
|
| 742 |
+
sub = {2*x*x: s}
|
| 743 |
+
assert w.subs(sub) == 1 + s
|
| 744 |
+
assert z.subs(sub) == 1 - s
|
| 745 |
+
assert q == 4*x**2*y**2
|
| 746 |
+
assert q.subs(sub) == 2*y**2*s
|
| 747 |
+
|
| 748 |
+
|
| 749 |
+
def test_issue_10829():
|
| 750 |
+
assert (4**x).subs(2**x, y) == y**2
|
| 751 |
+
assert (9**x).subs(3**x, y) == y**2
|
| 752 |
+
|
| 753 |
+
|
| 754 |
+
def test_pow_eval_subs_no_cache():
|
| 755 |
+
# Tests pull request 9376 is working
|
| 756 |
+
from sympy.core.cache import clear_cache
|
| 757 |
+
|
| 758 |
+
s = 1/sqrt(x**2)
|
| 759 |
+
# This bug only appeared when the cache was turned off.
|
| 760 |
+
# We need to approximate running this test without the cache.
|
| 761 |
+
# This creates approximately the same situation.
|
| 762 |
+
clear_cache()
|
| 763 |
+
|
| 764 |
+
# This used to fail with a wrong result.
|
| 765 |
+
# It incorrectly returned 1/sqrt(x**2) before this pull request.
|
| 766 |
+
result = s.subs(sqrt(x**2), y)
|
| 767 |
+
assert result == 1/y
|
| 768 |
+
|
| 769 |
+
|
| 770 |
+
def test_RootOf_issue_10092():
|
| 771 |
+
x = Symbol('x', real=True)
|
| 772 |
+
eq = x**3 - 17*x**2 + 81*x - 118
|
| 773 |
+
r = RootOf(eq, 0)
|
| 774 |
+
assert (x < r).subs(x, r) is S.false
|
| 775 |
+
|
| 776 |
+
|
| 777 |
+
def test_issue_8886():
|
| 778 |
+
from sympy.physics.mechanics import ReferenceFrame as R
|
| 779 |
+
# if something can't be sympified we assume that it
|
| 780 |
+
# doesn't play well with SymPy and disallow the
|
| 781 |
+
# substitution
|
| 782 |
+
v = R('A').x
|
| 783 |
+
raises(SympifyError, lambda: x.subs(x, v))
|
| 784 |
+
raises(SympifyError, lambda: v.subs(v, x))
|
| 785 |
+
assert v.__eq__(x) is False
|
| 786 |
+
|
| 787 |
+
|
| 788 |
+
def test_issue_12657():
|
| 789 |
+
# treat -oo like the atom that it is
|
| 790 |
+
reps = [(-oo, 1), (oo, 2)]
|
| 791 |
+
assert (x < -oo).subs(reps) == (x < 1)
|
| 792 |
+
assert (x < -oo).subs(list(reversed(reps))) == (x < 1)
|
| 793 |
+
reps = [(-oo, 2), (oo, 1)]
|
| 794 |
+
assert (x < oo).subs(reps) == (x < 1)
|
| 795 |
+
assert (x < oo).subs(list(reversed(reps))) == (x < 1)
|
| 796 |
+
|
| 797 |
+
|
| 798 |
+
def test_recurse_Application_args():
|
| 799 |
+
F = Lambda((x, y), exp(2*x + 3*y))
|
| 800 |
+
f = Function('f')
|
| 801 |
+
A = f(x, f(x, x))
|
| 802 |
+
C = F(x, F(x, x))
|
| 803 |
+
assert A.subs(f, F) == A.replace(f, F) == C
|
| 804 |
+
|
| 805 |
+
|
| 806 |
+
def test_Subs_subs():
|
| 807 |
+
assert Subs(x*y, x, x).subs(x, y) == Subs(x*y, x, y)
|
| 808 |
+
assert Subs(x*y, x, x + 1).subs(x, y) == \
|
| 809 |
+
Subs(x*y, x, y + 1)
|
| 810 |
+
assert Subs(x*y, y, x + 1).subs(x, y) == \
|
| 811 |
+
Subs(y**2, y, y + 1)
|
| 812 |
+
a = Subs(x*y*z, (y, x, z), (x + 1, x + z, x))
|
| 813 |
+
b = Subs(x*y*z, (y, x, z), (x + 1, y + z, y))
|
| 814 |
+
assert a.subs(x, y) == b and \
|
| 815 |
+
a.doit().subs(x, y) == a.subs(x, y).doit()
|
| 816 |
+
f = Function('f')
|
| 817 |
+
g = Function('g')
|
| 818 |
+
assert Subs(2*f(x, y) + g(x), f(x, y), 1).subs(y, 2) == Subs(
|
| 819 |
+
2*f(x, y) + g(x), (f(x, y), y), (1, 2))
|
| 820 |
+
|
| 821 |
+
|
| 822 |
+
def test_issue_13333():
|
| 823 |
+
eq = 1/x
|
| 824 |
+
assert eq.subs({"x": '1/2'}) == 2
|
| 825 |
+
assert eq.subs({"x": '(1/2)'}) == 2
|
| 826 |
+
|
| 827 |
+
|
| 828 |
+
def test_issue_15234():
|
| 829 |
+
x, y = symbols('x y', real=True)
|
| 830 |
+
p = 6*x**5 + x**4 - 4*x**3 + 4*x**2 - 2*x + 3
|
| 831 |
+
p_subbed = 6*x**5 - 4*x**3 - 2*x + y**4 + 4*y**2 + 3
|
| 832 |
+
assert p.subs([(x**i, y**i) for i in [2, 4]]) == p_subbed
|
| 833 |
+
x, y = symbols('x y', complex=True)
|
| 834 |
+
p = 6*x**5 + x**4 - 4*x**3 + 4*x**2 - 2*x + 3
|
| 835 |
+
p_subbed = 6*x**5 - 4*x**3 - 2*x + y**4 + 4*y**2 + 3
|
| 836 |
+
assert p.subs([(x**i, y**i) for i in [2, 4]]) == p_subbed
|
| 837 |
+
|
| 838 |
+
|
| 839 |
+
def test_issue_6976():
|
| 840 |
+
x, y = symbols('x y')
|
| 841 |
+
assert (sqrt(x)**3 + sqrt(x) + x + x**2).subs(sqrt(x), y) == \
|
| 842 |
+
y**4 + y**3 + y**2 + y
|
| 843 |
+
assert (x**4 + x**3 + x**2 + x + sqrt(x)).subs(x**2, y) == \
|
| 844 |
+
sqrt(x) + x**3 + x + y**2 + y
|
| 845 |
+
assert x.subs(x**3, y) == x
|
| 846 |
+
assert x.subs(x**Rational(1, 3), y) == y**3
|
| 847 |
+
|
| 848 |
+
# More substitutions are possible with nonnegative symbols
|
| 849 |
+
x, y = symbols('x y', nonnegative=True)
|
| 850 |
+
assert (x**4 + x**3 + x**2 + x + sqrt(x)).subs(x**2, y) == \
|
| 851 |
+
y**Rational(1, 4) + y**Rational(3, 2) + sqrt(y) + y**2 + y
|
| 852 |
+
assert x.subs(x**3, y) == y**Rational(1, 3)
|
| 853 |
+
|
| 854 |
+
|
| 855 |
+
def test_issue_11746():
|
| 856 |
+
assert (1/x).subs(x**2, 1) == 1/x
|
| 857 |
+
assert (1/(x**3)).subs(x**2, 1) == x**(-3)
|
| 858 |
+
assert (1/(x**4)).subs(x**2, 1) == 1
|
| 859 |
+
assert (1/(x**3)).subs(x**4, 1) == x**(-3)
|
| 860 |
+
assert (1/(y**5)).subs(x**5, 1) == y**(-5)
|
| 861 |
+
|
| 862 |
+
|
| 863 |
+
def test_issue_17823():
|
| 864 |
+
from sympy.physics.mechanics import dynamicsymbols
|
| 865 |
+
q1, q2 = dynamicsymbols('q1, q2')
|
| 866 |
+
expr = q1.diff().diff()**2*q1 + q1.diff()*q2.diff()
|
| 867 |
+
reps={q1: a, q1.diff(): a*x*y, q1.diff().diff(): z}
|
| 868 |
+
assert expr.subs(reps) == a*x*y*Derivative(q2, t) + a*z**2
|
| 869 |
+
|
| 870 |
+
|
| 871 |
+
def test_issue_19326():
|
| 872 |
+
x, y = [i(t) for i in map(Function, 'xy')]
|
| 873 |
+
assert (x*y).subs({x: 1 + x, y: x}) == (1 + x)*x
|
| 874 |
+
|
| 875 |
+
|
| 876 |
+
def test_issue_19558():
|
| 877 |
+
e = (7*x*cos(x) - 12*log(x)**3)*(-log(x)**4 + 2*sin(x) + 1)**2/ \
|
| 878 |
+
(2*(x*cos(x) - 2*log(x)**3)*(3*log(x)**4 - 7*sin(x) + 3)**2)
|
| 879 |
+
|
| 880 |
+
assert e.subs(x, oo) == AccumBounds(-oo, oo)
|
| 881 |
+
assert (sin(x) + cos(x)).subs(x, oo) == AccumBounds(-2, 2)
|
| 882 |
+
|
| 883 |
+
|
| 884 |
+
def test_issue_22033():
|
| 885 |
+
xr = Symbol('xr', real=True)
|
| 886 |
+
e = (1/xr)
|
| 887 |
+
assert e.subs(xr**2, y) == e
|
| 888 |
+
|
| 889 |
+
|
| 890 |
+
def test_guard_against_indeterminate_evaluation():
|
| 891 |
+
eq = x**y
|
| 892 |
+
assert eq.subs([(x, 1), (y, oo)]) == 1 # because 1**y == 1
|
| 893 |
+
assert eq.subs([(y, oo), (x, 1)]) is S.NaN
|
| 894 |
+
assert eq.subs({x: 1, y: oo}) is S.NaN
|
| 895 |
+
assert eq.subs([(x, 1), (y, oo)], simultaneous=True) is S.NaN
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_symbol.py
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import threading
|
| 2 |
+
|
| 3 |
+
from sympy.core.function import Function, UndefinedFunction
|
| 4 |
+
from sympy.core.numbers import (I, Rational, pi)
|
| 5 |
+
from sympy.core.relational import (GreaterThan, LessThan, StrictGreaterThan, StrictLessThan)
|
| 6 |
+
from sympy.core.symbol import (Dummy, Symbol, Wild, symbols)
|
| 7 |
+
from sympy.core.sympify import sympify # can't import as S yet
|
| 8 |
+
from sympy.core.symbol import uniquely_named_symbol, _symbol, Str
|
| 9 |
+
|
| 10 |
+
from sympy.testing.pytest import raises, skip_under_pyodide
|
| 11 |
+
from sympy.core.symbol import disambiguate
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def test_Str():
|
| 15 |
+
a1 = Str('a')
|
| 16 |
+
a2 = Str('a')
|
| 17 |
+
b = Str('b')
|
| 18 |
+
assert a1 == a2 != b
|
| 19 |
+
raises(TypeError, lambda: Str())
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def test_Symbol():
|
| 23 |
+
a = Symbol("a")
|
| 24 |
+
x1 = Symbol("x")
|
| 25 |
+
x2 = Symbol("x")
|
| 26 |
+
xdummy1 = Dummy("x")
|
| 27 |
+
xdummy2 = Dummy("x")
|
| 28 |
+
|
| 29 |
+
assert a != x1
|
| 30 |
+
assert a != x2
|
| 31 |
+
assert x1 == x2
|
| 32 |
+
assert x1 != xdummy1
|
| 33 |
+
assert xdummy1 != xdummy2
|
| 34 |
+
|
| 35 |
+
assert Symbol("x") == Symbol("x")
|
| 36 |
+
assert Dummy("x") != Dummy("x")
|
| 37 |
+
d = symbols('d', cls=Dummy)
|
| 38 |
+
assert isinstance(d, Dummy)
|
| 39 |
+
c, d = symbols('c,d', cls=Dummy)
|
| 40 |
+
assert isinstance(c, Dummy)
|
| 41 |
+
assert isinstance(d, Dummy)
|
| 42 |
+
raises(TypeError, lambda: Symbol())
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def test_Dummy():
|
| 46 |
+
assert Dummy() != Dummy()
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def test_Dummy_force_dummy_index():
|
| 50 |
+
raises(AssertionError, lambda: Dummy(dummy_index=1))
|
| 51 |
+
assert Dummy('d', dummy_index=2) == Dummy('d', dummy_index=2)
|
| 52 |
+
assert Dummy('d1', dummy_index=2) != Dummy('d2', dummy_index=2)
|
| 53 |
+
d1 = Dummy('d', dummy_index=3)
|
| 54 |
+
d2 = Dummy('d')
|
| 55 |
+
# might fail if d1 were created with dummy_index >= 10**6
|
| 56 |
+
assert d1 != d2
|
| 57 |
+
d3 = Dummy('d', dummy_index=3)
|
| 58 |
+
assert d1 == d3
|
| 59 |
+
assert Dummy()._count == Dummy('d', dummy_index=3)._count
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def test_lt_gt():
|
| 63 |
+
S = sympify
|
| 64 |
+
x, y = Symbol('x'), Symbol('y')
|
| 65 |
+
|
| 66 |
+
assert (x >= y) == GreaterThan(x, y)
|
| 67 |
+
assert (x >= 0) == GreaterThan(x, 0)
|
| 68 |
+
assert (x <= y) == LessThan(x, y)
|
| 69 |
+
assert (x <= 0) == LessThan(x, 0)
|
| 70 |
+
|
| 71 |
+
assert (0 <= x) == GreaterThan(x, 0)
|
| 72 |
+
assert (0 >= x) == LessThan(x, 0)
|
| 73 |
+
assert (S(0) >= x) == GreaterThan(0, x)
|
| 74 |
+
assert (S(0) <= x) == LessThan(0, x)
|
| 75 |
+
|
| 76 |
+
assert (x > y) == StrictGreaterThan(x, y)
|
| 77 |
+
assert (x > 0) == StrictGreaterThan(x, 0)
|
| 78 |
+
assert (x < y) == StrictLessThan(x, y)
|
| 79 |
+
assert (x < 0) == StrictLessThan(x, 0)
|
| 80 |
+
|
| 81 |
+
assert (0 < x) == StrictGreaterThan(x, 0)
|
| 82 |
+
assert (0 > x) == StrictLessThan(x, 0)
|
| 83 |
+
assert (S(0) > x) == StrictGreaterThan(0, x)
|
| 84 |
+
assert (S(0) < x) == StrictLessThan(0, x)
|
| 85 |
+
|
| 86 |
+
e = x**2 + 4*x + 1
|
| 87 |
+
assert (e >= 0) == GreaterThan(e, 0)
|
| 88 |
+
assert (0 <= e) == GreaterThan(e, 0)
|
| 89 |
+
assert (e > 0) == StrictGreaterThan(e, 0)
|
| 90 |
+
assert (0 < e) == StrictGreaterThan(e, 0)
|
| 91 |
+
|
| 92 |
+
assert (e <= 0) == LessThan(e, 0)
|
| 93 |
+
assert (0 >= e) == LessThan(e, 0)
|
| 94 |
+
assert (e < 0) == StrictLessThan(e, 0)
|
| 95 |
+
assert (0 > e) == StrictLessThan(e, 0)
|
| 96 |
+
|
| 97 |
+
assert (S(0) >= e) == GreaterThan(0, e)
|
| 98 |
+
assert (S(0) <= e) == LessThan(0, e)
|
| 99 |
+
assert (S(0) < e) == StrictLessThan(0, e)
|
| 100 |
+
assert (S(0) > e) == StrictGreaterThan(0, e)
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def test_no_len():
|
| 104 |
+
# there should be no len for numbers
|
| 105 |
+
x = Symbol('x')
|
| 106 |
+
raises(TypeError, lambda: len(x))
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def test_ineq_unequal():
|
| 110 |
+
S = sympify
|
| 111 |
+
x, y, z = symbols('x,y,z')
|
| 112 |
+
|
| 113 |
+
e = (
|
| 114 |
+
S(-1) >= x, S(-1) >= y, S(-1) >= z,
|
| 115 |
+
S(-1) > x, S(-1) > y, S(-1) > z,
|
| 116 |
+
S(-1) <= x, S(-1) <= y, S(-1) <= z,
|
| 117 |
+
S(-1) < x, S(-1) < y, S(-1) < z,
|
| 118 |
+
S(0) >= x, S(0) >= y, S(0) >= z,
|
| 119 |
+
S(0) > x, S(0) > y, S(0) > z,
|
| 120 |
+
S(0) <= x, S(0) <= y, S(0) <= z,
|
| 121 |
+
S(0) < x, S(0) < y, S(0) < z,
|
| 122 |
+
S('3/7') >= x, S('3/7') >= y, S('3/7') >= z,
|
| 123 |
+
S('3/7') > x, S('3/7') > y, S('3/7') > z,
|
| 124 |
+
S('3/7') <= x, S('3/7') <= y, S('3/7') <= z,
|
| 125 |
+
S('3/7') < x, S('3/7') < y, S('3/7') < z,
|
| 126 |
+
S(1.5) >= x, S(1.5) >= y, S(1.5) >= z,
|
| 127 |
+
S(1.5) > x, S(1.5) > y, S(1.5) > z,
|
| 128 |
+
S(1.5) <= x, S(1.5) <= y, S(1.5) <= z,
|
| 129 |
+
S(1.5) < x, S(1.5) < y, S(1.5) < z,
|
| 130 |
+
S(2) >= x, S(2) >= y, S(2) >= z,
|
| 131 |
+
S(2) > x, S(2) > y, S(2) > z,
|
| 132 |
+
S(2) <= x, S(2) <= y, S(2) <= z,
|
| 133 |
+
S(2) < x, S(2) < y, S(2) < z,
|
| 134 |
+
x >= -1, y >= -1, z >= -1,
|
| 135 |
+
x > -1, y > -1, z > -1,
|
| 136 |
+
x <= -1, y <= -1, z <= -1,
|
| 137 |
+
x < -1, y < -1, z < -1,
|
| 138 |
+
x >= 0, y >= 0, z >= 0,
|
| 139 |
+
x > 0, y > 0, z > 0,
|
| 140 |
+
x <= 0, y <= 0, z <= 0,
|
| 141 |
+
x < 0, y < 0, z < 0,
|
| 142 |
+
x >= 1.5, y >= 1.5, z >= 1.5,
|
| 143 |
+
x > 1.5, y > 1.5, z > 1.5,
|
| 144 |
+
x <= 1.5, y <= 1.5, z <= 1.5,
|
| 145 |
+
x < 1.5, y < 1.5, z < 1.5,
|
| 146 |
+
x >= 2, y >= 2, z >= 2,
|
| 147 |
+
x > 2, y > 2, z > 2,
|
| 148 |
+
x <= 2, y <= 2, z <= 2,
|
| 149 |
+
x < 2, y < 2, z < 2,
|
| 150 |
+
|
| 151 |
+
x >= y, x >= z, y >= x, y >= z, z >= x, z >= y,
|
| 152 |
+
x > y, x > z, y > x, y > z, z > x, z > y,
|
| 153 |
+
x <= y, x <= z, y <= x, y <= z, z <= x, z <= y,
|
| 154 |
+
x < y, x < z, y < x, y < z, z < x, z < y,
|
| 155 |
+
|
| 156 |
+
x - pi >= y + z, y - pi >= x + z, z - pi >= x + y,
|
| 157 |
+
x - pi > y + z, y - pi > x + z, z - pi > x + y,
|
| 158 |
+
x - pi <= y + z, y - pi <= x + z, z - pi <= x + y,
|
| 159 |
+
x - pi < y + z, y - pi < x + z, z - pi < x + y,
|
| 160 |
+
True, False
|
| 161 |
+
)
|
| 162 |
+
|
| 163 |
+
left_e = e[:-1]
|
| 164 |
+
for i, e1 in enumerate( left_e ):
|
| 165 |
+
for e2 in e[i + 1:]:
|
| 166 |
+
assert e1 != e2
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
def test_Wild_properties():
|
| 170 |
+
S = sympify
|
| 171 |
+
# these tests only include Atoms
|
| 172 |
+
x = Symbol("x")
|
| 173 |
+
y = Symbol("y")
|
| 174 |
+
p = Symbol("p", positive=True)
|
| 175 |
+
k = Symbol("k", integer=True)
|
| 176 |
+
n = Symbol("n", integer=True, positive=True)
|
| 177 |
+
|
| 178 |
+
given_patterns = [ x, y, p, k, -k, n, -n, S(-3), S(3),
|
| 179 |
+
pi, Rational(3, 2), I ]
|
| 180 |
+
|
| 181 |
+
integerp = lambda k: k.is_integer
|
| 182 |
+
positivep = lambda k: k.is_positive
|
| 183 |
+
symbolp = lambda k: k.is_Symbol
|
| 184 |
+
realp = lambda k: k.is_extended_real
|
| 185 |
+
|
| 186 |
+
S = Wild("S", properties=[symbolp])
|
| 187 |
+
R = Wild("R", properties=[realp])
|
| 188 |
+
Y = Wild("Y", exclude=[x, p, k, n])
|
| 189 |
+
P = Wild("P", properties=[positivep])
|
| 190 |
+
K = Wild("K", properties=[integerp])
|
| 191 |
+
N = Wild("N", properties=[positivep, integerp])
|
| 192 |
+
|
| 193 |
+
given_wildcards = [ S, R, Y, P, K, N ]
|
| 194 |
+
|
| 195 |
+
goodmatch = {
|
| 196 |
+
S: (x, y, p, k, n),
|
| 197 |
+
R: (p, k, -k, n, -n, -3, 3, pi, Rational(3, 2)),
|
| 198 |
+
Y: (y, -3, 3, pi, Rational(3, 2), I ),
|
| 199 |
+
P: (p, n, 3, pi, Rational(3, 2)),
|
| 200 |
+
K: (k, -k, n, -n, -3, 3),
|
| 201 |
+
N: (n, 3)}
|
| 202 |
+
|
| 203 |
+
for A in given_wildcards:
|
| 204 |
+
for pat in given_patterns:
|
| 205 |
+
d = pat.match(A)
|
| 206 |
+
if pat in goodmatch[A]:
|
| 207 |
+
assert d[A] in goodmatch[A]
|
| 208 |
+
else:
|
| 209 |
+
assert d is None
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
def test_symbols():
|
| 213 |
+
x = Symbol('x')
|
| 214 |
+
y = Symbol('y')
|
| 215 |
+
z = Symbol('z')
|
| 216 |
+
|
| 217 |
+
assert symbols('x') == x
|
| 218 |
+
assert symbols('x ') == x
|
| 219 |
+
assert symbols(' x ') == x
|
| 220 |
+
assert symbols('x,') == (x,)
|
| 221 |
+
assert symbols('x, ') == (x,)
|
| 222 |
+
assert symbols('x ,') == (x,)
|
| 223 |
+
|
| 224 |
+
assert symbols('x , y') == (x, y)
|
| 225 |
+
|
| 226 |
+
assert symbols('x,y,z') == (x, y, z)
|
| 227 |
+
assert symbols('x y z') == (x, y, z)
|
| 228 |
+
|
| 229 |
+
assert symbols('x,y,z,') == (x, y, z)
|
| 230 |
+
assert symbols('x y z ') == (x, y, z)
|
| 231 |
+
|
| 232 |
+
xyz = Symbol('xyz')
|
| 233 |
+
abc = Symbol('abc')
|
| 234 |
+
|
| 235 |
+
assert symbols('xyz') == xyz
|
| 236 |
+
assert symbols('xyz,') == (xyz,)
|
| 237 |
+
assert symbols('xyz,abc') == (xyz, abc)
|
| 238 |
+
|
| 239 |
+
assert symbols(('xyz',)) == (xyz,)
|
| 240 |
+
assert symbols(('xyz,',)) == ((xyz,),)
|
| 241 |
+
assert symbols(('x,y,z,',)) == ((x, y, z),)
|
| 242 |
+
assert symbols(('xyz', 'abc')) == (xyz, abc)
|
| 243 |
+
assert symbols(('xyz,abc',)) == ((xyz, abc),)
|
| 244 |
+
assert symbols(('xyz,abc', 'x,y,z')) == ((xyz, abc), (x, y, z))
|
| 245 |
+
|
| 246 |
+
assert symbols(('x', 'y', 'z')) == (x, y, z)
|
| 247 |
+
assert symbols(['x', 'y', 'z']) == [x, y, z]
|
| 248 |
+
assert symbols({'x', 'y', 'z'}) == {x, y, z}
|
| 249 |
+
|
| 250 |
+
raises(ValueError, lambda: symbols(''))
|
| 251 |
+
raises(ValueError, lambda: symbols(','))
|
| 252 |
+
raises(ValueError, lambda: symbols('x,,y,,z'))
|
| 253 |
+
raises(ValueError, lambda: symbols(('x', '', 'y', '', 'z')))
|
| 254 |
+
|
| 255 |
+
a, b = symbols('x,y', real=True)
|
| 256 |
+
assert a.is_real and b.is_real
|
| 257 |
+
|
| 258 |
+
x0 = Symbol('x0')
|
| 259 |
+
x1 = Symbol('x1')
|
| 260 |
+
x2 = Symbol('x2')
|
| 261 |
+
|
| 262 |
+
y0 = Symbol('y0')
|
| 263 |
+
y1 = Symbol('y1')
|
| 264 |
+
|
| 265 |
+
assert symbols('x0:0') == ()
|
| 266 |
+
assert symbols('x0:1') == (x0,)
|
| 267 |
+
assert symbols('x0:2') == (x0, x1)
|
| 268 |
+
assert symbols('x0:3') == (x0, x1, x2)
|
| 269 |
+
|
| 270 |
+
assert symbols('x:0') == ()
|
| 271 |
+
assert symbols('x:1') == (x0,)
|
| 272 |
+
assert symbols('x:2') == (x0, x1)
|
| 273 |
+
assert symbols('x:3') == (x0, x1, x2)
|
| 274 |
+
|
| 275 |
+
assert symbols('x1:1') == ()
|
| 276 |
+
assert symbols('x1:2') == (x1,)
|
| 277 |
+
assert symbols('x1:3') == (x1, x2)
|
| 278 |
+
|
| 279 |
+
assert symbols('x1:3,x,y,z') == (x1, x2, x, y, z)
|
| 280 |
+
|
| 281 |
+
assert symbols('x:3,y:2') == (x0, x1, x2, y0, y1)
|
| 282 |
+
assert symbols(('x:3', 'y:2')) == ((x0, x1, x2), (y0, y1))
|
| 283 |
+
|
| 284 |
+
a = Symbol('a')
|
| 285 |
+
b = Symbol('b')
|
| 286 |
+
c = Symbol('c')
|
| 287 |
+
d = Symbol('d')
|
| 288 |
+
|
| 289 |
+
assert symbols('x:z') == (x, y, z)
|
| 290 |
+
assert symbols('a:d,x:z') == (a, b, c, d, x, y, z)
|
| 291 |
+
assert symbols(('a:d', 'x:z')) == ((a, b, c, d), (x, y, z))
|
| 292 |
+
|
| 293 |
+
aa = Symbol('aa')
|
| 294 |
+
ab = Symbol('ab')
|
| 295 |
+
ac = Symbol('ac')
|
| 296 |
+
ad = Symbol('ad')
|
| 297 |
+
|
| 298 |
+
assert symbols('aa:d') == (aa, ab, ac, ad)
|
| 299 |
+
assert symbols('aa:d,x:z') == (aa, ab, ac, ad, x, y, z)
|
| 300 |
+
assert symbols(('aa:d','x:z')) == ((aa, ab, ac, ad), (x, y, z))
|
| 301 |
+
|
| 302 |
+
assert type(symbols(('q:2', 'u:2'), cls=Function)[0][0]) == UndefinedFunction # issue 23532
|
| 303 |
+
|
| 304 |
+
# issue 6675
|
| 305 |
+
def sym(s):
|
| 306 |
+
return str(symbols(s))
|
| 307 |
+
assert sym('a0:4') == '(a0, a1, a2, a3)'
|
| 308 |
+
assert sym('a2:4,b1:3') == '(a2, a3, b1, b2)'
|
| 309 |
+
assert sym('a1(2:4)') == '(a12, a13)'
|
| 310 |
+
assert sym('a0:2.0:2') == '(a0.0, a0.1, a1.0, a1.1)'
|
| 311 |
+
assert sym('aa:cz') == '(aaz, abz, acz)'
|
| 312 |
+
assert sym('aa:c0:2') == '(aa0, aa1, ab0, ab1, ac0, ac1)'
|
| 313 |
+
assert sym('aa:ba:b') == '(aaa, aab, aba, abb)'
|
| 314 |
+
assert sym('a:3b') == '(a0b, a1b, a2b)'
|
| 315 |
+
assert sym('a-1:3b') == '(a-1b, a-2b)'
|
| 316 |
+
assert sym(r'a:2\,:2' + chr(0)) == '(a0,0%s, a0,1%s, a1,0%s, a1,1%s)' % (
|
| 317 |
+
(chr(0),)*4)
|
| 318 |
+
assert sym('x(:a:3)') == '(x(a0), x(a1), x(a2))'
|
| 319 |
+
assert sym('x(:c):1') == '(xa0, xb0, xc0)'
|
| 320 |
+
assert sym('x((:a)):3') == '(x(a)0, x(a)1, x(a)2)'
|
| 321 |
+
assert sym('x(:a:3') == '(x(a0, x(a1, x(a2)'
|
| 322 |
+
assert sym(':2') == '(0, 1)'
|
| 323 |
+
assert sym(':b') == '(a, b)'
|
| 324 |
+
assert sym(':b:2') == '(a0, a1, b0, b1)'
|
| 325 |
+
assert sym(':2:2') == '(00, 01, 10, 11)'
|
| 326 |
+
assert sym(':b:b') == '(aa, ab, ba, bb)'
|
| 327 |
+
|
| 328 |
+
raises(ValueError, lambda: symbols(':'))
|
| 329 |
+
raises(ValueError, lambda: symbols('a:'))
|
| 330 |
+
raises(ValueError, lambda: symbols('::'))
|
| 331 |
+
raises(ValueError, lambda: symbols('a::'))
|
| 332 |
+
raises(ValueError, lambda: symbols(':a:'))
|
| 333 |
+
raises(ValueError, lambda: symbols('::a'))
|
| 334 |
+
|
| 335 |
+
|
| 336 |
+
def test_symbols_become_functions_issue_3539():
|
| 337 |
+
from sympy.abc import alpha, phi, beta, t
|
| 338 |
+
raises(TypeError, lambda: beta(2))
|
| 339 |
+
raises(TypeError, lambda: beta(2.5))
|
| 340 |
+
raises(TypeError, lambda: phi(2.5))
|
| 341 |
+
raises(TypeError, lambda: alpha(2.5))
|
| 342 |
+
raises(TypeError, lambda: phi(t))
|
| 343 |
+
|
| 344 |
+
|
| 345 |
+
def test_unicode():
|
| 346 |
+
xu = Symbol('x')
|
| 347 |
+
x = Symbol('x')
|
| 348 |
+
assert x == xu
|
| 349 |
+
|
| 350 |
+
raises(TypeError, lambda: Symbol(1))
|
| 351 |
+
|
| 352 |
+
|
| 353 |
+
def test_uniquely_named_symbol_and_Symbol():
|
| 354 |
+
F = uniquely_named_symbol
|
| 355 |
+
x = Symbol('x')
|
| 356 |
+
assert F(x) == x
|
| 357 |
+
assert F('x') == x
|
| 358 |
+
assert str(F('x', x)) == 'x0'
|
| 359 |
+
assert str(F('x', (x + 1, 1/x))) == 'x0'
|
| 360 |
+
_x = Symbol('x', real=True)
|
| 361 |
+
assert F(('x', _x)) == _x
|
| 362 |
+
assert F((x, _x)) == _x
|
| 363 |
+
assert F('x', real=True).is_real
|
| 364 |
+
y = Symbol('y')
|
| 365 |
+
assert F(('x', y), real=True).is_real
|
| 366 |
+
r = Symbol('x', real=True)
|
| 367 |
+
assert F(('x', r)).is_real
|
| 368 |
+
assert F(('x', r), real=False).is_real
|
| 369 |
+
assert F('x1', Symbol('x1'),
|
| 370 |
+
compare=lambda i: str(i).rstrip('1')).name == 'x0'
|
| 371 |
+
assert F('x1', Symbol('x1'),
|
| 372 |
+
modify=lambda i: i + '_').name == 'x1_'
|
| 373 |
+
assert _symbol(x, _x) == x
|
| 374 |
+
|
| 375 |
+
|
| 376 |
+
def test_disambiguate():
|
| 377 |
+
x, y, y_1, _x, x_1, x_2 = symbols('x y y_1 _x x_1 x_2')
|
| 378 |
+
t1 = Dummy('y'), _x, Dummy('x'), Dummy('x')
|
| 379 |
+
t2 = Dummy('x'), Dummy('x')
|
| 380 |
+
t3 = Dummy('x'), Dummy('y')
|
| 381 |
+
t4 = x, Dummy('x')
|
| 382 |
+
t5 = Symbol('x', integer=True), x, Symbol('x_1')
|
| 383 |
+
|
| 384 |
+
assert disambiguate(*t1) == (y, x_2, x, x_1)
|
| 385 |
+
assert disambiguate(*t2) == (x, x_1)
|
| 386 |
+
assert disambiguate(*t3) == (x, y)
|
| 387 |
+
assert disambiguate(*t4) == (x_1, x)
|
| 388 |
+
assert disambiguate(*t5) == (t5[0], x_2, x_1)
|
| 389 |
+
assert disambiguate(*t5)[0] != x # assumptions are retained
|
| 390 |
+
|
| 391 |
+
t6 = _x, Dummy('x')/y
|
| 392 |
+
t7 = y*Dummy('y'), y
|
| 393 |
+
|
| 394 |
+
assert disambiguate(*t6) == (x_1, x/y)
|
| 395 |
+
assert disambiguate(*t7) == (y*y_1, y_1)
|
| 396 |
+
assert disambiguate(Dummy('x_1'), Dummy('x_1')
|
| 397 |
+
) == (x_1, Symbol('x_1_1'))
|
| 398 |
+
|
| 399 |
+
|
| 400 |
+
@skip_under_pyodide("Cannot create threads under pyodide.")
|
| 401 |
+
def test_issue_gh_16734():
|
| 402 |
+
# https://github.com/sympy/sympy/issues/16734
|
| 403 |
+
|
| 404 |
+
syms = list(symbols('x, y'))
|
| 405 |
+
|
| 406 |
+
def thread1():
|
| 407 |
+
for n in range(1000):
|
| 408 |
+
syms[0], syms[1] = symbols(f'x{n}, y{n}')
|
| 409 |
+
syms[0].is_positive # Check an assumption in this thread.
|
| 410 |
+
syms[0] = None
|
| 411 |
+
|
| 412 |
+
def thread2():
|
| 413 |
+
while syms[0] is not None:
|
| 414 |
+
# Compare the symbol in this thread.
|
| 415 |
+
result = (syms[0] == syms[1]) # noqa
|
| 416 |
+
|
| 417 |
+
# Previously this would be very likely to raise an exception:
|
| 418 |
+
thread = threading.Thread(target=thread1)
|
| 419 |
+
thread.start()
|
| 420 |
+
thread2()
|
| 421 |
+
thread.join()
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_sympify.py
ADDED
|
@@ -0,0 +1,892 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.add import Add
|
| 2 |
+
from sympy.core.containers import Tuple
|
| 3 |
+
from sympy.core.function import (Function, Lambda)
|
| 4 |
+
from sympy.core.mul import Mul
|
| 5 |
+
from sympy.core.numbers import (Float, I, Integer, Rational, pi, oo)
|
| 6 |
+
from sympy.core.power import Pow
|
| 7 |
+
from sympy.core.singleton import S
|
| 8 |
+
from sympy.core.symbol import Symbol
|
| 9 |
+
from sympy.functions.elementary.complexes import Abs
|
| 10 |
+
from sympy.functions.elementary.exponential import exp
|
| 11 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 12 |
+
from sympy.functions.elementary.trigonometric import (cos, sin)
|
| 13 |
+
from sympy.logic.boolalg import (false, Or, true, Xor)
|
| 14 |
+
from sympy.matrices.dense import Matrix
|
| 15 |
+
from sympy.parsing.sympy_parser import null
|
| 16 |
+
from sympy.polys.polytools import Poly
|
| 17 |
+
from sympy.printing.repr import srepr
|
| 18 |
+
from sympy.sets.fancysets import Range
|
| 19 |
+
from sympy.sets.sets import Interval
|
| 20 |
+
from sympy.abc import x, y
|
| 21 |
+
from sympy.core.sympify import (sympify, _sympify, SympifyError, kernS,
|
| 22 |
+
CantSympify, converter)
|
| 23 |
+
from sympy.core.decorators import _sympifyit
|
| 24 |
+
from sympy.external import import_module
|
| 25 |
+
from sympy.testing.pytest import raises, XFAIL, skip
|
| 26 |
+
from sympy.utilities.decorator import conserve_mpmath_dps
|
| 27 |
+
from sympy.geometry import Point, Line
|
| 28 |
+
from sympy.functions.combinatorial.factorials import factorial, factorial2
|
| 29 |
+
from sympy.abc import _clash, _clash1, _clash2
|
| 30 |
+
from sympy.external.gmpy import gmpy as _gmpy, flint as _flint
|
| 31 |
+
from sympy.sets import FiniteSet, EmptySet
|
| 32 |
+
from sympy.tensor.array.dense_ndim_array import ImmutableDenseNDimArray
|
| 33 |
+
|
| 34 |
+
import mpmath
|
| 35 |
+
from collections import defaultdict, OrderedDict
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
numpy = import_module('numpy')
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def test_issue_3538():
|
| 42 |
+
v = sympify("exp(x)")
|
| 43 |
+
assert v == exp(x)
|
| 44 |
+
assert type(v) == type(exp(x))
|
| 45 |
+
assert str(type(v)) == str(type(exp(x)))
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def test_sympify1():
|
| 49 |
+
assert sympify("x") == Symbol("x")
|
| 50 |
+
assert sympify(" x") == Symbol("x")
|
| 51 |
+
assert sympify(" x ") == Symbol("x")
|
| 52 |
+
# issue 4877
|
| 53 |
+
assert sympify('--.5') == 0.5
|
| 54 |
+
assert sympify('-1/2') == -S.Half
|
| 55 |
+
assert sympify('-+--.5') == -0.5
|
| 56 |
+
assert sympify('-.[3]') == Rational(-1, 3)
|
| 57 |
+
assert sympify('.[3]') == Rational(1, 3)
|
| 58 |
+
assert sympify('+.[3]') == Rational(1, 3)
|
| 59 |
+
assert sympify('+0.[3]*10**-2') == Rational(1, 300)
|
| 60 |
+
assert sympify('.[052631578947368421]') == Rational(1, 19)
|
| 61 |
+
assert sympify('.0[526315789473684210]') == Rational(1, 19)
|
| 62 |
+
assert sympify('.034[56]') == Rational(1711, 49500)
|
| 63 |
+
# options to make reals into rationals
|
| 64 |
+
assert sympify('1.22[345]', rational=True) == \
|
| 65 |
+
1 + Rational(22, 100) + Rational(345, 99900)
|
| 66 |
+
assert sympify('2/2.6', rational=True) == Rational(10, 13)
|
| 67 |
+
assert sympify('2.6/2', rational=True) == Rational(13, 10)
|
| 68 |
+
assert sympify('2.6e2/17', rational=True) == Rational(260, 17)
|
| 69 |
+
assert sympify('2.6e+2/17', rational=True) == Rational(260, 17)
|
| 70 |
+
assert sympify('2.6e-2/17', rational=True) == Rational(26, 17000)
|
| 71 |
+
assert sympify('2.1+3/4', rational=True) == \
|
| 72 |
+
Rational(21, 10) + Rational(3, 4)
|
| 73 |
+
assert sympify('2.234456', rational=True) == Rational(279307, 125000)
|
| 74 |
+
assert sympify('2.234456e23', rational=True) == 223445600000000000000000
|
| 75 |
+
assert sympify('2.234456e-23', rational=True) == \
|
| 76 |
+
Rational(279307, 12500000000000000000000000000)
|
| 77 |
+
assert sympify('-2.234456e-23', rational=True) == \
|
| 78 |
+
Rational(-279307, 12500000000000000000000000000)
|
| 79 |
+
assert sympify('12345678901/17', rational=True) == \
|
| 80 |
+
Rational(12345678901, 17)
|
| 81 |
+
assert sympify('1/.3 + x', rational=True) == Rational(10, 3) + x
|
| 82 |
+
# make sure longs in fractions work
|
| 83 |
+
assert sympify('222222222222/11111111111') == \
|
| 84 |
+
Rational(222222222222, 11111111111)
|
| 85 |
+
# ... even if they come from repetend notation
|
| 86 |
+
assert sympify('1/.2[123456789012]') == Rational(333333333333, 70781892967)
|
| 87 |
+
# ... or from high precision reals
|
| 88 |
+
assert sympify('.1234567890123456', rational=True) == \
|
| 89 |
+
Rational(19290123283179, 156250000000000)
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
def test_sympify_Fraction():
|
| 93 |
+
try:
|
| 94 |
+
import fractions
|
| 95 |
+
except ImportError:
|
| 96 |
+
pass
|
| 97 |
+
else:
|
| 98 |
+
value = sympify(fractions.Fraction(101, 127))
|
| 99 |
+
assert value == Rational(101, 127) and type(value) is Rational
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def test_sympify_gmpy():
|
| 103 |
+
if _gmpy is not None:
|
| 104 |
+
import gmpy2
|
| 105 |
+
|
| 106 |
+
value = sympify(gmpy2.mpz(1000001))
|
| 107 |
+
assert value == Integer(1000001) and type(value) is Integer
|
| 108 |
+
|
| 109 |
+
value = sympify(gmpy2.mpq(101, 127))
|
| 110 |
+
assert value == Rational(101, 127) and type(value) is Rational
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
def test_sympify_flint():
|
| 114 |
+
if _flint is not None:
|
| 115 |
+
import flint
|
| 116 |
+
|
| 117 |
+
value = sympify(flint.fmpz(1000001))
|
| 118 |
+
assert value == Integer(1000001) and type(value) is Integer
|
| 119 |
+
|
| 120 |
+
value = sympify(flint.fmpq(101, 127))
|
| 121 |
+
assert value == Rational(101, 127) and type(value) is Rational
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
@conserve_mpmath_dps
|
| 125 |
+
def test_sympify_mpmath():
|
| 126 |
+
value = sympify(mpmath.mpf(1.0))
|
| 127 |
+
assert value == Float(1.0) and type(value) is Float
|
| 128 |
+
|
| 129 |
+
mpmath.mp.dps = 12
|
| 130 |
+
assert sympify(
|
| 131 |
+
mpmath.pi).epsilon_eq(Float("3.14159265359"), Float("1e-12")) == True
|
| 132 |
+
assert sympify(
|
| 133 |
+
mpmath.pi).epsilon_eq(Float("3.14159265359"), Float("1e-13")) == False
|
| 134 |
+
|
| 135 |
+
mpmath.mp.dps = 6
|
| 136 |
+
assert sympify(
|
| 137 |
+
mpmath.pi).epsilon_eq(Float("3.14159"), Float("1e-5")) == True
|
| 138 |
+
assert sympify(
|
| 139 |
+
mpmath.pi).epsilon_eq(Float("3.14159"), Float("1e-6")) == False
|
| 140 |
+
|
| 141 |
+
mpmath.mp.dps = 15
|
| 142 |
+
assert sympify(mpmath.mpc(1.0 + 2.0j)) == Float(1.0) + Float(2.0)*I
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
def test_sympify2():
|
| 146 |
+
class A:
|
| 147 |
+
def _sympy_(self):
|
| 148 |
+
return Symbol("x")**3
|
| 149 |
+
|
| 150 |
+
a = A()
|
| 151 |
+
|
| 152 |
+
assert _sympify(a) == x**3
|
| 153 |
+
assert sympify(a) == x**3
|
| 154 |
+
assert a == x**3
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def test_sympify3():
|
| 158 |
+
assert sympify("x**3") == x**3
|
| 159 |
+
assert sympify("x^3") == x**3
|
| 160 |
+
assert sympify("1/2") == Integer(1)/2
|
| 161 |
+
|
| 162 |
+
raises(SympifyError, lambda: _sympify('x**3'))
|
| 163 |
+
raises(SympifyError, lambda: _sympify('1/2'))
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
def test_sympify_keywords():
|
| 167 |
+
raises(SympifyError, lambda: sympify('if'))
|
| 168 |
+
raises(SympifyError, lambda: sympify('for'))
|
| 169 |
+
raises(SympifyError, lambda: sympify('while'))
|
| 170 |
+
raises(SympifyError, lambda: sympify('lambda'))
|
| 171 |
+
|
| 172 |
+
|
| 173 |
+
def test_sympify_float():
|
| 174 |
+
assert sympify("1e-64") != 0
|
| 175 |
+
assert sympify("1e-20000") != 0
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
def test_sympify_bool():
|
| 179 |
+
assert sympify(True) is true
|
| 180 |
+
assert sympify(False) is false
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
def test_sympify_iterables():
|
| 184 |
+
ans = [Rational(3, 10), Rational(1, 5)]
|
| 185 |
+
assert sympify(['.3', '.2'], rational=True) == ans
|
| 186 |
+
assert sympify({"x": 0, "y": 1}) == {x: 0, y: 1}
|
| 187 |
+
assert sympify(['1', '2', ['3', '4']]) == [S(1), S(2), [S(3), S(4)]]
|
| 188 |
+
|
| 189 |
+
|
| 190 |
+
@XFAIL
|
| 191 |
+
def test_issue_16772():
|
| 192 |
+
# because there is a converter for tuple, the
|
| 193 |
+
# args are only sympified without the flags being passed
|
| 194 |
+
# along; list, on the other hand, is not converted
|
| 195 |
+
# with a converter so its args are traversed later
|
| 196 |
+
ans = [Rational(3, 10), Rational(1, 5)]
|
| 197 |
+
assert sympify(('.3', '.2'), rational=True) == Tuple(*ans)
|
| 198 |
+
|
| 199 |
+
|
| 200 |
+
def test_issue_16859():
|
| 201 |
+
class no(float, CantSympify):
|
| 202 |
+
pass
|
| 203 |
+
raises(SympifyError, lambda: sympify(no(1.2)))
|
| 204 |
+
|
| 205 |
+
|
| 206 |
+
def test_sympify4():
|
| 207 |
+
class A:
|
| 208 |
+
def _sympy_(self):
|
| 209 |
+
return Symbol("x")
|
| 210 |
+
|
| 211 |
+
a = A()
|
| 212 |
+
|
| 213 |
+
assert _sympify(a)**3 == x**3
|
| 214 |
+
assert sympify(a)**3 == x**3
|
| 215 |
+
assert a == x
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
def test_sympify_text():
|
| 219 |
+
assert sympify('some') == Symbol('some')
|
| 220 |
+
assert sympify('core') == Symbol('core')
|
| 221 |
+
|
| 222 |
+
assert sympify('True') is True
|
| 223 |
+
assert sympify('False') is False
|
| 224 |
+
|
| 225 |
+
assert sympify('Poly') == Poly
|
| 226 |
+
assert sympify('sin') == sin
|
| 227 |
+
|
| 228 |
+
|
| 229 |
+
def test_sympify_function():
|
| 230 |
+
assert sympify('factor(x**2-1, x)') == -(1 - x)*(x + 1)
|
| 231 |
+
assert sympify('sin(pi/2)*cos(pi)') == -Integer(1)
|
| 232 |
+
|
| 233 |
+
|
| 234 |
+
def test_sympify_poly():
|
| 235 |
+
p = Poly(x**2 + x + 1, x)
|
| 236 |
+
|
| 237 |
+
assert _sympify(p) is p
|
| 238 |
+
assert sympify(p) is p
|
| 239 |
+
|
| 240 |
+
|
| 241 |
+
def test_sympify_factorial():
|
| 242 |
+
assert sympify('x!') == factorial(x)
|
| 243 |
+
assert sympify('(x+1)!') == factorial(x + 1)
|
| 244 |
+
assert sympify('(1 + y*(x + 1))!') == factorial(1 + y*(x + 1))
|
| 245 |
+
assert sympify('(1 + y*(x + 1)!)^2') == (1 + y*factorial(x + 1))**2
|
| 246 |
+
assert sympify('y*x!') == y*factorial(x)
|
| 247 |
+
assert sympify('x!!') == factorial2(x)
|
| 248 |
+
assert sympify('(x+1)!!') == factorial2(x + 1)
|
| 249 |
+
assert sympify('(1 + y*(x + 1))!!') == factorial2(1 + y*(x + 1))
|
| 250 |
+
assert sympify('(1 + y*(x + 1)!!)^2') == (1 + y*factorial2(x + 1))**2
|
| 251 |
+
assert sympify('y*x!!') == y*factorial2(x)
|
| 252 |
+
assert sympify('factorial2(x)!') == factorial(factorial2(x))
|
| 253 |
+
|
| 254 |
+
raises(SympifyError, lambda: sympify("+!!"))
|
| 255 |
+
raises(SympifyError, lambda: sympify(")!!"))
|
| 256 |
+
raises(SympifyError, lambda: sympify("!"))
|
| 257 |
+
raises(SympifyError, lambda: sympify("(!)"))
|
| 258 |
+
raises(SympifyError, lambda: sympify("x!!!"))
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
def test_issue_3595():
|
| 262 |
+
assert sympify("a_") == Symbol("a_")
|
| 263 |
+
assert sympify("_a") == Symbol("_a")
|
| 264 |
+
|
| 265 |
+
|
| 266 |
+
def test_lambda():
|
| 267 |
+
x = Symbol('x')
|
| 268 |
+
assert sympify('lambda: 1') == Lambda((), 1)
|
| 269 |
+
assert sympify('lambda x: x') == Lambda(x, x)
|
| 270 |
+
assert sympify('lambda x: 2*x') == Lambda(x, 2*x)
|
| 271 |
+
assert sympify('lambda x, y: 2*x+y') == Lambda((x, y), 2*x + y)
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
def test_lambda_raises():
|
| 275 |
+
raises(SympifyError, lambda: sympify("lambda *args: args")) # args argument error
|
| 276 |
+
raises(SympifyError, lambda: sympify("lambda **kwargs: kwargs[0]")) # kwargs argument error
|
| 277 |
+
raises(SympifyError, lambda: sympify("lambda x = 1: x")) # Keyword argument error
|
| 278 |
+
with raises(SympifyError):
|
| 279 |
+
_sympify('lambda: 1')
|
| 280 |
+
|
| 281 |
+
|
| 282 |
+
def test_sympify_raises():
|
| 283 |
+
raises(SympifyError, lambda: sympify("fx)"))
|
| 284 |
+
|
| 285 |
+
class A:
|
| 286 |
+
def __str__(self):
|
| 287 |
+
return 'x'
|
| 288 |
+
|
| 289 |
+
raises(SympifyError, lambda: sympify(A()))
|
| 290 |
+
|
| 291 |
+
|
| 292 |
+
def test__sympify():
|
| 293 |
+
x = Symbol('x')
|
| 294 |
+
f = Function('f')
|
| 295 |
+
|
| 296 |
+
# positive _sympify
|
| 297 |
+
assert _sympify(x) is x
|
| 298 |
+
assert _sympify(1) == Integer(1)
|
| 299 |
+
assert _sympify(0.5) == Float("0.5")
|
| 300 |
+
assert _sympify(1 + 1j) == 1.0 + I*1.0
|
| 301 |
+
|
| 302 |
+
# Function f is not Basic and can't sympify to Basic. We allow it to pass
|
| 303 |
+
# with sympify but not with _sympify.
|
| 304 |
+
# https://github.com/sympy/sympy/issues/20124
|
| 305 |
+
assert sympify(f) is f
|
| 306 |
+
raises(SympifyError, lambda: _sympify(f))
|
| 307 |
+
|
| 308 |
+
class A:
|
| 309 |
+
def _sympy_(self):
|
| 310 |
+
return Integer(5)
|
| 311 |
+
|
| 312 |
+
a = A()
|
| 313 |
+
assert _sympify(a) == Integer(5)
|
| 314 |
+
|
| 315 |
+
# negative _sympify
|
| 316 |
+
raises(SympifyError, lambda: _sympify('1'))
|
| 317 |
+
raises(SympifyError, lambda: _sympify([1, 2, 3]))
|
| 318 |
+
|
| 319 |
+
|
| 320 |
+
def test_sympifyit():
|
| 321 |
+
x = Symbol('x')
|
| 322 |
+
y = Symbol('y')
|
| 323 |
+
|
| 324 |
+
@_sympifyit('b', NotImplemented)
|
| 325 |
+
def add(a, b):
|
| 326 |
+
return a + b
|
| 327 |
+
|
| 328 |
+
assert add(x, 1) == x + 1
|
| 329 |
+
assert add(x, 0.5) == x + Float('0.5')
|
| 330 |
+
assert add(x, y) == x + y
|
| 331 |
+
|
| 332 |
+
assert add(x, '1') == NotImplemented
|
| 333 |
+
|
| 334 |
+
@_sympifyit('b')
|
| 335 |
+
def add_raises(a, b):
|
| 336 |
+
return a + b
|
| 337 |
+
|
| 338 |
+
assert add_raises(x, 1) == x + 1
|
| 339 |
+
assert add_raises(x, 0.5) == x + Float('0.5')
|
| 340 |
+
assert add_raises(x, y) == x + y
|
| 341 |
+
|
| 342 |
+
raises(SympifyError, lambda: add_raises(x, '1'))
|
| 343 |
+
|
| 344 |
+
|
| 345 |
+
def test_int_float():
|
| 346 |
+
class F1_1:
|
| 347 |
+
def __float__(self):
|
| 348 |
+
return 1.1
|
| 349 |
+
|
| 350 |
+
class F1_1b:
|
| 351 |
+
"""
|
| 352 |
+
This class is still a float, even though it also implements __int__().
|
| 353 |
+
"""
|
| 354 |
+
def __float__(self):
|
| 355 |
+
return 1.1
|
| 356 |
+
|
| 357 |
+
def __int__(self):
|
| 358 |
+
return 1
|
| 359 |
+
|
| 360 |
+
class F1_1c:
|
| 361 |
+
"""
|
| 362 |
+
This class is still a float, because it implements _sympy_()
|
| 363 |
+
"""
|
| 364 |
+
def __float__(self):
|
| 365 |
+
return 1.1
|
| 366 |
+
|
| 367 |
+
def __int__(self):
|
| 368 |
+
return 1
|
| 369 |
+
|
| 370 |
+
def _sympy_(self):
|
| 371 |
+
return Float(1.1)
|
| 372 |
+
|
| 373 |
+
class I5:
|
| 374 |
+
def __int__(self):
|
| 375 |
+
return 5
|
| 376 |
+
|
| 377 |
+
class I5b:
|
| 378 |
+
"""
|
| 379 |
+
This class implements both __int__() and __float__(), so it will be
|
| 380 |
+
treated as Float in SymPy. One could change this behavior, by using
|
| 381 |
+
float(a) == int(a), but deciding that integer-valued floats represent
|
| 382 |
+
exact numbers is arbitrary and often not correct, so we do not do it.
|
| 383 |
+
If, in the future, we decide to do it anyway, the tests for I5b need to
|
| 384 |
+
be changed.
|
| 385 |
+
"""
|
| 386 |
+
def __float__(self):
|
| 387 |
+
return 5.0
|
| 388 |
+
|
| 389 |
+
def __int__(self):
|
| 390 |
+
return 5
|
| 391 |
+
|
| 392 |
+
class I5c:
|
| 393 |
+
"""
|
| 394 |
+
This class implements both __int__() and __float__(), but also
|
| 395 |
+
a _sympy_() method, so it will be Integer.
|
| 396 |
+
"""
|
| 397 |
+
def __float__(self):
|
| 398 |
+
return 5.0
|
| 399 |
+
|
| 400 |
+
def __int__(self):
|
| 401 |
+
return 5
|
| 402 |
+
|
| 403 |
+
def _sympy_(self):
|
| 404 |
+
return Integer(5)
|
| 405 |
+
|
| 406 |
+
i5 = I5()
|
| 407 |
+
i5b = I5b()
|
| 408 |
+
i5c = I5c()
|
| 409 |
+
f1_1 = F1_1()
|
| 410 |
+
f1_1b = F1_1b()
|
| 411 |
+
f1_1c = F1_1c()
|
| 412 |
+
assert sympify(i5) == 5
|
| 413 |
+
assert isinstance(sympify(i5), Integer)
|
| 414 |
+
assert sympify(i5b) == 5.0
|
| 415 |
+
assert isinstance(sympify(i5b), Float)
|
| 416 |
+
assert sympify(i5c) == 5
|
| 417 |
+
assert isinstance(sympify(i5c), Integer)
|
| 418 |
+
assert abs(sympify(f1_1) - 1.1) < 1e-5
|
| 419 |
+
assert abs(sympify(f1_1b) - 1.1) < 1e-5
|
| 420 |
+
assert abs(sympify(f1_1c) - 1.1) < 1e-5
|
| 421 |
+
|
| 422 |
+
assert _sympify(i5) == 5
|
| 423 |
+
assert isinstance(_sympify(i5), Integer)
|
| 424 |
+
assert _sympify(i5b) == 5.0
|
| 425 |
+
assert isinstance(_sympify(i5b), Float)
|
| 426 |
+
assert _sympify(i5c) == 5
|
| 427 |
+
assert isinstance(_sympify(i5c), Integer)
|
| 428 |
+
assert abs(_sympify(f1_1) - 1.1) < 1e-5
|
| 429 |
+
assert abs(_sympify(f1_1b) - 1.1) < 1e-5
|
| 430 |
+
assert abs(_sympify(f1_1c) - 1.1) < 1e-5
|
| 431 |
+
|
| 432 |
+
|
| 433 |
+
def test_evaluate_false():
|
| 434 |
+
cases = {
|
| 435 |
+
'2 + 3': Add(2, 3, evaluate=False),
|
| 436 |
+
'2**2 / 3': Mul(Pow(2, 2, evaluate=False), Pow(3, -1, evaluate=False), evaluate=False),
|
| 437 |
+
'2 + 3 * 5': Add(2, Mul(3, 5, evaluate=False), evaluate=False),
|
| 438 |
+
'2 - 3 * 5': Add(2, Mul(-1, Mul(3, 5,evaluate=False), evaluate=False), evaluate=False),
|
| 439 |
+
'1 / 3': Mul(1, Pow(3, -1, evaluate=False), evaluate=False),
|
| 440 |
+
'True | False': Or(True, False, evaluate=False),
|
| 441 |
+
'1 + 2 + 3 + 5*3 + integrate(x)': Add(1, 2, 3, Mul(5, 3, evaluate=False), x**2/2, evaluate=False),
|
| 442 |
+
'2 * 4 * 6 + 8': Add(Mul(2, 4, 6, evaluate=False), 8, evaluate=False),
|
| 443 |
+
'2 - 8 / 4': Add(2, Mul(-1, Mul(8, Pow(4, -1, evaluate=False), evaluate=False), evaluate=False), evaluate=False),
|
| 444 |
+
'2 - 2**2': Add(2, Mul(-1, Pow(2, 2, evaluate=False), evaluate=False), evaluate=False),
|
| 445 |
+
}
|
| 446 |
+
for case, result in cases.items():
|
| 447 |
+
assert sympify(case, evaluate=False) == result
|
| 448 |
+
|
| 449 |
+
|
| 450 |
+
def test_issue_4133():
|
| 451 |
+
a = sympify('Integer(4)')
|
| 452 |
+
|
| 453 |
+
assert a == Integer(4)
|
| 454 |
+
assert a.is_Integer
|
| 455 |
+
|
| 456 |
+
|
| 457 |
+
def test_issue_3982():
|
| 458 |
+
a = [3, 2.0]
|
| 459 |
+
assert sympify(a) == [Integer(3), Float(2.0)]
|
| 460 |
+
assert sympify(tuple(a)) == Tuple(Integer(3), Float(2.0))
|
| 461 |
+
assert sympify(set(a)) == FiniteSet(Integer(3), Float(2.0))
|
| 462 |
+
|
| 463 |
+
|
| 464 |
+
def test_S_sympify():
|
| 465 |
+
assert S(1)/2 == sympify(1)/2 == S.Half
|
| 466 |
+
assert (-2)**(S(1)/2) == sqrt(2)*I
|
| 467 |
+
|
| 468 |
+
|
| 469 |
+
def test_issue_4788():
|
| 470 |
+
assert srepr(S(1.0 + 0J)) == srepr(S(1.0)) == srepr(Float(1.0))
|
| 471 |
+
|
| 472 |
+
|
| 473 |
+
def test_issue_4798_None():
|
| 474 |
+
assert S(None) is None
|
| 475 |
+
|
| 476 |
+
|
| 477 |
+
def test_issue_3218():
|
| 478 |
+
assert sympify("x+\ny") == x + y
|
| 479 |
+
|
| 480 |
+
def test_issue_19399():
|
| 481 |
+
if not numpy:
|
| 482 |
+
skip("numpy not installed.")
|
| 483 |
+
|
| 484 |
+
a = numpy.array(Rational(1, 2))
|
| 485 |
+
b = Rational(1, 3)
|
| 486 |
+
assert (a * b, type(a * b)) == (b * a, type(b * a))
|
| 487 |
+
|
| 488 |
+
|
| 489 |
+
def test_issue_4988_builtins():
|
| 490 |
+
C = Symbol('C')
|
| 491 |
+
vars = {'C': C}
|
| 492 |
+
exp1 = sympify('C')
|
| 493 |
+
assert exp1 == C # Make sure it did not get mixed up with sympy.C
|
| 494 |
+
|
| 495 |
+
exp2 = sympify('C', vars)
|
| 496 |
+
assert exp2 == C # Make sure it did not get mixed up with sympy.C
|
| 497 |
+
|
| 498 |
+
|
| 499 |
+
def test_geometry():
|
| 500 |
+
p = sympify(Point(0, 1))
|
| 501 |
+
assert p == Point(0, 1) and isinstance(p, Point)
|
| 502 |
+
L = sympify(Line(p, (1, 0)))
|
| 503 |
+
assert L == Line((0, 1), (1, 0)) and isinstance(L, Line)
|
| 504 |
+
|
| 505 |
+
|
| 506 |
+
def test_kernS():
|
| 507 |
+
s = '-1 - 2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x)))'
|
| 508 |
+
# when 1497 is fixed, this no longer should pass: the expression
|
| 509 |
+
# should be unchanged
|
| 510 |
+
assert -1 - 2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x))) == -1
|
| 511 |
+
# sympification should not allow the constant to enter a Mul
|
| 512 |
+
# or else the structure can change dramatically
|
| 513 |
+
ss = kernS(s)
|
| 514 |
+
assert ss != -1 and ss.simplify() == -1
|
| 515 |
+
s = '-1 - 2*(-(-x + 1/x)/(x*(x - 1/x)**2) - 1/(x*(x - 1/x)))'.replace(
|
| 516 |
+
'x', '_kern')
|
| 517 |
+
ss = kernS(s)
|
| 518 |
+
assert ss != -1 and ss.simplify() == -1
|
| 519 |
+
# issue 6687
|
| 520 |
+
assert (kernS('Interval(-1,-2 - 4*(-3))')
|
| 521 |
+
== Interval(-1, Add(-2, Mul(12, 1, evaluate=False), evaluate=False)))
|
| 522 |
+
assert kernS('_kern') == Symbol('_kern')
|
| 523 |
+
assert kernS('E**-(x)') == exp(-x)
|
| 524 |
+
e = 2*(x + y)*y
|
| 525 |
+
assert kernS(['2*(x + y)*y', ('2*(x + y)*y',)]) == [e, (e,)]
|
| 526 |
+
assert kernS('-(2*sin(x)**2 + 2*sin(x)*cos(x))*y/2') == \
|
| 527 |
+
-y*(2*sin(x)**2 + 2*sin(x)*cos(x))/2
|
| 528 |
+
# issue 15132
|
| 529 |
+
assert kernS('(1 - x)/(1 - x*(1-y))') == kernS('(1-x)/(1-(1-y)*x)')
|
| 530 |
+
assert kernS('(1-2**-(4+1)*(1-y)*x)') == (1 - x*(1 - y)/32)
|
| 531 |
+
assert kernS('(1-2**(4+1)*(1-y)*x)') == (1 - 32*x*(1 - y))
|
| 532 |
+
assert kernS('(1-2.*(1-y)*x)') == 1 - 2.*x*(1 - y)
|
| 533 |
+
one = kernS('x - (x - 1)')
|
| 534 |
+
assert one != 1 and one.expand() == 1
|
| 535 |
+
assert kernS("(2*x)/(x-1)") == 2*x/(x-1)
|
| 536 |
+
|
| 537 |
+
|
| 538 |
+
def test_issue_6540_6552():
|
| 539 |
+
assert S('[[1/3,2], (2/5,)]') == [[Rational(1, 3), 2], (Rational(2, 5),)]
|
| 540 |
+
assert S('[[2/6,2], (2/4,)]') == [[Rational(1, 3), 2], (S.Half,)]
|
| 541 |
+
assert S('[[[2*(1)]]]') == [[[2]]]
|
| 542 |
+
assert S('Matrix([2*(1)])') == Matrix([2])
|
| 543 |
+
|
| 544 |
+
|
| 545 |
+
def test_issue_6046():
|
| 546 |
+
assert str(S("Q & C", locals=_clash1)) == 'C & Q'
|
| 547 |
+
assert str(S('pi(x)', locals=_clash2)) == 'pi(x)'
|
| 548 |
+
locals = {}
|
| 549 |
+
exec("from sympy.abc import Q, C", locals)
|
| 550 |
+
assert str(S('C&Q', locals)) == 'C & Q'
|
| 551 |
+
# clash can act as Symbol or Function
|
| 552 |
+
assert str(S('pi(C, Q)', locals=_clash)) == 'pi(C, Q)'
|
| 553 |
+
assert len(S('pi + x', locals=_clash2).free_symbols) == 2
|
| 554 |
+
# but not both
|
| 555 |
+
raises(TypeError, lambda: S('pi + pi(x)', locals=_clash2))
|
| 556 |
+
assert all(set(i.values()) == {null} for i in (
|
| 557 |
+
_clash, _clash1, _clash2))
|
| 558 |
+
|
| 559 |
+
|
| 560 |
+
def test_issue_8821_highprec_from_str():
|
| 561 |
+
s = str(pi.evalf(128))
|
| 562 |
+
p = sympify(s)
|
| 563 |
+
assert Abs(sin(p)) < 1e-127
|
| 564 |
+
|
| 565 |
+
|
| 566 |
+
def test_issue_10295():
|
| 567 |
+
if not numpy:
|
| 568 |
+
skip("numpy not installed.")
|
| 569 |
+
|
| 570 |
+
A = numpy.array([[1, 3, -1],
|
| 571 |
+
[0, 1, 7]])
|
| 572 |
+
sA = S(A)
|
| 573 |
+
assert sA.shape == (2, 3)
|
| 574 |
+
for (ri, ci), val in numpy.ndenumerate(A):
|
| 575 |
+
assert sA[ri, ci] == val
|
| 576 |
+
|
| 577 |
+
B = numpy.array([-7, x, 3*y**2])
|
| 578 |
+
sB = S(B)
|
| 579 |
+
assert sB.shape == (3,)
|
| 580 |
+
assert B[0] == sB[0] == -7
|
| 581 |
+
assert B[1] == sB[1] == x
|
| 582 |
+
assert B[2] == sB[2] == 3*y**2
|
| 583 |
+
|
| 584 |
+
C = numpy.arange(0, 24)
|
| 585 |
+
C.resize(2,3,4)
|
| 586 |
+
sC = S(C)
|
| 587 |
+
assert sC[0, 0, 0].is_integer
|
| 588 |
+
assert sC[0, 0, 0] == 0
|
| 589 |
+
|
| 590 |
+
a1 = numpy.array([1, 2, 3])
|
| 591 |
+
a2 = numpy.array(list(range(24)))
|
| 592 |
+
a2.resize(2, 4, 3)
|
| 593 |
+
assert sympify(a1) == ImmutableDenseNDimArray([1, 2, 3])
|
| 594 |
+
assert sympify(a2) == ImmutableDenseNDimArray(list(range(24)), (2, 4, 3))
|
| 595 |
+
|
| 596 |
+
|
| 597 |
+
def test_Range():
|
| 598 |
+
# Only works in Python 3 where range returns a range type
|
| 599 |
+
assert sympify(range(10)) == Range(10)
|
| 600 |
+
assert _sympify(range(10)) == Range(10)
|
| 601 |
+
|
| 602 |
+
|
| 603 |
+
def test_sympify_set():
|
| 604 |
+
n = Symbol('n')
|
| 605 |
+
assert sympify({n}) == FiniteSet(n)
|
| 606 |
+
assert sympify(set()) == EmptySet
|
| 607 |
+
|
| 608 |
+
|
| 609 |
+
def test_sympify_numpy():
|
| 610 |
+
if not numpy:
|
| 611 |
+
skip('numpy not installed. Abort numpy tests.')
|
| 612 |
+
np = numpy
|
| 613 |
+
|
| 614 |
+
def equal(x, y):
|
| 615 |
+
return x == y and type(x) == type(y)
|
| 616 |
+
|
| 617 |
+
assert sympify(np.bool_(1)) is S(True)
|
| 618 |
+
try:
|
| 619 |
+
assert equal(
|
| 620 |
+
sympify(np.int_(1234567891234567891)), S(1234567891234567891))
|
| 621 |
+
assert equal(
|
| 622 |
+
sympify(np.intp(1234567891234567891)), S(1234567891234567891))
|
| 623 |
+
except OverflowError:
|
| 624 |
+
# May fail on 32-bit systems: Python int too large to convert to C long
|
| 625 |
+
pass
|
| 626 |
+
assert equal(sympify(np.intc(1234567891)), S(1234567891))
|
| 627 |
+
assert equal(sympify(np.int8(-123)), S(-123))
|
| 628 |
+
assert equal(sympify(np.int16(-12345)), S(-12345))
|
| 629 |
+
assert equal(sympify(np.int32(-1234567891)), S(-1234567891))
|
| 630 |
+
assert equal(
|
| 631 |
+
sympify(np.int64(-1234567891234567891)), S(-1234567891234567891))
|
| 632 |
+
assert equal(sympify(np.uint8(123)), S(123))
|
| 633 |
+
assert equal(sympify(np.uint16(12345)), S(12345))
|
| 634 |
+
assert equal(sympify(np.uint32(1234567891)), S(1234567891))
|
| 635 |
+
assert equal(
|
| 636 |
+
sympify(np.uint64(1234567891234567891)), S(1234567891234567891))
|
| 637 |
+
assert equal(sympify(np.float32(1.123456)), Float(1.123456, precision=24))
|
| 638 |
+
assert equal(sympify(np.float64(1.1234567891234)),
|
| 639 |
+
Float(1.1234567891234, precision=53))
|
| 640 |
+
|
| 641 |
+
# The exact precision of np.longdouble, npfloat128 and other extended
|
| 642 |
+
# precision dtypes is platform dependent.
|
| 643 |
+
ldprec = np.finfo(np.longdouble(1)).nmant + 1
|
| 644 |
+
assert equal(sympify(np.longdouble(1.123456789)),
|
| 645 |
+
Float(1.123456789, precision=ldprec))
|
| 646 |
+
|
| 647 |
+
assert equal(sympify(np.complex64(1 + 2j)), S(1.0 + 2.0*I))
|
| 648 |
+
assert equal(sympify(np.complex128(1 + 2j)), S(1.0 + 2.0*I))
|
| 649 |
+
|
| 650 |
+
lcprec = np.finfo(np.clongdouble(1)).nmant + 1
|
| 651 |
+
assert equal(sympify(np.clongdouble(1 + 2j)),
|
| 652 |
+
Float(1.0, precision=lcprec) + Float(2.0, precision=lcprec)*I)
|
| 653 |
+
|
| 654 |
+
#float96 does not exist on all platforms
|
| 655 |
+
if hasattr(np, 'float96'):
|
| 656 |
+
f96prec = np.finfo(np.float96(1)).nmant + 1
|
| 657 |
+
assert equal(sympify(np.float96(1.123456789)),
|
| 658 |
+
Float(1.123456789, precision=f96prec))
|
| 659 |
+
|
| 660 |
+
#float128 does not exist on all platforms
|
| 661 |
+
if hasattr(np, 'float128'):
|
| 662 |
+
f128prec = np.finfo(np.float128(1)).nmant + 1
|
| 663 |
+
assert equal(sympify(np.float128(1.123456789123)),
|
| 664 |
+
Float(1.123456789123, precision=f128prec))
|
| 665 |
+
|
| 666 |
+
|
| 667 |
+
@XFAIL
|
| 668 |
+
def test_sympify_rational_numbers_set():
|
| 669 |
+
ans = [Rational(3, 10), Rational(1, 5)]
|
| 670 |
+
assert sympify({'.3', '.2'}, rational=True) == FiniteSet(*ans)
|
| 671 |
+
|
| 672 |
+
|
| 673 |
+
def test_sympify_mro():
|
| 674 |
+
"""Tests the resolution order for classes that implement _sympy_"""
|
| 675 |
+
class a:
|
| 676 |
+
def _sympy_(self):
|
| 677 |
+
return Integer(1)
|
| 678 |
+
class b(a):
|
| 679 |
+
def _sympy_(self):
|
| 680 |
+
return Integer(2)
|
| 681 |
+
class c(a):
|
| 682 |
+
pass
|
| 683 |
+
|
| 684 |
+
assert sympify(a()) == Integer(1)
|
| 685 |
+
assert sympify(b()) == Integer(2)
|
| 686 |
+
assert sympify(c()) == Integer(1)
|
| 687 |
+
|
| 688 |
+
|
| 689 |
+
def test_sympify_converter():
|
| 690 |
+
"""Tests the resolution order for classes in converter"""
|
| 691 |
+
class a:
|
| 692 |
+
pass
|
| 693 |
+
class b(a):
|
| 694 |
+
pass
|
| 695 |
+
class c(a):
|
| 696 |
+
pass
|
| 697 |
+
|
| 698 |
+
converter[a] = lambda x: Integer(1)
|
| 699 |
+
converter[b] = lambda x: Integer(2)
|
| 700 |
+
|
| 701 |
+
assert sympify(a()) == Integer(1)
|
| 702 |
+
assert sympify(b()) == Integer(2)
|
| 703 |
+
assert sympify(c()) == Integer(1)
|
| 704 |
+
|
| 705 |
+
class MyInteger(Integer):
|
| 706 |
+
pass
|
| 707 |
+
|
| 708 |
+
if int in converter:
|
| 709 |
+
int_converter = converter[int]
|
| 710 |
+
else:
|
| 711 |
+
int_converter = None
|
| 712 |
+
|
| 713 |
+
try:
|
| 714 |
+
converter[int] = MyInteger
|
| 715 |
+
assert sympify(1) == MyInteger(1)
|
| 716 |
+
finally:
|
| 717 |
+
if int_converter is None:
|
| 718 |
+
del converter[int]
|
| 719 |
+
else:
|
| 720 |
+
converter[int] = int_converter
|
| 721 |
+
|
| 722 |
+
|
| 723 |
+
def test_issue_13924():
|
| 724 |
+
if not numpy:
|
| 725 |
+
skip("numpy not installed.")
|
| 726 |
+
|
| 727 |
+
a = sympify(numpy.array([1]))
|
| 728 |
+
assert isinstance(a, ImmutableDenseNDimArray)
|
| 729 |
+
assert a[0] == 1
|
| 730 |
+
|
| 731 |
+
|
| 732 |
+
def test_numpy_sympify_args():
|
| 733 |
+
# Issue 15098. Make sure sympify args work with numpy types (like numpy.str_)
|
| 734 |
+
if not numpy:
|
| 735 |
+
skip("numpy not installed.")
|
| 736 |
+
|
| 737 |
+
a = sympify(numpy.str_('a'))
|
| 738 |
+
assert type(a) is Symbol
|
| 739 |
+
assert a == Symbol('a')
|
| 740 |
+
|
| 741 |
+
class CustomSymbol(Symbol):
|
| 742 |
+
pass
|
| 743 |
+
|
| 744 |
+
a = sympify(numpy.str_('a'), {"Symbol": CustomSymbol})
|
| 745 |
+
assert isinstance(a, CustomSymbol)
|
| 746 |
+
|
| 747 |
+
a = sympify(numpy.str_('x^y'))
|
| 748 |
+
assert a == x**y
|
| 749 |
+
a = sympify(numpy.str_('x^y'), convert_xor=False)
|
| 750 |
+
assert a == Xor(x, y)
|
| 751 |
+
|
| 752 |
+
raises(SympifyError, lambda: sympify(numpy.str_('x'), strict=True))
|
| 753 |
+
|
| 754 |
+
a = sympify(numpy.str_('1.1'))
|
| 755 |
+
assert isinstance(a, Float)
|
| 756 |
+
assert a == 1.1
|
| 757 |
+
|
| 758 |
+
a = sympify(numpy.str_('1.1'), rational=True)
|
| 759 |
+
assert isinstance(a, Rational)
|
| 760 |
+
assert a == Rational(11, 10)
|
| 761 |
+
|
| 762 |
+
a = sympify(numpy.str_('x + x'))
|
| 763 |
+
assert isinstance(a, Mul)
|
| 764 |
+
assert a == 2*x
|
| 765 |
+
|
| 766 |
+
a = sympify(numpy.str_('x + x'), evaluate=False)
|
| 767 |
+
assert isinstance(a, Add)
|
| 768 |
+
assert a == Add(x, x, evaluate=False)
|
| 769 |
+
|
| 770 |
+
|
| 771 |
+
def test_issue_5939():
|
| 772 |
+
a = Symbol('a')
|
| 773 |
+
b = Symbol('b')
|
| 774 |
+
assert sympify('''a+\nb''') == a + b
|
| 775 |
+
|
| 776 |
+
|
| 777 |
+
def test_issue_16759():
|
| 778 |
+
d = sympify({.5: 1})
|
| 779 |
+
assert S.Half not in d
|
| 780 |
+
assert Float(.5) in d
|
| 781 |
+
assert d[.5] is S.One
|
| 782 |
+
d = sympify(OrderedDict({.5: 1}))
|
| 783 |
+
assert S.Half not in d
|
| 784 |
+
assert Float(.5) in d
|
| 785 |
+
assert d[.5] is S.One
|
| 786 |
+
d = sympify(defaultdict(int, {.5: 1}))
|
| 787 |
+
assert S.Half not in d
|
| 788 |
+
assert Float(.5) in d
|
| 789 |
+
assert d[.5] is S.One
|
| 790 |
+
|
| 791 |
+
|
| 792 |
+
def test_issue_17811():
|
| 793 |
+
a = Function('a')
|
| 794 |
+
assert sympify('a(x)*5', evaluate=False) == Mul(a(x), 5, evaluate=False)
|
| 795 |
+
|
| 796 |
+
|
| 797 |
+
def test_issue_8439():
|
| 798 |
+
assert sympify(float('inf')) == oo
|
| 799 |
+
assert x + float('inf') == x + oo
|
| 800 |
+
assert S(float('inf')) == oo
|
| 801 |
+
|
| 802 |
+
|
| 803 |
+
def test_issue_14706():
|
| 804 |
+
if not numpy:
|
| 805 |
+
skip("numpy not installed.")
|
| 806 |
+
|
| 807 |
+
z1 = numpy.zeros((1, 1), dtype=numpy.float64)
|
| 808 |
+
z2 = numpy.zeros((2, 2), dtype=numpy.float64)
|
| 809 |
+
z3 = numpy.zeros((), dtype=numpy.float64)
|
| 810 |
+
|
| 811 |
+
y1 = numpy.ones((1, 1), dtype=numpy.float64)
|
| 812 |
+
y2 = numpy.ones((2, 2), dtype=numpy.float64)
|
| 813 |
+
y3 = numpy.ones((), dtype=numpy.float64)
|
| 814 |
+
|
| 815 |
+
assert numpy.all(x + z1 == numpy.full((1, 1), x))
|
| 816 |
+
assert numpy.all(x + z2 == numpy.full((2, 2), x))
|
| 817 |
+
assert numpy.all(z1 + x == numpy.full((1, 1), x))
|
| 818 |
+
assert numpy.all(z2 + x == numpy.full((2, 2), x))
|
| 819 |
+
for z in [z3,
|
| 820 |
+
numpy.int64(0),
|
| 821 |
+
numpy.float64(0),
|
| 822 |
+
numpy.complex64(0)]:
|
| 823 |
+
assert x + z == x
|
| 824 |
+
assert z + x == x
|
| 825 |
+
assert isinstance(x + z, Symbol)
|
| 826 |
+
assert isinstance(z + x, Symbol)
|
| 827 |
+
|
| 828 |
+
# If these tests fail, then it means that numpy has finally
|
| 829 |
+
# fixed the issue of scalar conversion for rank>0 arrays
|
| 830 |
+
# which is mentioned in numpy/numpy#10404. In that case,
|
| 831 |
+
# some changes have to be made in sympify.py.
|
| 832 |
+
# Note: For future reference, for anyone who takes up this
|
| 833 |
+
# issue when numpy has finally fixed their side of the problem,
|
| 834 |
+
# the changes for this temporary fix were introduced in PR 18651
|
| 835 |
+
assert numpy.all(x + y1 == numpy.full((1, 1), x + 1.0))
|
| 836 |
+
assert numpy.all(x + y2 == numpy.full((2, 2), x + 1.0))
|
| 837 |
+
assert numpy.all(y1 + x == numpy.full((1, 1), x + 1.0))
|
| 838 |
+
assert numpy.all(y2 + x == numpy.full((2, 2), x + 1.0))
|
| 839 |
+
for y_ in [y3,
|
| 840 |
+
numpy.int64(1),
|
| 841 |
+
numpy.float64(1),
|
| 842 |
+
numpy.complex64(1)]:
|
| 843 |
+
assert x + y_ == y_ + x
|
| 844 |
+
assert isinstance(x + y_, Add)
|
| 845 |
+
assert isinstance(y_ + x, Add)
|
| 846 |
+
|
| 847 |
+
assert x + numpy.array(x) == 2 * x
|
| 848 |
+
assert x + numpy.array([x]) == numpy.array([2*x], dtype=object)
|
| 849 |
+
|
| 850 |
+
assert sympify(numpy.array([1])) == ImmutableDenseNDimArray([1], 1)
|
| 851 |
+
assert sympify(numpy.array([[[1]]])) == ImmutableDenseNDimArray([1], (1, 1, 1))
|
| 852 |
+
assert sympify(z1) == ImmutableDenseNDimArray([0.0], (1, 1))
|
| 853 |
+
assert sympify(z2) == ImmutableDenseNDimArray([0.0, 0.0, 0.0, 0.0], (2, 2))
|
| 854 |
+
assert sympify(z3) == ImmutableDenseNDimArray([0.0], ())
|
| 855 |
+
assert sympify(z3, strict=True) == 0.0
|
| 856 |
+
|
| 857 |
+
raises(SympifyError, lambda: sympify(numpy.array([1]), strict=True))
|
| 858 |
+
raises(SympifyError, lambda: sympify(z1, strict=True))
|
| 859 |
+
raises(SympifyError, lambda: sympify(z2, strict=True))
|
| 860 |
+
|
| 861 |
+
|
| 862 |
+
def test_issue_21536():
|
| 863 |
+
#test to check evaluate=False in case of iterable input
|
| 864 |
+
u = sympify("x+3*x+2", evaluate=False)
|
| 865 |
+
v = sympify("2*x+4*x+2+4", evaluate=False)
|
| 866 |
+
|
| 867 |
+
assert u.is_Add and set(u.args) == {x, 3*x, 2}
|
| 868 |
+
assert v.is_Add and set(v.args) == {2*x, 4*x, 2, 4}
|
| 869 |
+
assert sympify(["x+3*x+2", "2*x+4*x+2+4"], evaluate=False) == [u, v]
|
| 870 |
+
|
| 871 |
+
#test to check evaluate=True in case of iterable input
|
| 872 |
+
u = sympify("x+3*x+2", evaluate=True)
|
| 873 |
+
v = sympify("2*x+4*x+2+4", evaluate=True)
|
| 874 |
+
|
| 875 |
+
assert u.is_Add and set(u.args) == {4*x, 2}
|
| 876 |
+
assert v.is_Add and set(v.args) == {6*x, 6}
|
| 877 |
+
assert sympify(["x+3*x+2", "2*x+4*x+2+4"], evaluate=True) == [u, v]
|
| 878 |
+
|
| 879 |
+
#test to check evaluate with no input in case of iterable input
|
| 880 |
+
u = sympify("x+3*x+2")
|
| 881 |
+
v = sympify("2*x+4*x+2+4")
|
| 882 |
+
|
| 883 |
+
assert u.is_Add and set(u.args) == {4*x, 2}
|
| 884 |
+
assert v.is_Add and set(v.args) == {6*x, 6}
|
| 885 |
+
assert sympify(["x+3*x+2", "2*x+4*x+2+4"]) == [u, v]
|
| 886 |
+
|
| 887 |
+
def test_issue_27284():
|
| 888 |
+
if not numpy:
|
| 889 |
+
skip("numpy not installed.")
|
| 890 |
+
|
| 891 |
+
assert Float(numpy.float32(float('inf'))) == S.Infinity
|
| 892 |
+
assert Float(numpy.float32(float('-inf'))) == S.NegativeInfinity
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_traversal.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.basic import Basic
|
| 2 |
+
from sympy.core.containers import Tuple
|
| 3 |
+
from sympy.core.sorting import default_sort_key
|
| 4 |
+
from sympy.core.symbol import symbols
|
| 5 |
+
from sympy.core.singleton import S
|
| 6 |
+
from sympy.core.function import expand, Function
|
| 7 |
+
from sympy.core.numbers import I
|
| 8 |
+
from sympy.integrals.integrals import Integral
|
| 9 |
+
from sympy.polys.polytools import factor
|
| 10 |
+
from sympy.core.traversal import preorder_traversal, use, postorder_traversal, iterargs, iterfreeargs
|
| 11 |
+
from sympy.functions.elementary.piecewise import ExprCondPair, Piecewise
|
| 12 |
+
from sympy.testing.pytest import warns_deprecated_sympy
|
| 13 |
+
from sympy.utilities.iterables import capture
|
| 14 |
+
|
| 15 |
+
b1 = Basic()
|
| 16 |
+
b2 = Basic(b1)
|
| 17 |
+
b3 = Basic(b2)
|
| 18 |
+
b21 = Basic(b2, b1)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def test_preorder_traversal():
|
| 22 |
+
expr = Basic(b21, b3)
|
| 23 |
+
assert list(
|
| 24 |
+
preorder_traversal(expr)) == [expr, b21, b2, b1, b1, b3, b2, b1]
|
| 25 |
+
assert list(preorder_traversal(('abc', ('d', 'ef')))) == [
|
| 26 |
+
('abc', ('d', 'ef')), 'abc', ('d', 'ef'), 'd', 'ef']
|
| 27 |
+
|
| 28 |
+
result = []
|
| 29 |
+
pt = preorder_traversal(expr)
|
| 30 |
+
for i in pt:
|
| 31 |
+
result.append(i)
|
| 32 |
+
if i == b2:
|
| 33 |
+
pt.skip()
|
| 34 |
+
assert result == [expr, b21, b2, b1, b3, b2]
|
| 35 |
+
|
| 36 |
+
w, x, y, z = symbols('w:z')
|
| 37 |
+
expr = z + w*(x + y)
|
| 38 |
+
assert list(preorder_traversal([expr], keys=default_sort_key)) == \
|
| 39 |
+
[[w*(x + y) + z], w*(x + y) + z, z, w*(x + y), w, x + y, x, y]
|
| 40 |
+
assert list(preorder_traversal((x + y)*z, keys=True)) == \
|
| 41 |
+
[z*(x + y), z, x + y, x, y]
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def test_use():
|
| 45 |
+
x, y = symbols('x y')
|
| 46 |
+
|
| 47 |
+
assert use(0, expand) == 0
|
| 48 |
+
|
| 49 |
+
f = (x + y)**2*x + 1
|
| 50 |
+
|
| 51 |
+
assert use(f, expand, level=0) == x**3 + 2*x**2*y + x*y**2 + + 1
|
| 52 |
+
assert use(f, expand, level=1) == x**3 + 2*x**2*y + x*y**2 + + 1
|
| 53 |
+
assert use(f, expand, level=2) == 1 + x*(2*x*y + x**2 + y**2)
|
| 54 |
+
assert use(f, expand, level=3) == (x + y)**2*x + 1
|
| 55 |
+
|
| 56 |
+
f = (x**2 + 1)**2 - 1
|
| 57 |
+
kwargs = {'gaussian': True}
|
| 58 |
+
|
| 59 |
+
assert use(f, factor, level=0, kwargs=kwargs) == x**2*(x**2 + 2)
|
| 60 |
+
assert use(f, factor, level=1, kwargs=kwargs) == (x + I)**2*(x - I)**2 - 1
|
| 61 |
+
assert use(f, factor, level=2, kwargs=kwargs) == (x + I)**2*(x - I)**2 - 1
|
| 62 |
+
assert use(f, factor, level=3, kwargs=kwargs) == (x**2 + 1)**2 - 1
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def test_postorder_traversal():
|
| 66 |
+
x, y, z, w = symbols('x y z w')
|
| 67 |
+
expr = z + w*(x + y)
|
| 68 |
+
expected = [z, w, x, y, x + y, w*(x + y), w*(x + y) + z]
|
| 69 |
+
assert list(postorder_traversal(expr, keys=default_sort_key)) == expected
|
| 70 |
+
assert list(postorder_traversal(expr, keys=True)) == expected
|
| 71 |
+
|
| 72 |
+
expr = Piecewise((x, x < 1), (x**2, True))
|
| 73 |
+
expected = [
|
| 74 |
+
x, 1, x, x < 1, ExprCondPair(x, x < 1),
|
| 75 |
+
2, x, x**2, S.true,
|
| 76 |
+
ExprCondPair(x**2, True), Piecewise((x, x < 1), (x**2, True))
|
| 77 |
+
]
|
| 78 |
+
assert list(postorder_traversal(expr, keys=default_sort_key)) == expected
|
| 79 |
+
assert list(postorder_traversal(
|
| 80 |
+
[expr], keys=default_sort_key)) == expected + [[expr]]
|
| 81 |
+
|
| 82 |
+
assert list(postorder_traversal(Integral(x**2, (x, 0, 1)),
|
| 83 |
+
keys=default_sort_key)) == [
|
| 84 |
+
2, x, x**2, 0, 1, x, Tuple(x, 0, 1),
|
| 85 |
+
Integral(x**2, Tuple(x, 0, 1))
|
| 86 |
+
]
|
| 87 |
+
assert list(postorder_traversal(('abc', ('d', 'ef')))) == [
|
| 88 |
+
'abc', 'd', 'ef', ('d', 'ef'), ('abc', ('d', 'ef'))]
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def test_iterargs():
|
| 92 |
+
f = Function('f')
|
| 93 |
+
x = symbols('x')
|
| 94 |
+
assert list(iterfreeargs(Integral(f(x), (f(x), 1)))) == [
|
| 95 |
+
Integral(f(x), (f(x), 1)), 1]
|
| 96 |
+
assert list(iterargs(Integral(f(x), (f(x), 1)))) == [
|
| 97 |
+
Integral(f(x), (f(x), 1)), f(x), (f(x), 1), x, f(x), 1, x]
|
| 98 |
+
|
| 99 |
+
def test_deprecated_imports():
|
| 100 |
+
x = symbols('x')
|
| 101 |
+
|
| 102 |
+
with warns_deprecated_sympy():
|
| 103 |
+
from sympy.core.basic import preorder_traversal
|
| 104 |
+
preorder_traversal(x)
|
| 105 |
+
with warns_deprecated_sympy():
|
| 106 |
+
from sympy.simplify.simplify import bottom_up
|
| 107 |
+
bottom_up(x, lambda x: x)
|
| 108 |
+
with warns_deprecated_sympy():
|
| 109 |
+
from sympy.simplify.simplify import walk
|
| 110 |
+
walk(x, lambda x: x)
|
| 111 |
+
with warns_deprecated_sympy():
|
| 112 |
+
from sympy.simplify.traversaltools import use
|
| 113 |
+
use(x, lambda x: x)
|
| 114 |
+
with warns_deprecated_sympy():
|
| 115 |
+
from sympy.utilities.iterables import postorder_traversal
|
| 116 |
+
postorder_traversal(x)
|
| 117 |
+
with warns_deprecated_sympy():
|
| 118 |
+
from sympy.utilities.iterables import interactive_traversal
|
| 119 |
+
capture(lambda: interactive_traversal(x))
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_truediv.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#this module tests that SymPy works with true division turned on
|
| 2 |
+
|
| 3 |
+
from sympy.core.numbers import (Float, Rational)
|
| 4 |
+
from sympy.core.symbol import Symbol
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def test_truediv():
|
| 8 |
+
assert 1/2 != 0
|
| 9 |
+
assert Rational(1)/2 != 0
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def dotest(s):
|
| 13 |
+
x = Symbol("x")
|
| 14 |
+
y = Symbol("y")
|
| 15 |
+
l = [
|
| 16 |
+
Rational(2),
|
| 17 |
+
Float("1.3"),
|
| 18 |
+
x,
|
| 19 |
+
y,
|
| 20 |
+
pow(x, y)*y,
|
| 21 |
+
5,
|
| 22 |
+
5.5
|
| 23 |
+
]
|
| 24 |
+
for x in l:
|
| 25 |
+
for y in l:
|
| 26 |
+
s(x, y)
|
| 27 |
+
return True
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def test_basic():
|
| 31 |
+
def s(a, b):
|
| 32 |
+
x = a
|
| 33 |
+
x = +a
|
| 34 |
+
x = -a
|
| 35 |
+
x = a + b
|
| 36 |
+
x = a - b
|
| 37 |
+
x = a*b
|
| 38 |
+
x = a/b
|
| 39 |
+
x = a**b
|
| 40 |
+
del x
|
| 41 |
+
assert dotest(s)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def test_ibasic():
|
| 45 |
+
def s(a, b):
|
| 46 |
+
x = a
|
| 47 |
+
x += b
|
| 48 |
+
x = a
|
| 49 |
+
x -= b
|
| 50 |
+
x = a
|
| 51 |
+
x *= b
|
| 52 |
+
x = a
|
| 53 |
+
x /= b
|
| 54 |
+
assert dotest(s)
|
.venv/lib/python3.13/site-packages/sympy/core/tests/test_var.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.function import (Function, FunctionClass)
|
| 2 |
+
from sympy.core.symbol import (Symbol, var)
|
| 3 |
+
from sympy.testing.pytest import raises
|
| 4 |
+
|
| 5 |
+
def test_var():
|
| 6 |
+
ns = {"var": var, "raises": raises}
|
| 7 |
+
eval("var('a')", ns)
|
| 8 |
+
assert ns["a"] == Symbol("a")
|
| 9 |
+
|
| 10 |
+
eval("var('b bb cc zz _x')", ns)
|
| 11 |
+
assert ns["b"] == Symbol("b")
|
| 12 |
+
assert ns["bb"] == Symbol("bb")
|
| 13 |
+
assert ns["cc"] == Symbol("cc")
|
| 14 |
+
assert ns["zz"] == Symbol("zz")
|
| 15 |
+
assert ns["_x"] == Symbol("_x")
|
| 16 |
+
|
| 17 |
+
v = eval("var(['d', 'e', 'fg'])", ns)
|
| 18 |
+
assert ns['d'] == Symbol('d')
|
| 19 |
+
assert ns['e'] == Symbol('e')
|
| 20 |
+
assert ns['fg'] == Symbol('fg')
|
| 21 |
+
|
| 22 |
+
# check return value
|
| 23 |
+
assert v != ['d', 'e', 'fg']
|
| 24 |
+
assert v == [Symbol('d'), Symbol('e'), Symbol('fg')]
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def test_var_return():
|
| 28 |
+
ns = {"var": var, "raises": raises}
|
| 29 |
+
"raises(ValueError, lambda: var(''))"
|
| 30 |
+
v2 = eval("var('q')", ns)
|
| 31 |
+
v3 = eval("var('q p')", ns)
|
| 32 |
+
|
| 33 |
+
assert v2 == Symbol('q')
|
| 34 |
+
assert v3 == (Symbol('q'), Symbol('p'))
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def test_var_accepts_comma():
|
| 38 |
+
ns = {"var": var}
|
| 39 |
+
v1 = eval("var('x y z')", ns)
|
| 40 |
+
v2 = eval("var('x,y,z')", ns)
|
| 41 |
+
v3 = eval("var('x,y z')", ns)
|
| 42 |
+
|
| 43 |
+
assert v1 == v2
|
| 44 |
+
assert v1 == v3
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def test_var_keywords():
|
| 48 |
+
ns = {"var": var}
|
| 49 |
+
eval("var('x y', real=True)", ns)
|
| 50 |
+
assert ns['x'].is_real and ns['y'].is_real
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def test_var_cls():
|
| 54 |
+
ns = {"var": var, "Function": Function}
|
| 55 |
+
eval("var('f', cls=Function)", ns)
|
| 56 |
+
|
| 57 |
+
assert isinstance(ns['f'], FunctionClass)
|
| 58 |
+
|
| 59 |
+
eval("var('g,h', cls=Function)", ns)
|
| 60 |
+
|
| 61 |
+
assert isinstance(ns['g'], FunctionClass)
|
| 62 |
+
assert isinstance(ns['h'], FunctionClass)
|
video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000171.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"frame_idx": 171,
|
| 3 |
+
"image_key": "video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotated.mp4",
|
| 4 |
+
"annotations": []
|
| 5 |
+
}
|
video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000201.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"frame_idx": 201,
|
| 3 |
+
"image_key": "video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotated.mp4",
|
| 4 |
+
"annotations": []
|
| 5 |
+
}
|
video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000331.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"frame_idx": 331,
|
| 3 |
+
"image_key": "video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotated.mp4",
|
| 4 |
+
"annotations": []
|
| 5 |
+
}
|
video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000371.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"frame_idx": 371,
|
| 3 |
+
"image_key": "video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotated.mp4",
|
| 4 |
+
"annotations": []
|
| 5 |
+
}
|
video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000521.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"frame_idx": 521,
|
| 3 |
+
"image_key": "video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotated.mp4",
|
| 4 |
+
"annotations": []
|
| 5 |
+
}
|
video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000581.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"frame_idx": 581,
|
| 3 |
+
"image_key": "video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotated.mp4",
|
| 4 |
+
"annotations": []
|
| 5 |
+
}
|
video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000651.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"frame_idx": 651,
|
| 3 |
+
"image_key": "video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotated.mp4",
|
| 4 |
+
"annotations": []
|
| 5 |
+
}
|
video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000721.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"frame_idx": 721,
|
| 3 |
+
"image_key": "video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotated.mp4",
|
| 4 |
+
"annotations": []
|
| 5 |
+
}
|
video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000761.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"frame_idx": 761,
|
| 3 |
+
"image_key": "video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotated.mp4",
|
| 4 |
+
"annotations": []
|
| 5 |
+
}
|
video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotations/000921.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"frame_idx": 921,
|
| 3 |
+
"image_key": "video/video_2026-02-18T12-43-09Z/packhouse1_inline3/annotated.mp4",
|
| 4 |
+
"annotations": []
|
| 5 |
+
}
|