Ticket #14832: trac_14832_make_irreducible_polynomial.patch
File trac_14832_make_irreducible_polynomial.patch, 10.0 KB (added by , 10 years ago) |
---|
-
sage/rings/polynomial/polynomial_gf2x.pyx
# HG changeset patch # User Peter Bruin <peter.bruin@math.uzh.ch> # Date 1372186250 -7200 # Node ID 15c4954a1e738ebc79f550edab54282af3f50fa0 # Parent 739c6c4c4f751f2fe95f291c9b4e75cd7e51e4c2 Trac 14832: construct irreducible polynomials over finite fields diff --git a/sage/rings/polynomial/polynomial_gf2x.pyx b/sage/rings/polynomial/polynomial_gf2x.pyx
a b 276 276 return False 277 277 else: 278 278 return True 279 280 281 # The three functions below are used in polynomial_ring.py, but are in 282 # this Cython file since they call C++ functions. They return 283 # polynomials as lists so that no variable has to be specified. 284 # AUTHOR: Peter Bruin (June 2013) 285 286 def GF2X_BuildIrred_list(n): 287 """ 288 Return the list of coefficients of the lexicographically smallest 289 irreducible polynomial of degree `n` over the field of 2 elements. 290 291 EXAMPLE: 292 293 sage: from sage.rings.polynomial.polynomial_gf2x import GF2X_BuildIrred_list 294 sage: GF2X_BuildIrred_list(2) 295 [1, 1, 1] 296 sage: GF2X_BuildIrred_list(3) 297 [1, 1, 0, 1] 298 sage: GF2X_BuildIrred_list(4) 299 [1, 1, 0, 0, 1] 300 sage: GF(2)['x'](GF2X_BuildIrred_list(33)) 301 x^33 + x^6 + x^3 + x + 1 302 """ 303 from sage.rings.finite_rings.constructor import FiniteField 304 cdef GF2X_c f 305 GF2 = FiniteField(2) 306 GF2X_BuildIrred(f, int(n)) 307 return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in xrange(n + 1)] 308 309 def GF2X_BuildSparseIrred_list(n): 310 """ 311 Return the list of coefficients of an irreducible polynomial of 312 degree `n` of minimal weight over the field of 2 elements. 313 314 EXAMPLE: 315 316 sage: from sage.rings.polynomial.polynomial_gf2x import GF2X_BuildIrred_list, GF2X_BuildSparseIrred_list 317 sage: all([GF2X_BuildSparseIrred_list(n) == GF2X_BuildIrred_list(n) 318 ....: for n in range(1,33)]) 319 True 320 sage: GF(2)['x'](GF2X_BuildSparseIrred_list(33)) 321 x^33 + x^10 + 1 322 """ 323 from sage.rings.finite_rings.constructor import FiniteField 324 cdef GF2X_c f 325 GF2 = FiniteField(2) 326 GF2X_BuildSparseIrred(f, int(n)) 327 return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in xrange(n + 1)] 328 329 def GF2X_BuildRandomIrred_list(n): 330 """ 331 Return the list of coefficients of an irreducible polynomial of 332 degree `n` of minimal weight over the field of 2 elements. 333 334 EXAMPLE: 335 336 sage: from sage.rings.polynomial.polynomial_gf2x import GF2X_BuildRandomIrred_list 337 sage: GF2X_BuildRandomIrred_list(2) 338 [1, 1, 1] 339 sage: GF2X_BuildRandomIrred_list(3) in [[1, 1, 0, 1], [1, 0, 1, 1]] 340 True 341 """ 342 from sage.misc.randstate import current_randstate 343 from sage.rings.finite_rings.constructor import FiniteField 344 cdef GF2X_c tmp, f 345 GF2 = FiniteField(2) 346 current_randstate().set_seed_ntl(False) 347 GF2X_BuildSparseIrred(tmp, int(n)) 348 GF2X_BuildRandomIrred(f, tmp) 349 return [GF2(not GF2_IsZero(GF2X_coeff(f, i))) for i in xrange(n + 1)] -
sage/rings/polynomial/polynomial_ring.py
diff --git a/sage/rings/polynomial/polynomial_ring.py b/sage/rings/polynomial/polynomial_ring.py
a b 1798 1798 self._fraction_field = FractionField_1poly_field(self) 1799 1799 return self._fraction_field 1800 1800 1801 class PolynomialRing_dense_finite_field(PolynomialRing_field): 1802 """ 1803 Univariate polynomial ring over a finite field. 1804 """ 1805 def irreducible_element(self, n, algorithm=None): 1806 """ 1807 Construct an irreducible polynomial of degree `n`. 1808 1809 INPUT: 1810 1811 - ``n`` -- integer: degree of the polynomial to construct 1812 1813 - ``algorithm`` -- string: algorithm to use, or ``None`` 1814 1815 - ``'random'``: try random polynomials until an irreducible 1816 one is found. This is currently the only algorithm 1817 available over non-prime finite fields. 1818 1819 OUTPUT: 1820 1821 A monic irreducible polynomial of degree `n` in ``self``. 1822 1823 EXAMPLES: 1824 1825 sage: GF(5^3, 'a')['x'].irreducible_element(2) 1826 x^2 + (4*a^2 + a + 4)*x + 2*a^2 + 2 1827 1828 AUTHOR: 1829 1830 Peter Bruin (June 2013) 1831 """ 1832 if n < 1: 1833 raise ValueError("degree must be at least 1") 1834 1835 if algorithm is None or algorithm == "random": 1836 while True: 1837 f = self.gen()**n + self.random_element(n - 1) 1838 if f.is_irreducible(): 1839 return f 1840 else: 1841 raise ValueError("no such algorithm for finding an irreducible polynomial: %s" % algorithm) 1842 1801 1843 class PolynomialRing_dense_padic_ring_generic(PolynomialRing_integral_domain): 1802 1844 pass 1803 1845 … … 1995 2037 return s + self._implementation_repr 1996 2038 1997 2039 1998 class PolynomialRing_dense_mod_p(PolynomialRing_ field,2040 class PolynomialRing_dense_mod_p(PolynomialRing_dense_finite_field, 1999 2041 PolynomialRing_dense_mod_n, 2000 2042 PolynomialRing_singular_repr): 2001 2043 def __init__(self, base_ring, name="x", implementation=None): … … 2054 2096 from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular 2055 2097 self._has_singular = can_convert_to_singular(self) 2056 2098 2099 def irreducible_element(self, n, algorithm=None): 2100 """ 2101 Construct an irreducible polynomial of degree `n`. 2102 2103 INPUT: 2104 2105 - ``n`` -- integer: the degree of the polynomial to construct 2106 2107 - ``algorithm`` -- string: algorithm to use, or ``None``. 2108 Currently available options are: 2109 2110 - ``'adleman-lenstra'``: a variant of the Adleman--Lenstra 2111 algorithm as implemented in PARI. 2112 2113 - ``'conway'``: look up the Conway polynomial of degree `n` 2114 over the field of `p` elements in the database; raise a 2115 ``RuntimeError`` if it is not found. 2116 2117 - ``'first_lexicographic'``: return the lexicographically 2118 smallest irreducible polynomial of degree `n`. Only 2119 implemented for `p = 2`. 2120 2121 - ``'minimal_weight'``: return an irreducible polynomial of 2122 degree `n` with minimal number of non-zero coefficients. 2123 Only implemented for `p = 2`. 2124 2125 - ``'random'``: try random polynomials until an irreducible 2126 one is found. 2127 2128 If ``algorithm`` is ``None``, the Conway polynomial is used 2129 if it is found in the database. If no Conway polynomial is 2130 found, the algorithm ``minimal_weight`` is used if `p = 2`, 2131 and the algorithm ``adleman-lenstra`` if `p > 2`. 2132 2133 OUTPUT: 2134 2135 A monic irreducible polynomial of degree `n` in ``self``. 2136 2137 EXAMPLES: 2138 2139 sage: GF(5)['x'].irreducible_element(2) 2140 x^2 + 4*x + 2 2141 sage: GF(5)['x'].irreducible_element(2, algorithm="adleman-lenstra") 2142 x^2 + x + 1 2143 2144 sage: GF(2)['x'].irreducible_element(33) 2145 x^33 + x^13 + x^12 + x^11 + x^10 + x^8 + x^6 + x^3 + 1 2146 sage: GF(2)['x'].irreducible_element(33, algorithm="minimal_weight") 2147 x^33 + x^10 + 1 2148 2149 AUTHOR: 2150 2151 Peter Bruin (June 2013) 2152 """ 2153 from sage.libs.pari.all import pari 2154 from sage.rings.finite_rings.constructor import (conway_polynomial, 2155 exists_conway_polynomial) 2156 from polynomial_gf2x import (GF2X_BuildIrred_list, GF2X_BuildSparseIrred_list, 2157 GF2X_BuildRandomIrred_list) 2158 2159 p = self.characteristic() 2160 n = int(n) 2161 if n < 1: 2162 raise ValueError("degree must be at least 1") 2163 if algorithm is None: 2164 if exists_conway_polynomial(p, n): 2165 algorithm = "conway" 2166 elif p == 2: 2167 algorithm = "minimal_weight" 2168 else: 2169 algorithm = "adleman-lenstra" 2170 2171 if algorithm == "adleman-lenstra": 2172 return self(pari(p).ffinit(n)) 2173 elif algorithm == "conway": 2174 return self(conway_polynomial(p, n)) 2175 elif algorithm == "first_lexicographic": 2176 if p == 2: 2177 return self(GF2X_BuildIrred_list(n)) 2178 else: 2179 raise NotImplementedError("'first_lexicographic' option only implemented for p = 2") 2180 elif algorithm == "minimal_weight": 2181 if p == 2: 2182 return self(GF2X_BuildSparseIrred_list(n)) 2183 else: 2184 raise NotImplementedError("'minimal_weight' option only implemented for p = 2") 2185 elif algorithm == "random": 2186 if p == 2: 2187 return self(GF2X_BuildRandomIrred_list(n)) 2188 else: 2189 pass 2190 2191 # No suitable algorithm found, try algorithms from the base class. 2192 return PolynomialRing_dense_finite_field.irreducible_element(self, n, algorithm) 2193 2057 2194 2058 2195 def polygen(ring_or_element, name="x"): 2059 2196 """ -
sage/rings/polynomial/polynomial_ring_constructor.py
diff --git a/sage/rings/polynomial/polynomial_ring_constructor.py b/sage/rings/polynomial/polynomial_ring_constructor.py
a b 40 40 import sage.rings.padics.padic_base_leaves as padic_base_leaves 41 41 42 42 from sage.rings.integer import Integer 43 from sage.rings.finite_rings.constructor import is_FiniteField 43 44 from sage.rings.finite_rings.integer_mod_ring import is_IntegerModRing 44 45 45 46 from sage.misc.cachefunc import weak_cached_function … … 533 534 else: # n == 1! 534 535 R = m.PolynomialRing_integral_domain(base_ring, name) # specialized code breaks in this case. 535 536 537 elif is_FiniteField(base_ring) and not sparse: 538 R = m.PolynomialRing_dense_finite_field(base_ring, name) 539 536 540 elif isinstance(base_ring, padic_base_leaves.pAdicFieldCappedRelative): 537 541 R = m.PolynomialRing_dense_padic_field_capped_relative(base_ring, name) 538 542