![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /usr/local/lib/python3.6/dist-packages/sympy/polys/agca/ |
Upload File : |
"""Finite extensions of ring domains.""" from sympy.polys.polyerrors import CoercionFailed, NotInvertible from sympy.polys.polytools import Poly from sympy.printing.defaults import DefaultPrinting class ExtensionElement(DefaultPrinting): """ Element of a finite extension. A class of univariate polynomials modulo the ``modulus`` of the extension ``ext``. It is represented by the unique polynomial ``rep`` of lowest degree. Both ``rep`` and the representation ``mod`` of ``modulus`` are of class DMP. """ __slots__ = ('rep', 'ext') def __init__(self, rep, ext): self.rep = rep self.ext = ext def __neg__(f): return ExtElem(-f.rep, f.ext) def _get_rep(f, g): if isinstance(g, ExtElem): if g.ext == f.ext: return g.rep else: return None else: try: g = f.ext.convert(g) return g.rep except CoercionFailed: return None def __add__(f, g): rep = f._get_rep(g) if rep is not None: return ExtElem(f.rep + rep, f.ext) else: return NotImplemented __radd__ = __add__ def __sub__(f, g): rep = f._get_rep(g) if rep is not None: return ExtElem(f.rep - rep, f.ext) else: return NotImplemented def __rsub__(f, g): rep = f._get_rep(g) if rep is not None: return ExtElem(rep - f.rep, f.ext) else: return NotImplemented def __mul__(f, g): rep = f._get_rep(g) if rep is not None: return ExtElem((f.rep*rep) % f.ext.mod, f.ext) else: return NotImplemented __rmul__ = __mul__ def inverse(f): """Multiplicative inverse. Raises ====== NotInvertible If the element is a zero divisor. """ if not f.ext.domain.is_Field: raise NotImplementedError("base field expected") return ExtElem(f.rep.invert(f.ext.mod), f.ext) def _invrep(f, g): rep = f._get_rep(g) if rep is not None: return rep.invert(f.ext.mod) else: return None def __truediv__(f, g): if not f.ext.domain.is_Field: return NotImplemented try: rep = f._invrep(g) except NotInvertible: raise ZeroDivisionError if rep is not None: return f*ExtElem(rep, f.ext) else: return NotImplemented __floordiv__ = __truediv__ def __rtruediv__(f, g): try: return f.ext.convert(g)/f except CoercionFailed: return NotImplemented __rfloordiv__ = __rtruediv__ def __pow__(f, n): if not isinstance(n, int): raise TypeError("exponent of type 'int' expected") if n < 0: try: f, n = f.inverse(), -n except NotImplementedError: raise ValueError("negative powers are not defined") b = f.rep m = f.ext.mod r = f.ext.one.rep while n > 0: if n % 2: r = (r*b) % m b = (b*b) % m n //= 2 return ExtElem(r, f.ext) def __eq__(f, g): if isinstance(g, ExtElem): return f.rep == g.rep and f.ext == g.ext else: return NotImplemented def __ne__(f, g): return not f == g def __hash__(f): return hash((f.rep, f.ext)) def __str__(f): from sympy.printing.str import sstr return sstr(f.rep) __repr__ = __str__ ExtElem = ExtensionElement class MonogenicFiniteExtension: r""" Finite extension generated by an integral element. The generator is defined by a monic univariate polynomial derived from the argument ``mod``. A shorter alias is ``FiniteExtension``. Examples ======== Quadratic integer ring $\mathbb{Z}[\sqrt2]$: >>> from sympy import Symbol, Poly >>> from sympy.polys.agca.extensions import FiniteExtension >>> x = Symbol('x') >>> R = FiniteExtension(Poly(x**2 - 2)); R ZZ[x]/(x**2 - 2) >>> R.rank 2 >>> R(1 + x)*(3 - 2*x) x - 1 Finite field $GF(5^3)$ defined by the primitive polynomial $x^3 + x^2 + 2$ (over $\mathbb{Z}_5$). >>> F = FiniteExtension(Poly(x**3 + x**2 + 2, modulus=5)); F GF(5)[x]/(x**3 + x**2 + 2) >>> F.basis (1, x, x**2) >>> F(x + 3)/(x**2 + 2) -2*x**2 + x + 2 Function field of an elliptic curve: >>> t = Symbol('t') >>> FiniteExtension(Poly(t**2 - x**3 - x + 1, t, field=True)) ZZ(x)[t]/(t**2 - x**3 - x + 1) Notes ===== ``FiniteExtension`` is not a subclass of :class:`~.Domain`. Consequently, a ``FiniteExtension`` can't currently be used as ``domain`` for the :class:`~.Poly` class. """ def __init__(self, mod): if not (isinstance(mod, Poly) and mod.is_univariate): raise TypeError("modulus must be a univariate Poly") mod, rem = mod.div(mod.LC()) if not rem.is_zero: raise ValueError("modulus could not be made monic") self.rank = mod.degree() self.modulus = mod self.mod = mod.rep # DMP representation self.domain = dom = mod.domain self.ring = mod.rep.ring or dom.old_poly_ring(*mod.gens) self.zero = self.convert(self.ring.zero) self.one = self.convert(self.ring.one) gen = self.ring.gens[0] self.generator = self.convert(gen) self.basis = tuple(self.convert(gen**i) for i in range(self.rank)) def convert(self, f): rep = self.ring.convert(f) return ExtElem(rep % self.mod, self) __call__ = convert def __str__(self): return "%s/(%s)" % (self.ring, self.modulus.as_expr()) __repr__ = __str__ FiniteExtension = MonogenicFiniteExtension