1from sympy.core import Symbol, S, oo
2from sympy.functions.elementary.miscellaneous import sqrt
3from sympy.polys import poly
4from sympy.polys.dispersion import dispersion, dispersionset
5
6
7def test_dispersion():
8    x = Symbol("x")
9    a = Symbol("a")
10
11    fp = poly(S.Zero, x)
12    assert sorted(dispersionset(fp)) == [0]
13
14    fp = poly(S(2), x)
15    assert sorted(dispersionset(fp)) == [0]
16
17    fp = poly(x + 1, x)
18    assert sorted(dispersionset(fp)) == [0]
19    assert dispersion(fp) == 0
20
21    fp = poly((x + 1)*(x + 2), x)
22    assert sorted(dispersionset(fp)) == [0, 1]
23    assert dispersion(fp) == 1
24
25    fp = poly(x*(x + 3), x)
26    assert sorted(dispersionset(fp)) == [0, 3]
27    assert dispersion(fp) == 3
28
29    fp = poly((x - 3)*(x + 3), x)
30    assert sorted(dispersionset(fp)) == [0, 6]
31    assert dispersion(fp) == 6
32
33    fp = poly(x**4 - 3*x**2 + 1, x)
34    gp = fp.shift(-3)
35    assert sorted(dispersionset(fp, gp)) == [2, 3, 4]
36    assert dispersion(fp, gp) == 4
37    assert sorted(dispersionset(gp, fp)) == []
38    assert dispersion(gp, fp) is -oo
39
40    fp = poly(x*(3*x**2+a)*(x-2536)*(x**3+a), x)
41    gp = fp.as_expr().subs(x, x-345).as_poly(x)
42    assert sorted(dispersionset(fp, gp)) == [345, 2881]
43    assert sorted(dispersionset(gp, fp)) == [2191]
44
45    gp = poly((x-2)**2*(x-3)**3*(x-5)**3, x)
46    assert sorted(dispersionset(gp)) == [0, 1, 2, 3]
47    assert sorted(dispersionset(gp, (gp+4)**2)) == [1, 2]
48
49    fp = poly(x*(x+2)*(x-1), x)
50    assert sorted(dispersionset(fp)) == [0, 1, 2, 3]
51
52    fp = poly(x**2 + sqrt(5)*x - 1, x, domain='QQ<sqrt(5)>')
53    gp = poly(x**2 + (2 + sqrt(5))*x + sqrt(5), x, domain='QQ<sqrt(5)>')
54    assert sorted(dispersionset(fp, gp)) == [2]
55    assert sorted(dispersionset(gp, fp)) == [1, 4]
56
57    # There are some difficulties if we compute over Z[a]
58    # and alpha happenes to lie in Z[a] instead of simply Z.
59    # Hence we can not decide if alpha is indeed integral
60    # in general.
61
62    fp = poly(4*x**4 + (4*a + 8)*x**3 + (a**2 + 6*a + 4)*x**2 + (a**2 + 2*a)*x, x)
63    assert sorted(dispersionset(fp)) == [0, 1]
64
65    # For any specific value of a, the dispersion is 3*a
66    # but the algorithm can not find this in general.
67    # This is the point where the resultant based Ansatz
68    # is superior to the current one.
69    fp = poly(a**2*x**3 + (a**3 + a**2 + a + 1)*x, x)
70    gp = fp.as_expr().subs(x, x - 3*a).as_poly(x)
71    assert sorted(dispersionset(fp, gp)) == []
72
73    fpa = fp.as_expr().subs(a, 2).as_poly(x)
74    gpa = gp.as_expr().subs(a, 2).as_poly(x)
75    assert sorted(dispersionset(fpa, gpa)) == [6]
76
77    # Work with Expr instead of Poly
78    f = (x + 1)*(x + 2)
79    assert sorted(dispersionset(f)) == [0, 1]
80    assert dispersion(f) == 1
81
82    f = x**4 - 3*x**2 + 1
83    g = x**4 - 12*x**3 + 51*x**2 - 90*x + 55
84    assert sorted(dispersionset(f, g)) == [2, 3, 4]
85    assert dispersion(f, g) == 4
86
87    # Work with Expr and specify a generator
88    f = (x + 1)*(x + 2)
89    assert sorted(dispersionset(f, None, x)) == [0, 1]
90    assert dispersion(f, None, x) == 1
91
92    f = x**4 - 3*x**2 + 1
93    g = x**4 - 12*x**3 + 51*x**2 - 90*x + 55
94    assert sorted(dispersionset(f, g, x)) == [2, 3, 4]
95    assert dispersion(f, g, x) == 4
96