123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- from sympy.core.symbol import symbols
- from sympy.functions.elementary.trigonometric import (cos, sin)
- from sympy.polys import QQ, ZZ
- from sympy.polys.polytools import Poly
- from sympy.polys.polyerrors import NotInvertible
- from sympy.polys.agca.extensions import FiniteExtension
- from sympy.polys.domainmatrix import DomainMatrix
- from sympy.testing.pytest import raises
- from sympy.abc import x, y, t
- def test_FiniteExtension():
- # Gaussian integers
- A = FiniteExtension(Poly(x**2 + 1, x))
- assert A.rank == 2
- assert str(A) == 'ZZ[x]/(x**2 + 1)'
- i = A.generator
- assert i.parent() is A
- assert i*i == A(-1)
- raises(TypeError, lambda: i*())
- assert A.basis == (A.one, i)
- assert A(1) == A.one
- assert i**2 == A(-1)
- assert i**2 != -1 # no coercion
- assert (2 + i)*(1 - i) == 3 - i
- assert (1 + i)**8 == A(16)
- assert A(1).inverse() == A(1)
- raises(NotImplementedError, lambda: A(2).inverse())
- # Finite field of order 27
- F = FiniteExtension(Poly(x**3 - x + 1, x, modulus=3))
- assert F.rank == 3
- a = F.generator # also generates the cyclic group F - {0}
- assert F.basis == (F(1), a, a**2)
- assert a**27 == a
- assert a**26 == F(1)
- assert a**13 == F(-1)
- assert a**9 == a + 1
- assert a**3 == a - 1
- assert a**6 == a**2 + a + 1
- assert F(x**2 + x).inverse() == 1 - a
- assert F(x + 2)**(-1) == F(x + 2).inverse()
- assert a**19 * a**(-19) == F(1)
- assert (a - 1) / (2*a**2 - 1) == a**2 + 1
- assert (a - 1) // (2*a**2 - 1) == a**2 + 1
- assert 2/(a**2 + 1) == a**2 - a + 1
- assert (a**2 + 1)/2 == -a**2 - 1
- raises(NotInvertible, lambda: F(0).inverse())
- # Function field of an elliptic curve
- K = FiniteExtension(Poly(t**2 - x**3 - x + 1, t, field=True))
- assert K.rank == 2
- assert str(K) == 'ZZ(x)[t]/(t**2 - x**3 - x + 1)'
- y = K.generator
- c = 1/(x**3 - x**2 + x - 1)
- assert ((y + x)*(y - x)).inverse() == K(c)
- assert (y + x)*(y - x)*c == K(1) # explicit inverse of y + x
- def test_FiniteExtension_eq_hash():
- # Test eq and hash
- p1 = Poly(x**2 - 2, x, domain=ZZ)
- p2 = Poly(x**2 - 2, x, domain=QQ)
- K1 = FiniteExtension(p1)
- K2 = FiniteExtension(p2)
- assert K1 == FiniteExtension(Poly(x**2 - 2))
- assert K2 != FiniteExtension(Poly(x**2 - 2))
- assert len({K1, K2, FiniteExtension(p1)}) == 2
- def test_FiniteExtension_mod():
- # Test mod
- K = FiniteExtension(Poly(x**3 + 1, x, domain=QQ))
- xf = K(x)
- assert (xf**2 - 1) % 1 == K.zero
- assert 1 % (xf**2 - 1) == K.zero
- assert (xf**2 - 1) / (xf - 1) == xf + 1
- assert (xf**2 - 1) // (xf - 1) == xf + 1
- assert (xf**2 - 1) % (xf - 1) == K.zero
- raises(ZeroDivisionError, lambda: (xf**2 - 1) % 0)
- raises(TypeError, lambda: xf % [])
- raises(TypeError, lambda: [] % xf)
- # Test mod over ring
- K = FiniteExtension(Poly(x**3 + 1, x, domain=ZZ))
- xf = K(x)
- assert (xf**2 - 1) % 1 == K.zero
- raises(NotImplementedError, lambda: (xf**2 - 1) % (xf - 1))
- def test_FiniteExtension_from_sympy():
- # Test to_sympy/from_sympy
- K = FiniteExtension(Poly(x**3 + 1, x, domain=ZZ))
- xf = K(x)
- assert K.from_sympy(x) == xf
- assert K.to_sympy(xf) == x
- def test_FiniteExtension_set_domain():
- KZ = FiniteExtension(Poly(x**2 + 1, x, domain='ZZ'))
- KQ = FiniteExtension(Poly(x**2 + 1, x, domain='QQ'))
- assert KZ.set_domain(QQ) == KQ
- def test_FiniteExtension_exquo():
- # Test exquo
- K = FiniteExtension(Poly(x**4 + 1))
- xf = K(x)
- assert K.exquo(xf**2 - 1, xf - 1) == xf + 1
- def test_FiniteExtension_convert():
- # Test from_MonogenicFiniteExtension
- K1 = FiniteExtension(Poly(x**2 + 1))
- K2 = QQ[x]
- x1, x2 = K1(x), K2(x)
- assert K1.convert(x2) == x1
- assert K2.convert(x1) == x2
- K = FiniteExtension(Poly(x**2 - 1, domain=QQ))
- assert K.convert_from(QQ(1, 2), QQ) == K.one/2
- def test_FiniteExtension_division_ring():
- # Test division in FiniteExtension over a ring
- KQ = FiniteExtension(Poly(x**2 - 1, x, domain=QQ))
- KZ = FiniteExtension(Poly(x**2 - 1, x, domain=ZZ))
- KQt = FiniteExtension(Poly(x**2 - 1, x, domain=QQ[t]))
- KQtf = FiniteExtension(Poly(x**2 - 1, x, domain=QQ.frac_field(t)))
- assert KQ.is_Field is True
- assert KZ.is_Field is False
- assert KQt.is_Field is False
- assert KQtf.is_Field is True
- for K in KQ, KZ, KQt, KQtf:
- xK = K.convert(x)
- assert xK / K.one == xK
- assert xK // K.one == xK
- assert xK % K.one == K.zero
- raises(ZeroDivisionError, lambda: xK / K.zero)
- raises(ZeroDivisionError, lambda: xK // K.zero)
- raises(ZeroDivisionError, lambda: xK % K.zero)
- if K.is_Field:
- assert xK / xK == K.one
- assert xK // xK == K.one
- assert xK % xK == K.zero
- else:
- raises(NotImplementedError, lambda: xK / xK)
- raises(NotImplementedError, lambda: xK // xK)
- raises(NotImplementedError, lambda: xK % xK)
- def test_FiniteExtension_Poly():
- K = FiniteExtension(Poly(x**2 - 2))
- p = Poly(x, y, domain=K)
- assert p.domain == K
- assert p.as_expr() == x
- assert (p**2).as_expr() == 2
- K = FiniteExtension(Poly(x**2 - 2, x, domain=QQ))
- K2 = FiniteExtension(Poly(t**2 - 2, t, domain=K))
- assert str(K2) == 'QQ[x]/(x**2 - 2)[t]/(t**2 - 2)'
- eK = K2.convert(x + t)
- assert K2.to_sympy(eK) == x + t
- assert K2.to_sympy(eK ** 2) == 4 + 2*x*t
- p = Poly(x + t, y, domain=K2)
- assert p**2 == Poly(4 + 2*x*t, y, domain=K2)
- def test_FiniteExtension_sincos_jacobian():
- # Use FiniteExtensino to compute the Jacobian of a matrix involving sin
- # and cos of different symbols.
- r, p, t = symbols('rho, phi, theta')
- elements = [
- [sin(p)*cos(t), r*cos(p)*cos(t), -r*sin(p)*sin(t)],
- [sin(p)*sin(t), r*cos(p)*sin(t), r*sin(p)*cos(t)],
- [ cos(p), -r*sin(p), 0],
- ]
- def make_extension(K):
- K = FiniteExtension(Poly(sin(p)**2+cos(p)**2-1, sin(p), domain=K[cos(p)]))
- K = FiniteExtension(Poly(sin(t)**2+cos(t)**2-1, sin(t), domain=K[cos(t)]))
- return K
- Ksc1 = make_extension(ZZ[r])
- Ksc2 = make_extension(ZZ)[r]
- for K in [Ksc1, Ksc2]:
- elements_K = [[K.convert(e) for e in row] for row in elements]
- J = DomainMatrix(elements_K, (3, 3), K)
- det = J.charpoly()[-1] * (-K.one)**3
- assert det == K.convert(r**2*sin(p))
|