|
14 | 14 |
|
15 | 15 | from sage.categories.category_with_axiom import CategoryWithAxiom
|
16 | 16 | from sage.categories.enumerated_sets import EnumeratedSets
|
| 17 | +from sage.rings.integer import Integer |
17 | 18 |
|
18 | 19 |
|
19 | 20 | class FiniteFields(CategoryWithAxiom):
|
@@ -192,5 +193,55 @@ def zeta(self, n=None):
|
192 | 193 | return mg() ** co_order
|
193 | 194 | return self._element_of_factored_order(n.factor())
|
194 | 195 |
|
| 196 | + def _element_of_factored_order(self, F): |
| 197 | + """ |
| 198 | + Return an element of ``self`` of order ``n`` where ``n`` is |
| 199 | + given in factored form. |
| 200 | +
|
| 201 | + This is copied from the cython implementation in |
| 202 | + ``finite_field_base.pyx`` which is kept as it may be faster. |
| 203 | +
|
| 204 | + INPUT: |
| 205 | +
|
| 206 | + - ``F`` -- the factorization of the required order. The order |
| 207 | + must be a divisor of ``self.order() - 1`` but this is not |
| 208 | + checked. |
| 209 | +
|
| 210 | + EXAMPLES:: |
| 211 | +
|
| 212 | + sage: k = Zmod(1913) |
| 213 | + sage: k in Fields() # to let k be a finite field |
| 214 | + True |
| 215 | + sage: k._element_of_factored_order(factor(1912)) |
| 216 | + 3 |
| 217 | + """ |
| 218 | + n = Integer(1) |
| 219 | + primes = [] |
| 220 | + for p, e in F: |
| 221 | + primes.append(p) |
| 222 | + n *= p**e |
| 223 | + |
| 224 | + N = self.order() - 1 |
| 225 | + c = N // n |
| 226 | + |
| 227 | + # We check whether (x + g)^c has the required order, where |
| 228 | + # x runs through the finite field. |
| 229 | + # This has the advantage that g is the first element we try, |
| 230 | + # so if that was a chosen to be a multiplicative generator, |
| 231 | + # we are done immediately. Second, the PARI finite field |
| 232 | + # iterator gives all the constant elements first, so we try |
| 233 | + # (g+(constant))^c before anything else. |
| 234 | + g = self.gen() |
| 235 | + if g == self.one(): |
| 236 | + # this allows to handle the ring Integers(prime) |
| 237 | + g = self.multiplicative_generator() |
| 238 | + for x in self: |
| 239 | + a = (g + x)**c |
| 240 | + if not a: |
| 241 | + continue |
| 242 | + if all(a**(n // p) != 1 for p in primes): |
| 243 | + return a |
| 244 | + raise AssertionError("no element found") |
| 245 | + |
195 | 246 | class ElementMethods:
|
196 | 247 | pass
|
0 commit comments