Skip to content

Commit fe44fed

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

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

src/flint/types/acb_poly.pyx

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,95 @@ 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+
353+
def left_shift(self, slong n):
354+
"""
355+
Returns ``self`` shifted left by ``n`` coefficients by inserting
356+
zero coefficients. This is equivalent to multiplying the polynomial
357+
by x^n
358+
359+
>>> f = acb_poly([1,2,3])
360+
>>> f.left_shift(0)
361+
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
362+
>>> f.left_shift(1)
363+
3.00000000000000*x^3 + 2.00000000000000*x^2 + 1.00000000000000*x
364+
>>> f.left_shift(4)
365+
3.00000000000000*x^6 + 2.00000000000000*x^5 + 1.00000000000000*x^4
366+
367+
"""
368+
cdef acb_poly res
369+
res = acb_poly.__new__(acb_poly)
370+
371+
if n < 0:
372+
raise ValueError("Value must be shifted by a non-negative integer")
373+
if n > 0:
374+
acb_poly_shift_left(res.val, self.val, n)
375+
else: # do nothing, just copy self
376+
acb_poly_set(res.val, self.val)
377+
378+
return res
379+
380+
def right_shift(self, slong n):
381+
"""
382+
Returns ``self`` shifted right by ``n`` coefficients.
383+
This is equivalent to the floor division of the polynomial
384+
by x^n
385+
386+
>>> f = acb_poly([1,2,3])
387+
>>> f.right_shift(0)
388+
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
389+
>>> f.right_shift(1)
390+
3.00000000000000*x + 2.00000000000000
391+
>>> f.right_shift(4)
392+
0
393+
"""
394+
cdef acb_poly res
395+
res = acb_poly.__new__(acb_poly)
396+
397+
if n < 0:
398+
raise ValueError("Value must be shifted by a non-negative integer")
399+
if n > 0:
400+
acb_poly_shift_right(res.val, self.val, n)
401+
else: # do nothing, just copy self
402+
acb_poly_set(res.val, self.val)
403+
404+
return res
405+
317406
def __pow__(acb_poly s, ulong exp, mod):
318407
if mod is not None:
319408
raise NotImplementedError("acb_poly modular exponentiation")

src/flint/types/arb_poly.pyx

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,95 @@ 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+
351+
def left_shift(self, slong n):
352+
"""
353+
Returns ``self`` shifted left by ``n`` coefficients by inserting
354+
zero coefficients. This is equivalent to multiplying the polynomial
355+
by x^n
356+
357+
>>> f = arb_poly([1,2,3])
358+
>>> f.left_shift(0)
359+
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
360+
>>> f.left_shift(1)
361+
3.00000000000000*x^3 + 2.00000000000000*x^2 + 1.00000000000000*x
362+
>>> f.left_shift(4)
363+
3.00000000000000*x^6 + 2.00000000000000*x^5 + 1.00000000000000*x^4
364+
365+
"""
366+
cdef arb_poly res
367+
res = arb_poly.__new__(arb_poly)
368+
369+
if n < 0:
370+
raise ValueError("Value must be shifted by a non-negative integer")
371+
if n > 0:
372+
arb_poly_shift_left(res.val, self.val, n)
373+
else: # do nothing, just copy self
374+
arb_poly_set(res.val, self.val)
375+
376+
return res
377+
378+
def right_shift(self, slong n):
379+
"""
380+
Returns ``self`` shifted right by ``n`` coefficients.
381+
This is equivalent to the floor division of the polynomial
382+
by x^n
383+
384+
>>> f = arb_poly([1,2,3])
385+
>>> f.right_shift(0)
386+
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
387+
>>> f.right_shift(1)
388+
3.00000000000000*x + 2.00000000000000
389+
>>> f.right_shift(4)
390+
0
391+
"""
392+
cdef arb_poly res
393+
res = arb_poly.__new__(arb_poly)
394+
395+
if n < 0:
396+
raise ValueError("Value must be shifted by a non-negative integer")
397+
if n > 0:
398+
arb_poly_shift_right(res.val, self.val, n)
399+
else: # do nothing, just copy self
400+
arb_poly_set(res.val, self.val)
401+
402+
return res
403+
315404
def __pow__(arb_poly s, ulong exp, mod):
316405
if mod is not None:
317406
raise NotImplementedError("arb_poly modular exponentiation")

0 commit comments

Comments
 (0)