## 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
```