Pure n-th power monomials of a polynomial
Two methods to extract the "pure n-th power monomials"
in a multivariate polynomial in Sage:
Dictionary of monomials and coefficients
A multivariate polynomial has a method to produce a dictionary
whose keys are exponent tuples and whose values are coefficients
for the corresponding monomials.
A polynomial ring can in turn convert such a dictionary into
a polynomial.
With these conversions in mind, the process becomes easy!
Define a polynomial ring and a polynomial:
sage: R.<x, y, z> = QQ[]
sage: f = x^10*y^5 + x^5*y^2 + x^2*z^2
sage: f
x^10*y^5 + x^5*y^2 + x^2*z^2
Turn it into a dictionary:
sage: d = f.dict()
sage: d
{(10, 5, 0): 1, (5, 2, 0): 1, (2, 0, 2): 1}
Extract a dictionary with the congruence condition:
sage: dd = {ee: c for ee, c in d.items() if all(e % 5 == 0 for e in ee)}
sage: dd
{(10, 5, 0): 1}
Turn the extracted dictionary back into a polynomial:
sage: R(dd)
x^10*y^5
These steps can be combined into a function.
Readable version:
def only_perfect_power_monomials(f, n):
R = f.parent()
d = f.dict()
dd = {ee: c for ee, c in d.items() if all(e % n == 0 for e in ee)}
return R(dd)
Compact version:
def only_perfect_power_monomials(f, n):
return f.parent()({ee: c for ee, c in f.dict().items()
if all(e % n == 0 for e in ee)})
Use the function:
sage: R.<x, y, z> = QQ[]
sage: f = x^10*y^5 + x^5*y^2 + x^2*z^2
sage: only_perfect_power_monomials(f, 5)
x^10*y^5
Taking n-th roots of monomials
We cannot take the fifth root of a polynomial variable,
but if a monomial happens to be a perfect fifth power,
then we can take its fifth root.
Let us illustrate this and then use it.
Define a polynomial ring and a polynomial:
sage: R.<x, y, z> = QQ[]
sage: f = x^10*y^5 + x^5*y^2 + x^2*z^2
sage: f
x^10*y^5 + x^5*y^2 + x^2*z^2
Extract its monomials and give them names:
sage: f.monomials()
[x^10*y^5, x^5*y^2, x^2*z^2]
sage: a, b, c = f.monomials()
Taking fifth roots of the monomials sometimes works:
sage: a^(1/5)
x^2*y
and sometimes fails:
sage: b^(1/5)
Traceback (most recent call last)
...
TypeError: no conversion of this rational to integer
...
During handling of the above exception, another exception occurred:
...
Traceback (most recent call last)
...
ValueError: not a 5th power
sage: c^(1/5)
Traceback (most recent call last)
...
TypeError: no conversion of this rational to integer
...
During handling of the above exception, another exception occurred:
...
Traceback (most recent call last)
...
ValueError: not a 5th power
Function that takes n-th roots of monomials if possible, zero otherwise:
def monomial_wise_nth_root_or_zero(f, n):
R = f.parent()
def nth_root_or_zero(m):
try:
return m^(1/n)
except ValueError:
return R.zero()
mm = f.monomials()
return sum([f[m] * nth_root_or_zero(m) for m in mm], R.zero())
Use the function:
sage: R.<x, y, z> = QQ[]
sage: f = x^10*y^5 + x^5*y^2 + x^2*z^2
sage: monomial_wise_nth_root_or_zero(f, 5)
x^2*y
Function that keeps only perfect n-th power monomials (choose your flavour):
def only_perfect_power_monomials(f, n):
R = f.parent()
def nth_root_or_zero(m):
try:
return m^(1/n)
except ValueError:
return R.zero()
mm = f.monomials()
return sum([f[m] * nth_root_or_zero(m)^n for m in mm], R.zero())
def only_perfect_power_monomials(f, n):
R = f.parent()
def keep_only_if_perfect_nth_power(m):
try:
return (m^(1/n))^n
except ValueError:
return R.zero()
mm = f.monomials()
return sum([f[m] * keep_only_if_perfect_nth_power(m) for m in mm], R.zero())
def only_perfect_power_monomials(f, n):
R = f.parent()
def keep_only_if_perfect_nth_power(m):
try:
m^(1/n)
return m
except ValueError:
return R.zero()
mm = f.monomials()
return sum([f[m] * keep_only_if_perfect_nth_power(m) for m in mm], R.zero())
def only_perfect_power_monomials(f, n):
R = f.parent()
result = R.zero()
for m in f.monomials():
try:
m^(1/n)
result += f[m] * m
except ValueError:
pass
return result
Use these functions:
sage: R.<x, y, z> = QQ[]
sage: f = x^10*y^5 + x^5*y^2 + x^2*z^2
sage: only_perfect_power_monomials(f, 5)
x^10*y^5