| 1814 | def irreducible_element(self, n, algorithm=None): |
| 1815 | """ |
| 1816 | Construct an irreducible polynomial of degree `n`. |
| 1817 | |
| 1818 | INPUT: |
| 1819 | |
| 1820 | - ``n`` -- integer: degree of the polynomial to construct |
| 1821 | |
| 1822 | - ``algorithm`` -- string: algorithm to use, or ``None`` |
| 1823 | |
| 1824 | - ``'random'``: try random polynomials until an irreducible |
| 1825 | one is found. This is currently the only algorithm |
| 1826 | available over non-prime finite fields. |
| 1827 | |
| 1828 | OUTPUT: |
| 1829 | |
| 1830 | A monic irreducible polynomial of degree `n` in ``self``. |
| 1831 | |
| 1832 | EXAMPLES: |
| 1833 | |
| 1834 | sage: GF(5^3, 'a')['x'].irreducible_element(2) |
| 1835 | x^2 + (4*a^2 + a + 4)*x + 2*a^2 + 2 |
| 1836 | |
| 1837 | AUTHORS: |
| 1838 | |
| 1839 | - Peter Bruin (June 2013) |
| 1840 | """ |
| 1841 | if n < 1: |
| 1842 | raise ValueError("degree must be at least 1") |
| 1843 | |
| 1844 | if algorithm is None or algorithm == "random": |
| 1845 | while True: |
| 1846 | f = self.gen()**n + self.random_element(n - 1) |
| 1847 | if f.is_irreducible(): |
| 1848 | return f |
| 1849 | else: |
| 1850 | raise ValueError("no such algorithm for finding an irreducible polynomial: %s" % algorithm) |
| 1851 | |
| 2108 | def irreducible_element(self, n, algorithm=None): |
| 2109 | """ |
| 2110 | Construct an irreducible polynomial of degree `n`. |
| 2111 | |
| 2112 | INPUT: |
| 2113 | |
| 2114 | - ``n`` -- integer: the degree of the polynomial to construct |
| 2115 | |
| 2116 | - ``algorithm`` -- string: algorithm to use, or ``None``. |
| 2117 | Currently available options are: |
| 2118 | |
| 2119 | - ``'adleman-lenstra'``: a variant of the Adleman--Lenstra |
| 2120 | algorithm as implemented in PARI. |
| 2121 | |
| 2122 | - ``'conway'``: look up the Conway polynomial of degree `n` |
| 2123 | over the field of `p` elements in the database; raise a |
| 2124 | ``RuntimeError`` if it is not found. |
| 2125 | |
| 2126 | - ``'first_lexicographic'``: return the lexicographically |
| 2127 | smallest irreducible polynomial of degree `n`. Only |
| 2128 | implemented for `p = 2`. |
| 2129 | |
| 2130 | - ``'minimal_weight'``: return an irreducible polynomial of |
| 2131 | degree `n` with minimal number of non-zero coefficients. |
| 2132 | Only implemented for `p = 2`. |
| 2133 | |
| 2134 | - ``'random'``: try random polynomials until an irreducible |
| 2135 | one is found. |
| 2136 | |
| 2137 | If ``algorithm`` is ``None``, the Conway polynomial is used |
| 2138 | if it is found in the database. If no Conway polynomial is |
| 2139 | found, the algorithm ``minimal_weight`` is used if `p = 2`, |
| 2140 | and the algorithm ``adleman-lenstra`` if `p > 2`. |
| 2141 | |
| 2142 | OUTPUT: |
| 2143 | |
| 2144 | A monic irreducible polynomial of degree `n` in ``self``. |
| 2145 | |
| 2146 | EXAMPLES: |
| 2147 | |
| 2148 | sage: GF(5)['x'].irreducible_element(2) |
| 2149 | x^2 + 4*x + 2 |
| 2150 | sage: GF(5)['x'].irreducible_element(2, algorithm="adleman-lenstra") |
| 2151 | x^2 + x + 1 |
| 2152 | |
| 2153 | sage: GF(2)['x'].irreducible_element(33) |
| 2154 | x^33 + x^13 + x^12 + x^11 + x^10 + x^8 + x^6 + x^3 + 1 |
| 2155 | sage: GF(2)['x'].irreducible_element(33, algorithm="minimal_weight") |
| 2156 | x^33 + x^10 + 1 |
| 2157 | |
| 2158 | AUTHORS: |
| 2159 | |
| 2160 | - Peter Bruin (June 2013) |
| 2161 | """ |
| 2162 | from sage.libs.pari.all import pari |
| 2163 | from sage.rings.finite_rings.constructor import (conway_polynomial, |
| 2164 | exists_conway_polynomial) |
| 2165 | from polynomial_gf2x import (GF2X_BuildIrred_list, GF2X_BuildSparseIrred_list, |
| 2166 | GF2X_BuildRandomIrred_list) |
| 2167 | |
| 2168 | p = self.characteristic() |
| 2169 | n = int(n) |
| 2170 | if n < 1: |
| 2171 | raise ValueError("degree must be at least 1") |
| 2172 | if algorithm is None: |
| 2173 | if exists_conway_polynomial(p, n): |
| 2174 | algorithm = "conway" |
| 2175 | elif p == 2: |
| 2176 | algorithm = "minimal_weight" |
| 2177 | else: |
| 2178 | algorithm = "adleman-lenstra" |
| 2179 | |
| 2180 | if algorithm == "adleman-lenstra": |
| 2181 | return self(pari(p).ffinit(n)) |
| 2182 | elif algorithm == "conway": |
| 2183 | return self(conway_polynomial(p, n)) |
| 2184 | elif algorithm == "first_lexicographic": |
| 2185 | if p == 2: |
| 2186 | return self(GF2X_BuildIrred_list(n)) |
| 2187 | else: |
| 2188 | raise NotImplementedError("'first_lexicographic' option only implemented for p = 2") |
| 2189 | elif algorithm == "minimal_weight": |
| 2190 | if p == 2: |
| 2191 | return self(GF2X_BuildSparseIrred_list(n)) |
| 2192 | else: |
| 2193 | raise NotImplementedError("'minimal_weight' option only implemented for p = 2") |
| 2194 | elif algorithm == "random": |
| 2195 | if p == 2: |
| 2196 | return self(GF2X_BuildRandomIrred_list(n)) |
| 2197 | else: |
| 2198 | pass |
| 2199 | |
| 2200 | # No suitable algorithm found, try algorithms from the base class. |
| 2201 | return PolynomialRing_dense_finite_field.irreducible_element(self, n, algorithm) |