Skip to content

Commit 65f4cd2

Browse files
author
Release Manager
committed
gh-35358: Lighter construction of finite field elements from lists ### 📚 Description When doing intensive polynomial arithmetic with the NTL implementation the constructor with lists is called a large number of times and may spend a lot of time constructing the vector_space and FreeModuleElement objects. The very common call to vector_space(map=False) is optimized to be as cheap as possible using the already cached object. The common case of lists of length 0 and 1 is replaced by cheaper shortcuts. This improves performance when doing intensive polynomial computations over finite field extensions. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x ]`. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [ ] I have updated the documentation accordingly. URL: #35358 Reported by: Rémy Oudompheng Reviewer(s): Travis Scrimshaw
2 parents d051998 + 63c3ab6 commit 65f4cd2

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

src/sage/rings/finite_rings/element_pari_ffelt.pyx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,19 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement):
270270
sage: k = FiniteField(3^11, 't', impl='pari_ffelt')
271271
sage: k([ 0, 1/2 ])
272272
2*t
273+
sage: k([ 0, 1/2, 0, 0, 0, 0, 0, 0, 0, -1, 0 ])
274+
2*t^9 + 2*t
273275
sage: k([ k(0), k(1) ])
274276
t
275277
sage: k([ GF(3)(2), GF(3^5,'u')(1) ])
276278
t + 2
277279
sage: R.<x> = PolynomialRing(k)
280+
sage: k([ x/x ])
281+
1
278282
sage: k([ R(-1), x/x ])
279283
t + 2
284+
sage: k([ R(-1), R(0), 0 ])
285+
2
280286
281287
Check that zeros are created correctly (:trac:`11685`)::
282288
@@ -496,7 +502,13 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement):
496502
self.construct_from(x.constant_coefficient())
497503

498504
elif isinstance(x, list):
499-
if len(x) == self._parent.degree():
505+
n = len(x)
506+
if n == 0:
507+
self.construct_from(None)
508+
elif n == 1:
509+
Fp = self._parent.base_ring()
510+
self.construct_from(Fp(x[0]))
511+
elif n == self._parent.degree():
500512
self.construct_from(self._parent.vector_space(map=False)(x))
501513
else:
502514
Fp = self._parent.base_ring()

src/sage/rings/finite_rings/finite_field_base.pyx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,8 +1248,6 @@ cdef class FiniteField(Field):
12481248
sage: all(to_V(h(c) * e) == c * to_V(e) for e in E for c in F)
12491249
True
12501250
"""
1251-
from sage.modules.all import VectorSpace
1252-
from sage.categories.morphism import is_Morphism
12531251
if subfield is not None:
12541252
if base is not None:
12551253
raise ValueError
@@ -1259,6 +1257,13 @@ cdef class FiniteField(Field):
12591257
deprecation(28481, "The default value for map will be changing to True. To keep the current behavior, explicitly pass map=False.")
12601258
map = False
12611259

1260+
if base is None and self.__vector_space is not None and not map:
1261+
# A very common case: return as early as possible.
1262+
return self.__vector_space
1263+
1264+
from sage.modules.all import VectorSpace
1265+
from sage.categories.morphism import is_Morphism
1266+
12621267
if base is None:
12631268
base = self.prime_subfield()
12641269
s = self.degree()

0 commit comments

Comments
 (0)