Skip to content

Commit bdb62ca

Browse files
Add shift and truncate methods to fmpz_poly and fmpq_poly
1 parent 6826c38 commit bdb62ca

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed

src/flint/types/fmpq_poly.pyx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,41 @@ cdef class fmpq_poly(flint_poly):
209209
"""
210210
return <bint>fmpq_poly_is_gen(self.val)
211211

212+
def truncate(self, slong n):
213+
r"""
214+
Notionally truncate the polynomial to have length ``n``. If
215+
``n`` is larger than the length of the input, then a copy of ``self`` is
216+
returned. If ``n`` is not positive, then the zero polynomial
217+
is returned.
218+
219+
Effectively returns this polynomial :math:`\mod x^n`.
220+
221+
>>> f = fmpq_poly([1,2,3])
222+
>>> f.truncate(3) == f
223+
True
224+
>>> f.truncate(2)
225+
2*x + 1
226+
>>> f.truncate(1)
227+
1
228+
>>> f.truncate(0)
229+
0
230+
>>> f.truncate(-1)
231+
0
232+
233+
"""
234+
cdef fmpq_poly res
235+
res = fmpq_poly.__new__(fmpq_poly)
236+
237+
length = fmpq_poly_length(self.val)
238+
if n <= 0: # return zero
239+
return res
240+
elif n > length: # do nothing
241+
fmpq_poly_set(res.val, self.val)
242+
else:
243+
fmpq_poly_set_trunc(res.val, self.val, n)
244+
245+
return res
246+
212247
def leading_coefficient(self):
213248
"""
214249
Returns the leading coefficient of the polynomial.
@@ -402,6 +437,59 @@ cdef class fmpq_poly(flint_poly):
402437
return t
403438
return t._divmod_(s)
404439

440+
def left_shift(self, slong n):
441+
"""
442+
Returns ``self`` shifted left by ``n`` coefficients by inserting
443+
zero coefficients. This is equivalent to multiplying the polynomial
444+
by x^n
445+
446+
>>> f = fmpq_poly([1,2,3])
447+
>>> f.left_shift(0)
448+
3*x^2 + 2*x + 1
449+
>>> f.left_shift(1)
450+
3*x^3 + 2*x^2 + x
451+
>>> f.left_shift(4)
452+
3*x^6 + 2*x^5 + x^4
453+
454+
"""
455+
cdef fmpq_poly res
456+
res = fmpq_poly.__new__(fmpq_poly)
457+
458+
if n < 0:
459+
raise ValueError("Value must be shifted by a non-negative integer")
460+
if n > 0:
461+
fmpq_poly_shift_left(res.val, self.val, n)
462+
else: # do nothing, just copy self
463+
fmpq_poly_set(res.val, self.val)
464+
465+
return res
466+
467+
def right_shift(self, slong n):
468+
"""
469+
Returns ``self`` shifted right by ``n`` coefficients.
470+
This is equivalent to the floor division of the polynomial
471+
by x^n
472+
473+
>>> f = fmpq_poly([1,2,3])
474+
>>> f.right_shift(0)
475+
3*x^2 + 2*x + 1
476+
>>> f.right_shift(1)
477+
3*x + 2
478+
>>> f.right_shift(4)
479+
0
480+
"""
481+
cdef fmpq_poly res
482+
res = fmpq_poly.__new__(fmpq_poly)
483+
484+
if n < 0:
485+
raise ValueError("Value must be shifted by a non-negative integer")
486+
if n > 0:
487+
fmpq_poly_shift_right(res.val, self.val, n)
488+
else: # do nothing, just copy self
489+
fmpq_poly_set(res.val, self.val)
490+
491+
return res
492+
405493
def __pow__(fmpq_poly self, exp, mod):
406494
cdef fmpq_poly res
407495
if mod is not None:

src/flint/types/fmpz_poly.pyx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,41 @@ cdef class fmpz_poly(flint_poly):
186186
"""
187187
return <bint>fmpz_poly_is_gen(self.val)
188188

189+
def truncate(self, slong n):
190+
r"""
191+
Notionally truncate the polynomial to have length ``n``. If
192+
``n`` is larger than the length of the input, then a copy of ``self`` is
193+
returned. If ``n`` is not positive, then the zero polynomial
194+
is returned.
195+
196+
Effectively returns this polynomial :math:`\mod x^n`.
197+
198+
>>> f = fmpz_poly([1,2,3])
199+
>>> f.truncate(3) == f
200+
True
201+
>>> f.truncate(2)
202+
2*x + 1
203+
>>> f.truncate(1)
204+
1
205+
>>> f.truncate(0)
206+
0
207+
>>> f.truncate(-1)
208+
0
209+
210+
"""
211+
cdef fmpz_poly res
212+
res = fmpz_poly.__new__(fmpz_poly)
213+
214+
length = fmpz_poly_length(self.val)
215+
if n <= 0: # return zero
216+
return res
217+
elif n > length: # do nothing
218+
fmpz_poly_set(res.val, self.val)
219+
else:
220+
fmpz_poly_set_trunc(res.val, self.val, n)
221+
222+
return res
223+
189224
def leading_coefficient(self):
190225
"""
191226
Returns the leading coefficient of the polynomial.
@@ -383,6 +418,59 @@ cdef class fmpz_poly(flint_poly):
383418
return other
384419
return other._divmod_(self)
385420

421+
def left_shift(self, slong n):
422+
"""
423+
Returns ``self`` shifted left by ``n`` coefficients by inserting
424+
zero coefficients. This is equivalent to multiplying the polynomial
425+
by x^n
426+
427+
>>> f = fmpz_poly([1,2,3])
428+
>>> f.left_shift(0)
429+
3*x^2 + 2*x + 1
430+
>>> f.left_shift(1)
431+
3*x^3 + 2*x^2 + x
432+
>>> f.left_shift(4)
433+
3*x^6 + 2*x^5 + x^4
434+
435+
"""
436+
cdef fmpz_poly res
437+
res = fmpz_poly.__new__(fmpz_poly)
438+
439+
if n < 0:
440+
raise ValueError("Value must be shifted by a non-negative integer")
441+
if n > 0:
442+
fmpz_poly_shift_left(res.val, self.val, n)
443+
else: # do nothing, just copy self
444+
fmpz_poly_set(res.val, self.val)
445+
446+
return res
447+
448+
def right_shift(self, slong n):
449+
"""
450+
Returns ``self`` shifted right by ``n`` coefficients.
451+
This is equivalent to the floor division of the polynomial
452+
by x^n
453+
454+
>>> f = fmpz_poly([1,2,3])
455+
>>> f.right_shift(0)
456+
3*x^2 + 2*x + 1
457+
>>> f.right_shift(1)
458+
3*x + 2
459+
>>> f.right_shift(4)
460+
0
461+
"""
462+
cdef fmpz_poly res
463+
res = fmpz_poly.__new__(fmpz_poly)
464+
465+
if n < 0:
466+
raise ValueError("Value must be shifted by a non-negative integer")
467+
if n > 0:
468+
fmpz_poly_shift_right(res.val, self.val, n)
469+
else: # do nothing, just copy self
470+
fmpz_poly_set(res.val, self.val)
471+
472+
return res
473+
386474
def __pow__(fmpz_poly self, exp, mod):
387475
cdef fmpz_poly res
388476
if mod is not None:

0 commit comments

Comments
 (0)