# Arithmetic Engine for Polynomials as Tuples#

sage.algebras.fusion_rings.poly_tup_engine.apply_coeff_map(eq_tup, coeff_map)#

Apply `coeff_map` to coefficients.

EXAMPLES:

```sage: from sage.algebras.fusion_rings.poly_tup_engine import apply_coeff_map
sage: sq = lambda x : x**2
sage: R.<x, y, z> = PolynomialRing(ZZ)
sage: from sage.algebras.fusion_rings.poly_tup_engine import poly_to_tup, _tup_to_poly
sage: _tup_to_poly(apply_coeff_map(poly_to_tup(x + 2*y + 3*z), sq), parent=R)
x + 4*y + 9*z
```
sage.algebras.fusion_rings.poly_tup_engine.compute_known_powers(max_degs, val_dict, one)#

Pre-compute powers of known values for efficiency when preparing to substitute into a list of polynomials.

INPUT:

• `max_deg` – an `ETuple` indicating the maximal degree of each variable

• `val_dict` – a dictionary of `(var_idx, poly_tup)` key-value pairs

• `poly_tup` – a tuple of `(ETuple, coeff)` pairs reperesenting a multivariate polynomial

EXAMPLES:

```sage: from sage.algebras.fusion_rings.poly_tup_engine import compute_known_powers
sage: R.<x, y, z> = PolynomialRing(QQ)
sage: polys = [x**3 + 1, x**2*y + z**3, y**2 - 3*y]
sage: from sage.algebras.fusion_rings.poly_tup_engine import poly_to_tup
sage: known_val = { 0 : poly_to_tup(R(-1)), 2 : poly_to_tup(y**2) }
sage: from sage.algebras.fusion_rings.poly_tup_engine import get_variables_degrees
sage: max_deg = get_variables_degrees([poly_to_tup(p) for p in polys], 3)
sage: compute_known_powers(max_deg, known_val, R.base_ring().one())
{0: [(((0, 0, 0), 1),),
(((0, 0, 0), -1),),
(((0, 0, 0), 1),),
(((0, 0, 0), -1),)],
2: [(((0, 0, 0), 1),),
(((0, 2, 0), 1),),
(((0, 4, 0), 1),),
(((0, 6, 0), 1),)]}
```
sage.algebras.fusion_rings.poly_tup_engine.constant_coeff(eq_tup, field)#

Return the constant coefficient of the polynomial represented by given tuple.

EXAMPLES:

```sage: from sage.algebras.fusion_rings.poly_tup_engine import constant_coeff
sage: from sage.rings.polynomial.polydict import ETuple
sage: poly_tup = ((ETuple([0, 3, 0]), 2), (ETuple([0, 1, 0]), -1), (ETuple([0, 0, 0]), -2/3))
sage: constant_coeff(poly_tup, QQ)
-2/3
sage: R.<x, y, z> = PolynomialRing(QQ)
sage: from sage.algebras.fusion_rings.poly_tup_engine import poly_to_tup
sage: constant_coeff(poly_to_tup(x**5 + x*y*z - 9), QQ)
-9
```
sage.algebras.fusion_rings.poly_tup_engine.get_variables_degrees(eqns, nvars)#

Find maximum degrees for each variable in equations.

EXAMPLES:

```sage: from sage.algebras.fusion_rings.poly_tup_engine import get_variables_degrees
sage: R.<x, y, z> = PolynomialRing(QQ)
sage: polys = [x**2 + 1, x*y*z**2 - 4*x*y, x*z**3 - 4/3*y + 1]
sage: from sage.algebras.fusion_rings.poly_tup_engine import poly_to_tup
sage: get_variables_degrees([poly_to_tup(p) for p in polys], 3)
[2, 1, 3]
```
sage.algebras.fusion_rings.poly_tup_engine.poly_to_tup(poly)#

Convert a polynomial object into the internal representation as tuple of `(ETuple exp, NumberFieldElement coeff)` pairs.

EXAMPLES:

```sage: from sage.algebras.fusion_rings.poly_tup_engine import poly_to_tup
sage: R.<x, y> = PolynomialRing(QQ)
sage: poly_to_tup(x**2 + 1)
(((2, 0), 1), ((0, 0), 1))
sage: poly_to_tup(x**2*y**4 - 4/5*x*y**2 + 1/3 * y)
(((2, 4), 1), ((1, 2), -4/5), ((0, 1), 1/3))
```
sage.algebras.fusion_rings.poly_tup_engine.poly_tup_sortkey(eq_tup)#

Return the sortkey of a polynomial represented as a tuple of `(ETuple, coeff)` pairs with respect to the degree lexicographical term order.

Using this key to sort polynomial tuples results in comparing polynomials term by term (we assume the tuple representation is sorted so that the leading term with respect to the degree reverse lexicographical order comes first). For each term, we first compare degrees, then the monomials themselves. Different polynomials can have the same sortkey.

EXAMPLES:

```sage: F = CyclotomicField(20)
sage: zeta20 = F.gen()
sage: R.<x, y, z> = PolynomialRing(F)
sage: from sage.algebras.fusion_rings.poly_tup_engine import poly_tup_sortkey, poly_to_tup
sage: p = (zeta20 + 1)*x^2 + (zeta20^3 + 6)*x*z + (zeta20^2 + 7*zeta20)*z^2 + (2/3*zeta20 + 1/4)*x + y
sage: p1 = poly_to_tup(p); p1
(((2, 0, 0), zeta20 + 1),
((1, 0, 1), zeta20^3 + 6),
((0, 0, 2), zeta20^2 + 7*zeta20),
((1, 0, 0), 2/3*zeta20 + 1/4),
((0, 1, 0), 1))
sage: poly_tup_sortkey(p1)
(2, 0, 2, 2, 0, 1, -2, 1, 2, -2, 2, 1, 0, 1, 1, -1, 1)
```
sage.algebras.fusion_rings.poly_tup_engine.resize(eq_tup, idx_map, nvars)#

Return a tuple representing a polynomial in a ring with `len(sorted_vars)` generators.

This method is used for creating polynomial objects with the “right number” of variables for computing Groebner bases of the partitioned equations graph and for adding constraints ensuring certain F-symbols are nonzero.

EXAMPLES:

```sage: from sage.algebras.fusion_rings.poly_tup_engine import resize
sage: from sage.rings.polynomial.polydict import ETuple
sage: K = CyclotomicField(56)
sage: poly_tup = ((ETuple([0, 3, 0, 2]), K(2)), (ETuple([0, 1, 0, 1]), K(-1)), (ETuple([0, 0, 0, 0]), K(-2/3)))
sage: idx_map = {1: 0, 3: 1}
sage: resize(poly_tup, idx_map, 2)
(((3, 2), 2), ((1, 1), -1), ((0, 0), -2/3))

sage: R = PolynomialRing(K, 'fx', 20)
sage: R.inject_variables()
Defining fx0, fx1, fx2, fx3, fx4, fx5, fx6, fx7, fx8, fx9, fx10, fx11, fx12, fx13, fx14, fx15, fx16, fx17, fx18, fx19
sage: sparse_poly = R(fx0**2 * fx17 + fx3)
sage: from sage.algebras.fusion_rings.poly_tup_engine import poly_to_tup, _tup_to_poly
sage: S.<x, y, z> = PolynomialRing(K)
sage: _tup_to_poly(resize(poly_to_tup(sparse_poly), {0:0, 3:1, 17:2}, 3), parent=S)
x^2*z + y
```
sage.algebras.fusion_rings.poly_tup_engine.tup_to_univ_poly(eq_tup, univ_poly_ring)#

Given a tuple of pairs representing a univariate polynomial and a univariate polynomial ring, return a univariate polynomial object.

Each pair in the tuple is assumed to be of the form `(ETuple, coeff)`, where `coeff` is an element of `univ_poly_ring.base_ring()`.

EXAMPLES:

```sage: from sage.algebras.fusion_rings.poly_tup_engine import tup_to_univ_poly
sage: from sage.rings.polynomial.polydict import ETuple
sage: K = CyclotomicField(56)
sage: poly_tup = ((ETuple([0, 3, 0]), K(2)), (ETuple([0, 1, 0]), K(-1)), (ETuple([0, 0, 0]), K(-2/3)))
sage: R = K['b']
sage: tup_to_univ_poly(poly_tup, R)
2*b^3 - b - 2/3
```
sage.algebras.fusion_rings.poly_tup_engine.variables(eq_tup)#

Return indices of all variables appearing in eq_tup

EXAMPLES:

```sage: from sage.algebras.fusion_rings.poly_tup_engine import variables
sage: from sage.rings.polynomial.polydict import ETuple
sage: poly_tup = ((ETuple([0, 3, 0]), 2), (ETuple([0, 1, 0]), -1), (ETuple([0, 0, 0]), -2/3))
sage: variables(poly_tup)

sage: from sage.algebras.fusion_rings.poly_tup_engine import poly_to_tup
sage: R.<x, y, z> = PolynomialRing(QQ)
sage: variables(poly_to_tup(x*2*y + y**3 - 4/3*x))
[0, 1]
sage: variables(poly_to_tup(R(1/4)))
[]
```