/
integerring.py
142 lines (105 loc) · 3.83 KB
/
integerring.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
"""Implementation of :class:`IntegerRing` class."""
import abc
from ..polys.polyerrors import CoercionFailed
from .characteristiczero import CharacteristicZero
from .groundtypes import (DiofantInteger, GMPYInteger, PythonInteger,
gmpy_factorial, gmpy_gcd, gmpy_gcdex, gmpy_sqrt,
python_factorial, python_gcd, python_gcdex,
python_sqrt)
from .ring import CommutativeRing
from .simpledomain import SimpleDomain
class IntegerRing(CharacteristicZero, SimpleDomain, CommutativeRing):
"""General class for integer rings."""
rep = 'ZZ'
is_IntegerRing = True
is_Numerical = True
has_assoc_Ring = True
@property
def field(self):
"""Returns a field associated with ``self``."""
from . import QQ
return QQ
def to_expr(self, element):
return DiofantInteger(element)
def from_expr(self, expr):
if expr.is_Integer:
return self.dtype(expr.numerator)
elif expr.is_Float and int(expr) == expr:
return self.dtype(expr)
else:
raise CoercionFailed(f'expected an integer, got {expr}')
def _from_PythonIntegerRing(self, a, K0):
return self.dtype(a)
_from_GMPYIntegerRing = _from_PythonIntegerRing
_from_PythonFiniteField = _from_PythonIntegerRing
_from_GMPYFiniteField = _from_PythonIntegerRing
_from_GMPYIntegerModRing = _from_PythonIntegerRing
_from_PythonIntegerModRing = _from_PythonIntegerRing
def _from_PythonRationalField(self, a, K0):
if a.denominator == 1:
return self.dtype(a.numerator)
_from_GMPYRationalField = _from_PythonRationalField
def _from_RealField(self, a, K0):
p, q = K0.to_rational(a)
if q == 1:
return self.dtype(p)
def _from_AlgebraicField(self, a, K0):
if a.is_ground:
return self.convert(a.rep.LC, K0.domain)
@abc.abstractmethod
def finite_field(self, p):
"""Returns a finite field."""
raise NotImplementedError
@abc.abstractmethod
def finite_ring(self, n):
"""Returns a finite ring."""
raise NotImplementedError
class PythonIntegerRing(IntegerRing):
"""Integer ring based on Python's integers."""
dtype = PythonInteger
zero = dtype(0)
one = dtype(1)
def gcdex(self, a, b):
"""Compute extended GCD of ``a`` and ``b``."""
return python_gcdex(a, b)
def gcd(self, a, b):
"""Compute GCD of ``a`` and ``b``."""
return python_gcd(a, b)
def sqrt(self, a):
"""Compute square root of ``a``."""
return python_sqrt(a)
def factorial(self, a):
"""Compute factorial of ``a``."""
return python_factorial(a)
def finite_field(self, p):
from .finitefield import PythonFiniteField
return PythonFiniteField(p)
def finite_ring(self, n):
from .finitefield import PythonIntegerModRing
return PythonIntegerModRing(n)
class GMPYIntegerRing(IntegerRing):
"""Integer ring based on GMPY's integers."""
dtype = GMPYInteger
zero = dtype(0)
one = dtype(1)
def gcdex(self, a, b):
"""Compute extended GCD of ``a`` and ``b``."""
h, s, t = gmpy_gcdex(a, b)
return s, t, h
def gcd(self, a, b):
"""Compute GCD of ``a`` and ``b``."""
return gmpy_gcd(a, b)
def sqrt(self, a):
"""Compute square root of ``a``."""
return gmpy_sqrt(a)
def factorial(self, a):
"""Compute factorial of ``a``."""
return gmpy_factorial(a)
def finite_field(self, p):
from .finitefield import GMPYFiniteField
return GMPYFiniteField(p)
def finite_ring(self, n):
from .finitefield import GMPYIntegerModRing
return GMPYIntegerModRing(n)
ZZ_python = PythonIntegerRing()
ZZ_gmpy = GMPYIntegerRing()