Skip to content

Commit 95b8190

Browse files
committed
refactoring polynomial and from_polynomial
1 parent a09d769 commit 95b8190

File tree

1 file changed

+107
-122
lines changed

1 file changed

+107
-122
lines changed

src/sage/rings/polynomial/integer_valued_polynomials.py

Lines changed: 107 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,63 @@ def degree_on_basis(self, m):
171171
"""
172172
return ZZ(m)
173173

174+
def from_polynomial(self, p):
175+
"""
176+
Convert a polynomial into the ring of integer-valued polynomials.
177+
178+
This raises a ``ValueError`` if this is not possible.
179+
180+
INPUT:
181+
182+
- ``p`` -- a polynomial in one variable
183+
184+
EXAMPLES::
185+
186+
sage: A = IntegerValuedPolynomialRing(ZZ).S()
187+
sage: S = A.basis()
188+
sage: S[5].polynomial()
189+
1/120*x^5 + 1/8*x^4 + 17/24*x^3 + 15/8*x^2 + 137/60*x + 1
190+
sage: A.from_polynomial(_)
191+
S[5]
192+
sage: x = polygen(QQ, 'x')
193+
sage: A.from_polynomial(x)
194+
-S[0] + S[1]
195+
196+
sage: A = IntegerValuedPolynomialRing(ZZ).B()
197+
sage: B = A.basis()
198+
sage: B[5].polynomial()
199+
1/120*x^5 - 1/12*x^4 + 7/24*x^3 - 5/12*x^2 + 1/5*x
200+
sage: A.from_polynomial(_)
201+
B[5]
202+
sage: x = polygen(QQ, 'x')
203+
sage: A.from_polynomial(x)
204+
B[1]
205+
206+
TESTS::
207+
208+
sage: x = polygen(QQ,'x')
209+
sage: A.from_polynomial(x+1/3)
210+
Traceback (most recent call last):
211+
...
212+
ValueError: not a polynomial with integer values: 1/3
213+
"""
214+
B = self.basis()
215+
poly = self._poly
216+
remain = p
217+
result = self.zero()
218+
while remain:
219+
N = remain.degree()
220+
top_coeff = remain.leading_coefficient() * factorial(N)
221+
try:
222+
top_coeff = self.base_ring()(top_coeff)
223+
except TypeError as exc:
224+
msg = 'not a polynomial with integer'
225+
msg += f' values: {top_coeff}'
226+
raise ValueError(msg) from exc
227+
remain += -top_coeff * poly(N)
228+
result += top_coeff * B[N]
229+
return result
230+
174231
def gen(self):
175232
r"""
176233
Return the generator of this algebra.
@@ -222,6 +279,31 @@ def __call__(self, v):
222279
"""
223280
return self.polynomial()(v)
224281

282+
def polynomial(self):
283+
"""
284+
Convert to a polynomial in `x`.
285+
286+
EXAMPLES::
287+
288+
sage: F = IntegerValuedPolynomialRing(ZZ).S()
289+
sage: B = F.gen()
290+
sage: (B+1).polynomial()
291+
x + 2
292+
293+
sage: F = IntegerValuedPolynomialRing(ZZ).B()
294+
sage: B = F.gen()
295+
sage: (B+1).polynomial()
296+
x + 1
297+
298+
TESTS::
299+
300+
sage: F.zero().polynomial().parent()
301+
Univariate Polynomial Ring in x over Rational Field
302+
"""
303+
R = PolynomialRing(QQ, 'x')
304+
p = self.parent()._poly
305+
return R.sum(c * p(i) for i, c in self)
306+
225307
def shift(self, j=1):
226308
"""
227309
Shift all indices by `j`.
@@ -420,45 +502,6 @@ def _from_binomial_basis(self, i):
420502
return self._from_dict({k: R((-1)**(i - k) * i.binomial(k))
421503
for k in range(i + 1)})
422504

423-
def from_polynomial(self, p):
424-
"""
425-
Convert a polynomial into the ring of integer-valued polynomials.
426-
427-
This raises a ``ValueError`` if this is not possible.
428-
429-
INPUT:
430-
431-
- ``p`` -- a polynomial in one variable
432-
433-
EXAMPLES::
434-
435-
sage: A = IntegerValuedPolynomialRing(ZZ).S()
436-
sage: S = A.basis()
437-
sage: S[5].polynomial()
438-
1/120*x^5 + 1/8*x^4 + 17/24*x^3 + 15/8*x^2 + 137/60*x + 1
439-
sage: A.from_polynomial(_)
440-
S[5]
441-
sage: x = polygen(QQ, 'x')
442-
sage: A.from_polynomial(x)
443-
-S[0] + S[1]
444-
"""
445-
B = self.basis()
446-
x = p.parent().gen()
447-
remain = p
448-
result = self.zero()
449-
while remain:
450-
N = remain.degree()
451-
top_coeff = remain.leading_coefficient() * factorial(N)
452-
try:
453-
top_coeff = self.base_ring()(top_coeff)
454-
except TypeError as exc:
455-
msg = 'not a polynomial with integer'
456-
msg += f' values: {top_coeff}'
457-
raise ValueError(msg) from exc
458-
remain += -top_coeff * binomial(N + x, N)
459-
result += top_coeff * B[N]
460-
return result
461-
462505
def from_h_vector(self, h):
463506
"""
464507
Convert from some `h`-vector.
@@ -614,6 +657,19 @@ def _coerce_map_from_(self, R):
614657
return self.base_ring().has_coerce_map_from(R.base_ring())
615658
return self.base_ring().has_coerce_map_from(R)
616659

660+
def _poly(self, i):
661+
"""
662+
Convert the basis element `S[i]` to a polynomial.
663+
664+
EXAMPLES::
665+
666+
sage: F = IntegerValuedPolynomialRing(ZZ).S()
667+
sage: F._poly(4)
668+
1/24*x^4 + 5/12*x^3 + 35/24*x^2 + 25/12*x + 1
669+
"""
670+
x = polygen(QQ, 'x')
671+
return binomial(x + i, i)
672+
617673
class Element(CombinatorialFreeModule.Element):
618674

619675
def umbra(self):
@@ -720,26 +776,6 @@ def derivative_at_minus_one(self):
720776
"""
721777
return QQ.sum(c / QQ(i) for i, c in self if i)
722778

723-
def polynomial(self):
724-
"""
725-
Convert to a polynomial in `x`.
726-
727-
EXAMPLES::
728-
729-
sage: F = IntegerValuedPolynomialRing(ZZ).S()
730-
sage: B = F.gen()
731-
sage: (B+1).polynomial()
732-
x + 2
733-
734-
TESTS::
735-
736-
sage: F.zero().polynomial().parent()
737-
Univariate Polynomial Ring in x over Rational Field
738-
"""
739-
x = polygen(QQ, 'x')
740-
R = x.parent()
741-
return R.sum(c * binomial(x + i, i) for i, c in self)
742-
743779
def h_vector(self):
744780
"""
745781
Return the numerator of the generating series of values.
@@ -931,51 +967,6 @@ def _from_shifted_basis(self, i):
931967
return self._from_dict({k: R(i.binomial(k))
932968
for k in range(i + 1)})
933969

934-
def from_polynomial(self, p):
935-
"""
936-
Convert a polynomial into the ring of integer-valued polynomials.
937-
938-
This raises a ``ValueError`` if this is not possible.
939-
940-
INPUT:
941-
942-
- ``p`` -- a polynomial in one variable
943-
944-
EXAMPLES::
945-
946-
sage: A = IntegerValuedPolynomialRing(ZZ).B()
947-
sage: B = A.basis()
948-
sage: B[5].polynomial()
949-
1/120*x^5 - 1/12*x^4 + 7/24*x^3 - 5/12*x^2 + 1/5*x
950-
sage: A.from_polynomial(_)
951-
B[5]
952-
sage: x = polygen(QQ, 'x')
953-
sage: A.from_polynomial(x)
954-
B[1]
955-
956-
TESTS::
957-
958-
sage: x = polygen(QQ,'x')
959-
sage: A.from_polynomial(x+1/3)
960-
Traceback (most recent call last):
961-
...
962-
ValueError: not a polynomial with integer values
963-
"""
964-
B = self.basis()
965-
x = p.parent().gen()
966-
remain = p
967-
result = self.zero()
968-
while remain:
969-
N = remain.degree()
970-
top_coeff = remain.leading_coefficient() * factorial(N)
971-
try:
972-
top_coeff = self.base_ring()(top_coeff)
973-
except TypeError as exc:
974-
raise ValueError('not a polynomial with integer values') from exc
975-
remain += -top_coeff * binomial(x, N)
976-
result += top_coeff * B[N]
977-
return result
978-
979970
def _element_constructor_(self, x):
980971
r"""
981972
Convert ``x`` into ``self``.
@@ -1098,26 +1089,20 @@ def _coerce_map_from_(self, R):
10981089
return self.base_ring().has_coerce_map_from(R.base_ring())
10991090
return self.base_ring().has_coerce_map_from(R)
11001091

1101-
class Element(CombinatorialFreeModule.Element):
1102-
1103-
def polynomial(self):
1104-
"""
1105-
Convert to a polynomial in `x`.
1106-
1107-
EXAMPLES::
1092+
def _poly(self, i):
1093+
"""
1094+
Convert the basis element `B[i]` to a polynomial.
11081095
1109-
sage: F = IntegerValuedPolynomialRing(ZZ).B()
1110-
sage: B = F.gen()
1111-
sage: (B+1).polynomial()
1112-
x + 1
1096+
EXAMPLES::
11131097
1114-
TESTS::
1098+
sage: F = IntegerValuedPolynomialRing(ZZ).B()
1099+
sage: F._poly(4)
1100+
1/24*x^4 - 1/4*x^3 + 11/24*x^2 - 1/4*x
1101+
"""
1102+
x = polygen(QQ, 'x')
1103+
return binomial(x, i)
11151104

1116-
sage: F.zero().polynomial().parent()
1117-
Univariate Polynomial Ring in x over Rational Field
1118-
"""
1119-
x = polygen(QQ, 'x')
1120-
R = x.parent()
1121-
return R.sum(c * binomial(x, i) for i, c in self)
1105+
class Element(CombinatorialFreeModule.Element):
1106+
pass
11221107

11231108
B = Binomial

0 commit comments

Comments
 (0)