# Revision history [back]

Instead of symbolic variables you can work in polynomial rings, as follows.

R.<u1,u2,u3,x1,x2,x3> = PolynomialRing(QQ)
f=1/((u1*u2*u3 - x1*x2*x3)*(u1*u2*u3 - 1)*(u1*u2 - x1*x2)*(u1*u2 - 1)*(u1 - x1)*(u1 - 1))
fden=f.denominator() #denominator of f


Division of polynomials automatically yields elements of the fraction field.

You can re-interpret a multivariate polynomial as being a polynomial in one variable, putting the remaining variables in the base ring:

sage: f_u1 = fden.polynomial(u1)
sage: f_u1.parent()
Univariate Polynomial Ring in u1 over Multivariate Polynomial Ring in u2, u3, x1, x2, x3 over Rational Field


But now the base ring is not a field, so it is hard to find roots. We change the base ring to be the fraction field of the old base ring:

sage: f_u1 = f_u1.change_ring(f_u1.base_ring().fraction_field())
sage: f_u1.parent()
Univariate Polynomial Ring in u1 over Fraction Field of Multivariate Polynomial Ring in u2, u3, x1, x2, x3 over Rational Field


Now we can find roots:

sage: f_u1.roots()
[(1, 1),
(x1, 1),
(1/u2, 1),
(x1*x2/u2, 1),
(1/(u2*u3), 1),
(x1*x2*x3/(u2*u3), 1)]


This should be much more efficient than using symbolic variables. Let me know if this works for you.

Instead of working with symbolic variables you can work in (fraction fields of) polynomial rings, as follows.

R.<u1,u2,u3,x1,x2,x3> = PolynomialRing(QQ)
f=1/((u1*u2*u3 - x1*x2*x3)*(u1*u2*u3 - 1)*(u1*u2 - x1*x2)*(u1*u2 - 1)*(u1 - x1)*(u1 - 1))
fden=f.denominator() #denominator of f


Division of polynomials automatically yields elements of the fraction field.

You can re-interpret a multivariate polynomial as being a polynomial in one variable, putting the remaining variables in the base ring:

sage: f_u1 = fden.polynomial(u1)
sage: f_u1.parent()
Univariate Polynomial Ring in u1 over Multivariate Polynomial Ring in u2, u3, x1, x2, x3 over Rational Field


But now the base ring is not a field, so it is hard to find roots. We change the base ring to be the fraction field of the old base ring:

sage: f_u1 = f_u1.change_ring(f_u1.base_ring().fraction_field())
sage: f_u1.parent()
Univariate Polynomial Ring in u1 over Fraction Field of Multivariate Polynomial Ring in u2, u3, x1, x2, x3 over Rational Field


Now we can find roots:

sage: f_u1.roots()
[(1, 1),
(x1, 1),
(1/u2, 1),
(x1*x2/u2, 1),
(1/(u2*u3), 1),
(x1*x2*x3/(u2*u3), 1)]


This should be much more efficient than using symbolic variables. Let me know if this works for you.

As for residues, indeed they are not implemented for rational functions. But you can easily implement the formulas yourself. For example, the residue of $p(z)/q(z)$ at a simple pole $z=r$ is $p(r)/q'(r)$.

Instead of working with symbolic variables you can work in (fraction fields of) polynomial rings, as follows.

R.<u1,u2,u3,x1,x2,x3> = PolynomialRing(QQ)
f=1/((u1*u2*u3 - x1*x2*x3)*(u1*u2*u3 - 1)*(u1*u2 - x1*x2)*(u1*u2 - 1)*(u1 - x1)*(u1 - 1))
fden=f.denominator() #denominator of f


Division of polynomials automatically yields elements of the fraction field.

You can re-interpret a multivariate polynomial as being a polynomial in one variable, putting the remaining variables in the base ring:

sage: f_u1 = fden.polynomial(u1)
sage: f_u1.parent()
Univariate Polynomial Ring in u1 over Multivariate Polynomial Ring in u2, u3, x1, x2, x3 over Rational Field


But now the base ring is not a field, so it is hard to find roots. We change the base ring to be roots there. But we can search for roots in the fraction field of the old base ring:

sage: f_u1 = f_u1.change_ring(f_u1.base_ring().fraction_field())
sage: f_u1.parent()
Univariate Polynomial Ring in u1 over Fraction Field of Multivariate Polynomial Ring in u2, u3, x1, x2, x3 over Rational Field


Now we can find roots:

sage: f_u1.roots()
f_u1.roots(f_u1.base_ring().fraction_field())
[(1, 1),
(x1, 1),
(1/u2, 1),
(x1*x2/u2, 1),
(1/(u2*u3), 1),
(x1*x2*x3/(u2*u3), 1)]


This should be much more efficient than using symbolic variables. Let me know if this works for you.

As for residues, indeed they are not implemented for rational functions. But you can easily implement the formulas yourself. For example, the residue of $p(z)/q(z)$ at a simple pole $z=r$ is $p(r)/q'(r)$.

Instead of working with symbolic variables you can work in (fraction fields of) polynomial rings, as follows.

R.<u1,u2,u3,x1,x2,x3> = PolynomialRing(QQ)
f=1/((u1*u2*u3 - x1*x2*x3)*(u1*u2*u3 - 1)*(u1*u2 - x1*x2)*(u1*u2 - 1)*(u1 - x1)*(u1 - 1))
fden=f.denominator() #denominator of f


Division of polynomials automatically yields elements of the fraction field.

You can re-interpret a multivariate polynomial as being a polynomial in one variable, putting the remaining variables in the base ring:

sage: f_u1 = fden.polynomial(u1)
sage: f_u1.parent()
Univariate Polynomial Ring in u1 over Multivariate Polynomial Ring in u2, u3, x1, x2, x3 over Rational Field


But now the base ring is not a field, so it is hard to find roots there. But we can search for roots in the fraction field of the base ring:

sage: f_u1.roots(f_u1.base_ring().fraction_field())
[(1, 1),
(x1, 1),
(1/u2, 1),
(x1*x2/u2, 1),
(1/(u2*u3), 1),
(x1*x2*x3/(u2*u3), 1)]


This should be much more efficient than using symbolic variables. Let me know if this works for you.

As for residues, indeed they are not implemented for rational functions. But you can easily implement the formulas yourself. For example, the residue of $p(z)/q(z)$ at a simple pole $z=r$ is $p(r)/q'(r)$.

Edit: In the second step, the roots of the denominator with respect to $u_2$ may live in a larger field (when there are irreducible factors of degree $\gt 1$ w.r.t $u_2$ in the denominator), so you have to add these to your field when searching for roots. Basically you want the splitting field of the numerator.

Instead of working with symbolic variables you can work in (fraction fields of) polynomial rings, as follows.

R.<u1,u2,u3,x1,x2,x3> = PolynomialRing(QQ)
f=1/((u1*u2*u3 - x1*x2*x3)*(u1*u2*u3 - 1)*(u1*u2 - x1*x2)*(u1*u2 - 1)*(u1 - x1)*(u1 - 1))
fden=f.denominator() #denominator of f


Division of polynomials automatically yields elements of the fraction field.

You can re-interpret a multivariate polynomial as being a polynomial in one variable, putting the remaining variables in the base ring:

sage: f_u1 = fden.polynomial(u1)
sage: f_u1.parent()
Univariate Polynomial Ring in u1 over Multivariate Polynomial Ring in u2, u3, x1, x2, x3 over Rational Field


But now the base ring is not a field, so it is hard to find roots there. But we can search for roots in the fraction field of the base ring:

sage: f_u1.roots(f_u1.base_ring().fraction_field())
[(1, 1),
(x1, 1),
(1/u2, 1),
(x1*x2/u2, 1),
(1/(u2*u3), 1),
(x1*x2*x3/(u2*u3), 1)]


This should be much more efficient than using symbolic variables. Let me know if this works for you.

As for residues, indeed they are not implemented for rational functions. But you can easily implement the formulas yourself. For example, the residue of $p(z)/q(z)$ at a simple pole $z=r$ is $p(r)/q'(r)$.

Edit: In the second step, the roots of the denominator with respect to $u_2$ may live in a larger field (when there are irreducible factors of degree $\gt 1$ w.r.t $u_2$ in the denominator), so you have to add these to your field when searching for roots. Basically you want the splitting field of the numerator.

denominator.

Instead of working with symbolic variables you can work in (fraction fields of) polynomial rings, as follows.

R.<u1,u2,u3,x1,x2,x3> = PolynomialRing(QQ)
f=1/((u1*u2*u3 - x1*x2*x3)*(u1*u2*u3 - 1)*(u1*u2 - x1*x2)*(u1*u2 - 1)*(u1 - x1)*(u1 - 1))
fden=f.denominator() #denominator of f


Division of polynomials automatically yields elements of the fraction field.

You can re-interpret a multivariate polynomial as being a polynomial in one variable, putting the remaining variables in the base ring:

sage: f_u1 = fden.polynomial(u1)
sage: f_u1.parent()
Univariate Polynomial Ring in u1 over Multivariate Polynomial Ring in u2, u3, x1, x2, x3 over Rational Field


But now the base ring is not a field, so it is hard to find roots there. But we can search for roots in the fraction field of the base ring:

sage: f_u1.roots(f_u1.base_ring().fraction_field())
[(1, 1),
(x1, 1),
(1/u2, 1),
(x1*x2/u2, 1),
(1/(u2*u3), 1),
(x1*x2*x3/(u2*u3), 1)]


This should be much more efficient than using symbolic variables. Let me know if this works for you.

As for residues, indeed they are not implemented for rational functions. But you can easily implement the formulas yourself. For example, the residue of $p(z)/q(z)$ at a simple pole $z=r$ is $p(r)/q'(r)$.

Edit: In the second step, the roots of the denominator with respect to $u_2$ may live in a larger field (when there are irreducible factors of degree $\gt 1$ w.r.t $u_2$ in the denominator), so you have to add these to your field when searching for roots. Basically you want the splitting field of the denominator.

denominator. Since the variables are still undetermined it seems you would have to create a function field (extension).