How can I rewrite a SageMath / SymPy expression in terms of predefined subexpressions?
05:33 27 Jun 2026

I'm currently using SAGE via cocalc.com to find a mistake in a formula I derived. I'm trying to find different building blocks in the expression that SAGE puts out. First of all here is the expression for c2:

c2 = 
1/2*(k1^3*k3^3*v^6 + k2^3*k4^3 + 2*k2^3*k4^2*k5 + k2^3*k4*k5^2 + (3*k1^3*k3^2*k4 + 2*k1^3*k3^2*k5)*v^5 + (3*k1^2*k2*k3^2*k4 + 3*k1^3*k3*k4^2 - k1^3*k3*k5^2 + 2*(k1^2*k2*k3^2 + 2*k1^3*k3*k4)*k5)*v^4 + (6*k1^2*k2*k3*k4^2 + k1^3*k4^3 - (2*k1^2*k2*k3 + 2*k1*k2*k3^2 - k1^3*k4)*k5^2 + 2*(4*k1^2*k2*k3*k4 + k1^3*k4^2)*k5)*v^3 + (3*k1*k2^2*k3*k4^2 + 3*k1^2*k2*k4^3 - (k1*k2^2*k3 - 3*k1^2*k2*k4)*k5^2 + 2*(2*k1*k2^2*k3*k4 + 3*k1^2*k2*k4^2)*k5)*v^2 + 3*(k1*k2^2*k4^3 + 2*k1*k2^2*k4^2*k5 + k1*k2^2*k4*k5^2)*v)/(k1^3*k3^3*v^6 + k2^3*k4^3 + 3*k2^3*k4^2*k5 + 3*k2^3*k4*k5^2 + k2^3*k5^3 + 3*(k1^3*k3^2*k4 + k1^3*k3^2*k5)*v^5 + 3*(k1^2*k2*k3^2*k4 + k1^3*k3*k4^2 + k1^3*k3*k5^2 + (k1^2*k2*k3^2 + 2*k1^3*k3*k4)*k5)*v^4 + (6*k1^2*k2*k3*k4^2 + k1^3*k4^3 + k1^3*k5^3 + 3*(2*k1^2*k2*k3 + k1^3*k4)*k5^2 + 3*(4*k1^2*k2*k3*k4 + k1^3*k4^2)*k5)*v^3 + 3*(k1*k2^2*k3*k4^2 + k1^2*k2*k4^3 + k1^2*k2*k5^3 + (k1*k2^2*k3 + 3*k1^2*k2*k4)*k5^2 + (2*k1*k2^2*k3*k4 + 3*k1^2*k2*k4^2)*k5)*v^2 + 3*(k1*k2^2*k4^3 + 3*k1*k2^2*k4^2*k5 + 3*k1*k2^2*k4*k5^2 + k1*k2^2*k5^3)*v)

Okay, this looks terrible... So far, so good. However, I know different building blocks that should appear. For example, I know that v usually only appears with k1 and k3, I have a 2x2 matrix M and its determinant and two additional expressions a11 and a21. Here should be a complete building block list:

k1v = k1 * v
k3v = k3 * v

m11 = k1 * v + k2
m12 = k3 * v
m21 = k2
m22 = k3 * v + k4 + k5

detM = (k1 * v + k2) * (k4 + k5) + k1 * k3 * v^2

a11 = ( (k3 * k5 * v) / detM ) - 1
a21 = (k1 * k3 * v^2 + k1 * k4 * v + k2 * k4) / detM

Some context: I suspected detM to appear in the denominator, but I had a hard time verifying this and I think there must be a smarter way. I was using these lines:

nen2 = c2*detM*detM*detM
nomdivdet2 = nen2.full_simplify()
print(nomdivdet2.denominator())

The print puts out 2 , which comes from the 1/2 in front of the expression. Thus, I derive

c2 = 
1/2*(k1^3*k3^3*v^6 + k2^3*k4^3 + 2*k2^3*k4^2*k5 + k2^3*k4*k5^2 + (3*k1^3*k3^2*k4 + 2*k1^3*k3^2*k5)*v^5 + (3*k1^2*k2*k3^2*k4 + 3*k1^3*k3*k4^2 - k1^3*k3*k5^2 + 2*(k1^2*k2*k3^2 + 2*k1^3*k3*k4)*k5)*v^4 + (6*k1^2*k2*k3*k4^2 + k1^3*k4^3 - (2*k1^2*k2*k3 + 2*k1*k2*k3^2 - k1^3*k4)*k5^2 + 2*(4*k1^2*k2*k3*k4 + k1^3*k4^2)*k5)*v^3 + (3*k1*k2^2*k3*k4^2 + 3*k1^2*k2*k4^3 - (k1*k2^2*k3 - 3*k1^2*k2*k4)*k5^2 + 2*(2*k1*k2^2*k3*k4 + 3*k1^2*k2*k4^2)*k5)*v^2 + 3*(k1*k2^2*k4^3 + 2*k1*k2^2*k4^2*k5 + k1*k2^2*k4*k5^2)*v)/ detM^3

This looks much better already, but this seems to be a very complicated way to verify.


Main Question: Is there a simple way to tell SAGE / Python to write c2 at the very top in terms of the building block list, i.e. in terms of detM, a11, a21, k1v, k3v ?

python symbolic-math sage