# Revision history [back]

Represent $y_i$ as vector of size $k+4$ with components being the degrees of $x_1, \dots, x_k, q_1, q_2, q_3$. Then create a dictionary D with such vectors as keys and integer values (counters with zero initial values). With each $y_i$ coming from $P_1$ increase the corresponding value in D, while with every $y_i$ coming from $P_2$ decrease the corresponding value in D. The ratio $P_1/P_2$ can be easily reconstructed from the resulting D and it won't contain any common factors between the numerator and denominator.

Represent $y_i$ as a vector of size $k+4$ with components being the degrees of $x_1, \dots, x_k, q_1, q_2, q_3$. q_3, m$. Then create a dictionary D with such vectors as keys and integer values (counters with zero initial values). With each$y_i$coming from$P_1$increase the corresponding value in D, while with every$y_i$coming from$P_2$decrease the corresponding value in D. The ratio$P_1/P_2$can be easily reconstructed from the resulting D and it won't contain any common factors between the numerator and denominator. Represent$y_i$as a vector of size$k+4$with components being the degrees of$x_1, \dots, x_k, q_1, q_2, q_3, m$. Then create a dictionary D with such vectors as keys and integer values (counters with zero initial values). With each$y_i$coming from$P_1$increase the corresponding value in D, while with every$y_i$coming from$P_2$decrease the corresponding value in D. The ratio$P_1/P_2$can be easily reconstructed from the resulting D and it won't contain any common factors between the numerator and denominator. ADDED. Here a rough translation of your code to these settings. In fact, it shows that no cancellations happen in your polynomials have no common factors, and slow down is caused by size of the resulting object. def mul_br(D,x,inc=1): for t in x.dict(): D.setdefault(t,0) D[t] += inc if D[t]==0: del D[t] def mex(): k = 3 L = LaurentPolynomialRing(ZZ, 5+k, 'mqx') m,q1,q2,q3,q4 = L.gens()[:5] X = L.gens()[5:] D = dict() #chim = prod([ br(X[j]/m) for j in range(k)]) for j in range(k): mul_br(D,X[j]/m) #chix = prod([ br(X[j]) for j in range(k)]) for j in range(k): mul_br(D,X[j],-1) #chiup = prod([ prod([ br(q1*q2*X[i]/X[j])*br(q1*q3*X[i]/X[j])*br(q2*q3*X[i]/X[j])*(br(X[i]/X[j]))^2 for i in range(k) if i > j]) for j in range(k)]) for j in range(k): for i in range(k): if i > j: mul_br(D,q1*q2*X[i]/X[j]) mul_br(D,q1*q3*X[i]/X[j]) mul_br(D,q2*q3*X[i]/X[j]) mul_br(D,X[i]/X[j],2) #chiups = prod([ prod([ br(X[i]/(X[j]*q1*q2))*br(X[i]/(X[j]*q1*q3))*br(X[i]/(X[j]*q2*q3)) for i in range(k) if i > j]) for j in range(k)]) for j in range(k): for i in range(k): if i > j: mul_br(D,X[i]/(X[j]*q1*q2)) mul_br(D,X[i]/(X[j]*q1*q3)) mul_br(D,X[i]/(X[j]*q2*q3)) #chido = prod([ prod([ br(q1*X[i]/X[j])*br(q2*X[i]/X[j])*br(q3*X[i]/X[j])*br(q1*q2*q3*X[i]/X[j]) for i in range(k) if i > j]) for j in range (k)]) for j in range (k): for i in range(k): if i > j: mul_br(D,q1*X[i]/X[j],-1) mul_br(D,q2*X[i]/X[j],-1) mul_br(D,q3*X[i]/X[j],-1) mul_br(D,q1*q2*q3*X[i]/X[j],-1) #chidos = prod([ prod([ br(X[i]/(X[j]*q1))*br(X[i]/(X[j]*q2))*br(X[i]/(X[j]*q3))*br(X[i]/(X[j]*q1*q2*q3)) for i in range(k) if i > j]) for j in range (k)]) for j in range (k): for i in range(k): if i > j: mul_br(D,X[i]/(X[j]*q1),-1) mul_br(D,X[i]/(X[j]*q2),-1) mul_br(D,X[i]/(X[j]*q3),-1) mul_br(D,X[i]/(X[j]*q1*q2*q3),-1) dx = prod(X[j] for j in range(k)) #chinum = (chim*chiup*chiups) #chiden = (chix*chido*chidos*dx) #chi = chinum/chiden return D  Running mex() returns an answer in form of a dictionary with 51 elements. If you want an actual polynomial from it, you can get it by running prod( (1-1/prod(g^e for g,e in zip(L.gens(),d)))^p for d,p in D.items() ) / dx  although it may be time consuming. Represent$y_i$as a vector of size$k+4$with components being the degrees of$x_1, \dots, x_k, q_1, q_2, q_3, m$. Then create a dictionary D with such vectors as keys and integer values (counters with zero initial values). With each$y_i$coming from$P_1$increase the corresponding value in D, while with every$y_i$coming from$P_2$decrease the corresponding value in D. The ratio$P_1/P_2\$ can be easily reconstructed from the resulting D and it won't contain any common factors between the numerator and denominator.

ADDED. Here a rough translation of your code to these settings. In fact, it shows that no cancellations happen in your polynomials as they have no common factors, and while the slow down is caused by size of the resulting object.

def mul_br(D,x,inc=1):
for t in x.dict():
D.setdefault(t,0)
D[t] += inc
if D[t]==0:
del D[t]

def mex():
k = 3
L = LaurentPolynomialRing(ZZ, 5+k, 'mqx')
m,q1,q2,q3,q4 = L.gens()[:5]
X = L.gens()[5:]

D = dict()

#chim = prod([ br(X[j]/m) for j in range(k)])
for j in range(k):
mul_br(D,X[j]/m)
#chix = prod([ br(X[j]) for j in range(k)])
for j in range(k):
mul_br(D,X[j],-1)
#chiup = prod([ prod([ br(q1*q2*X[i]/X[j])*br(q1*q3*X[i]/X[j])*br(q2*q3*X[i]/X[j])*(br(X[i]/X[j]))^2 for i in range(k) if i > j]) for j in range(k)])
for j in range(k):
for i in range(k):
if i > j:
mul_br(D,q1*q2*X[i]/X[j])
mul_br(D,q1*q3*X[i]/X[j])
mul_br(D,q2*q3*X[i]/X[j])
mul_br(D,X[i]/X[j],2)
#chiups = prod([ prod([ br(X[i]/(X[j]*q1*q2))*br(X[i]/(X[j]*q1*q3))*br(X[i]/(X[j]*q2*q3)) for i in range(k) if i > j]) for j in range(k)])
for j in range(k):
for i in range(k):
if i > j:
mul_br(D,X[i]/(X[j]*q1*q2))
mul_br(D,X[i]/(X[j]*q1*q3))
mul_br(D,X[i]/(X[j]*q2*q3))
#chido = prod([ prod([ br(q1*X[i]/X[j])*br(q2*X[i]/X[j])*br(q3*X[i]/X[j])*br(q1*q2*q3*X[i]/X[j]) for i in range(k) if i > j]) for j in range (k)])
for j in range (k):
for i in range(k):
if i > j:
mul_br(D,q1*X[i]/X[j],-1)
mul_br(D,q2*X[i]/X[j],-1)
mul_br(D,q3*X[i]/X[j],-1)
mul_br(D,q1*q2*q3*X[i]/X[j],-1)
#chidos = prod([ prod([ br(X[i]/(X[j]*q1))*br(X[i]/(X[j]*q2))*br(X[i]/(X[j]*q3))*br(X[i]/(X[j]*q1*q2*q3)) for i in range(k) if i > j]) for j in range (k)])
for j in range (k):
for i in range(k):
if i > j:
mul_br(D,X[i]/(X[j]*q1),-1)
mul_br(D,X[i]/(X[j]*q2),-1)
mul_br(D,X[i]/(X[j]*q3),-1)
mul_br(D,X[i]/(X[j]*q1*q2*q3),-1)
dx = prod(X[j] for j in range(k))
#chinum = (chim*chiup*chiups)
#chiden = (chix*chido*chidos*dx)
#chi = chinum/chiden

return D


Running mex() returns an answer in form of a dictionary with 51 elements. If you want an actual polynomial from it, you can get it by running

prod( (1-1/prod(g^e for g,e in zip(L.gens(),d)))^p for d,p in D.items() ) / dx


although it may be time consuming.