Skip to content

Commit 302e9e6

Browse files
Add shift and truncate methods to nmod_poly
1 parent 81784a9 commit 302e9e6

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

src/flint/types/nmod_poly.pyx

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,42 @@ cdef class nmod_poly(flint_poly):
252252
nmod_poly_reverse(res.val, self.val, length)
253253
return res
254254

255+
def truncate(self, slong n):
256+
r"""
257+
Notionally truncate the polynomial to have length ``n``. If
258+
``n`` is larger than the length of the input, then a copy of ``self`` is
259+
returned. If ``n`` is not positive, then the zero polynomial
260+
is returned.
261+
262+
Effectively returns this polynomial :math:`\mod x^n`.
263+
264+
>>> f = nmod_poly([1,2,3], 65537)
265+
>>> f.truncate(3) == f
266+
True
267+
>>> f.truncate(2)
268+
2*x + 1
269+
>>> f.truncate(1)
270+
1
271+
>>> f.truncate(0)
272+
0
273+
>>> f.truncate(-1)
274+
0
275+
276+
"""
277+
cdef nmod_poly res
278+
res = nmod_poly.__new__(nmod_poly)
279+
nmod_poly_init_preinv(res.val, self.val.mod.n, self.val.mod.ninv)
280+
281+
length = nmod_poly_length(self.val)
282+
if n <= 0: # return zero
283+
return res
284+
elif n > length: # do nothing
285+
nmod_poly_set(res.val, self.val)
286+
else:
287+
nmod_poly_set_trunc(res.val, self.val, n)
288+
289+
return res
290+
255291
def leading_coefficient(self):
256292
"""
257293
Return the leading coefficient of this polynomial.
@@ -521,6 +557,61 @@ cdef class nmod_poly(flint_poly):
521557
def __rmod__(s, t):
522558
return divmod(t, s)[1] # XXX
523559

560+
def left_shift(self, slong n):
561+
"""
562+
Returns ``self`` shifted left by ``n`` coefficients by inserting
563+
zero coefficients. This is equivalent to multiplying the polynomial
564+
by x^n
565+
566+
>>> f = nmod_poly([1,2,3], 99991)
567+
>>> f.left_shift(0)
568+
3*x^2 + 2*x + 1
569+
>>> f.left_shift(1)
570+
3*x^3 + 2*x^2 + x
571+
>>> f.left_shift(4)
572+
3*x^6 + 2*x^5 + x^4
573+
574+
"""
575+
cdef nmod_poly res
576+
res = nmod_poly.__new__(nmod_poly)
577+
nmod_poly_init_preinv(res.val, self.val.mod.n, self.val.mod.ninv)
578+
579+
if n < 0:
580+
raise ValueError("Value must be shifted by a non-negative integer")
581+
if n > 0:
582+
nmod_poly_shift_left(res.val, self.val, n)
583+
else: # do nothing, just copy self
584+
nmod_poly_set(res.val, self.val)
585+
586+
return res
587+
588+
def right_shift(self, slong n):
589+
"""
590+
Returns ``self`` shifted right by ``n`` coefficients.
591+
This is equivalent to the floor division of the polynomial
592+
by x^n
593+
594+
>>> f = nmod_poly([1,2,3], 99991)
595+
>>> f.right_shift(0)
596+
3*x^2 + 2*x + 1
597+
>>> f.right_shift(1)
598+
3*x + 2
599+
>>> f.right_shift(4)
600+
0
601+
"""
602+
cdef nmod_poly res
603+
res = nmod_poly.__new__(nmod_poly)
604+
nmod_poly_init_preinv(res.val, self.val.mod.n, self.val.mod.ninv)
605+
606+
if n < 0:
607+
raise ValueError("Value must be shifted by a non-negative integer")
608+
if n > 0:
609+
nmod_poly_shift_right(res.val, self.val, n)
610+
else: # do nothing, just copy self
611+
nmod_poly_set(res.val, self.val)
612+
613+
return res
614+
524615
def __pow__(nmod_poly self, exp, mod=None):
525616
cdef nmod_poly res
526617
if mod is not None:

0 commit comments

Comments
 (0)