Skip to content

Commit 1b7ed3f

Browse files
Add shifts and truncate methods for arb_poly and acb_poly
1 parent bdb62ca commit 1b7ed3f

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed

src/flint/types/acb_poly.pyx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,94 @@ cdef class acb_poly(flint_poly):
314314
return s
315315
return divmod(t, s)
316316

317+
def truncate(self, slong n):
318+
r"""
319+
Notionally truncate the polynomial to have length ``n``. If
320+
``n`` is larger than the length of the input, then a copy of ``self`` is
321+
returned. If ``n`` is not positive, then the zero polynomial
322+
is returned.
323+
324+
Effectively returns this polynomial :math:`\mod x^n`.
325+
326+
>>> f = acb_poly([1,2,3])
327+
>>> f.truncate(3)
328+
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
329+
>>> f.truncate(2)
330+
2.00000000000000*x + 1.00000000000000
331+
>>> f.truncate(1)
332+
1.00000000000000
333+
>>> f.truncate(0)
334+
0
335+
>>> f.truncate(-1)
336+
0
337+
338+
"""
339+
cdef acb_poly res
340+
res = acb_poly.__new__(acb_poly)
341+
342+
length = acb_poly_length(self.val)
343+
if n <= 0: # return zero
344+
return res
345+
elif n > length: # do nothing
346+
acb_poly_set(res.val, self.val)
347+
else:
348+
acb_poly_set_trunc(res.val, self.val, n)
349+
350+
return res
351+
352+
def left_shift(self, slong n):
353+
"""
354+
Returns ``self`` shifted left by ``n`` coefficients by inserting
355+
zero coefficients. This is equivalent to multiplying the polynomial
356+
by x^n
357+
358+
>>> f = acb_poly([1,2,3])
359+
>>> f.left_shift(0)
360+
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
361+
>>> f.left_shift(1)
362+
3.00000000000000*x^3 + 2.00000000000000*x^2 + 1.00000000000000*x
363+
>>> f.left_shift(4)
364+
3.00000000000000*x^6 + 2.00000000000000*x^5 + 1.00000000000000*x^4
365+
366+
"""
367+
cdef acb_poly res
368+
res = acb_poly.__new__(acb_poly)
369+
370+
if n < 0:
371+
raise ValueError("Value must be shifted by a non-negative integer")
372+
if n > 0:
373+
acb_poly_shift_left(res.val, self.val, n)
374+
else: # do nothing, just copy self
375+
acb_poly_set(res.val, self.val)
376+
377+
return res
378+
379+
def right_shift(self, slong n):
380+
"""
381+
Returns ``self`` shifted right by ``n`` coefficients.
382+
This is equivalent to the floor division of the polynomial
383+
by x^n
384+
385+
>>> f = acb_poly([1,2,3])
386+
>>> f.right_shift(0)
387+
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
388+
>>> f.right_shift(1)
389+
3.00000000000000*x + 2.00000000000000
390+
>>> f.right_shift(4)
391+
0
392+
"""
393+
cdef acb_poly res
394+
res = acb_poly.__new__(acb_poly)
395+
396+
if n < 0:
397+
raise ValueError("Value must be shifted by a non-negative integer")
398+
if n > 0:
399+
acb_poly_shift_right(res.val, self.val, n)
400+
else: # do nothing, just copy self
401+
acb_poly_set(res.val, self.val)
402+
403+
return res
404+
317405
def __pow__(acb_poly s, ulong exp, mod):
318406
if mod is not None:
319407
raise NotImplementedError("acb_poly modular exponentiation")

src/flint/types/arb_poly.pyx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,94 @@ cdef class arb_poly(flint_poly):
312312
return s
313313
return divmod(t, s)
314314

315+
def truncate(self, slong n):
316+
r"""
317+
Notionally truncate the polynomial to have length ``n``. If
318+
``n`` is larger than the length of the input, then a copy of ``self`` is
319+
returned. If ``n`` is not positive, then the zero polynomial
320+
is returned.
321+
322+
Effectively returns this polynomial :math:`\mod x^n`.
323+
324+
>>> f = arb_poly([1,2,3])
325+
>>> f.truncate(3)
326+
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
327+
>>> f.truncate(2)
328+
2.00000000000000*x + 1.00000000000000
329+
>>> f.truncate(1)
330+
1.00000000000000
331+
>>> f.truncate(0)
332+
0
333+
>>> f.truncate(-1)
334+
0
335+
336+
"""
337+
cdef arb_poly res
338+
res = arb_poly.__new__(arb_poly)
339+
340+
length = arb_poly_length(self.val)
341+
if n <= 0: # return zero
342+
return res
343+
elif n > length: # do nothing
344+
arb_poly_set(res.val, self.val)
345+
else:
346+
arb_poly_set_trunc(res.val, self.val, n)
347+
348+
return res
349+
350+
def left_shift(self, slong n):
351+
"""
352+
Returns ``self`` shifted left by ``n`` coefficients by inserting
353+
zero coefficients. This is equivalent to multiplying the polynomial
354+
by x^n
355+
356+
>>> f = arb_poly([1,2,3])
357+
>>> f.left_shift(0)
358+
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
359+
>>> f.left_shift(1)
360+
3.00000000000000*x^3 + 2.00000000000000*x^2 + 1.00000000000000*x
361+
>>> f.left_shift(4)
362+
3.00000000000000*x^6 + 2.00000000000000*x^5 + 1.00000000000000*x^4
363+
364+
"""
365+
cdef arb_poly res
366+
res = arb_poly.__new__(arb_poly)
367+
368+
if n < 0:
369+
raise ValueError("Value must be shifted by a non-negative integer")
370+
if n > 0:
371+
arb_poly_shift_left(res.val, self.val, n)
372+
else: # do nothing, just copy self
373+
arb_poly_set(res.val, self.val)
374+
375+
return res
376+
377+
def right_shift(self, slong n):
378+
"""
379+
Returns ``self`` shifted right by ``n`` coefficients.
380+
This is equivalent to the floor division of the polynomial
381+
by x^n
382+
383+
>>> f = arb_poly([1,2,3])
384+
>>> f.right_shift(0)
385+
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
386+
>>> f.right_shift(1)
387+
3.00000000000000*x + 2.00000000000000
388+
>>> f.right_shift(4)
389+
0
390+
"""
391+
cdef arb_poly res
392+
res = arb_poly.__new__(arb_poly)
393+
394+
if n < 0:
395+
raise ValueError("Value must be shifted by a non-negative integer")
396+
if n > 0:
397+
arb_poly_shift_right(res.val, self.val, n)
398+
else: # do nothing, just copy self
399+
arb_poly_set(res.val, self.val)
400+
401+
return res
402+
315403
def __pow__(arb_poly s, ulong exp, mod):
316404
if mod is not None:
317405
raise NotImplementedError("arb_poly modular exponentiation")

0 commit comments

Comments
 (0)