Given two expressions, `p` and `q`
p = x*y + x + y*z
q = p + z
it is easy to show that `q = (x + z)*(y + 1)`. But I'm wanting to avoid factoring but would like to know whether a solution for `x` from `p = 0` or `q = 0` is a factor or not. For `q`, the root `x = -z` represent a simple factor whereas the root of x = `-yz/(y + 1)` is different.
I'm lacking the vocabulary to differentiate `-z` from `-yz/(y + 1)`. Is it that the latter has a denominator while the former does not? (And since the original expression had no denominator then the `-z` represents a "whole" factor while the other root does not?)
As an alternative to factoring, it seems like collection and identification of similar subexpressions should allow a multivariate expression to be written in terms of un-factored factors, e.g. `collect(q, x) -> x*(y + 1) + y*z + z` and then use `factor_terms` on the non-x portion of the expression to find a matching factor of `y + 1` so the expression can be separated into two factors, one with `y` and one with `x` and `z`. This works for less trivial expressions and can be done recursively something like this:
def sep(e):
free = e.free_symbols
if not free:return e
x = next(ordered(free))
c = collect(e.expand(),x)
if not c.is_Add:return c
i,d = c.as_independent(x)
d = d.func(*[factor_terms(di) for di in d.args])
i = factor_terms(i)
ia, a = i.as_independent(Add, as_Add=False)
if a==1:
return e
_a = sep(a)
D = Dummy()
return factor_terms(ia*D + d.xreplace({a:D})).subs(D, _a)
eq
v**3*y*z**10 + 4*v**3*y*z**6 + 2*v**3*y*z**5 + 4*v**3*y*z**2 + 4*v**3*y*z + v**3*y + v**3*z**10 + 4*v**3*z**6 + 2*v**3*z**5 + 4*v**3*z**2 + 4*v**3*z + v**3 + 3*v**2*x*y*z**10 + 12*v**2*x*y*z**6 + 6*v**2*x*y*z**5 + 12*v**2*x*y*z**2 + 12*v**2*x*y*z + 3*v**2*x*y + 3*v**2*x*z**10 + 12*v**2*x*z**6 + 6*v**2*x*z**5 + 12*v**2*x*z**2 + 12*v**2*x*z + 3*v**2*x + 3*v*x**2*y*z**10 + 12*v*x**2*y*z**6 + 6*v*x**2*y*z**5 + 12*v*x**2*y*z**2 + 12*v*x**2*y*z + 3*v*x**2*y + 3*v*x**2*z**10 + 12*v*x**2*z**6 + 6*v*x**2*z**5 + 12*v*x**2*z**2 + 12*v*x**2*z + 3*v*x**2 + x**3*y*z**10 + 4*x**3*y*z**6 + 2*x**3*y*z**5 + 4*x**3*y*z**2 + 4*x**3*y*z + x**3*y + x**3*z**10 + 4*x**3*z**6 + 2*x**3*z**5 + 4*x**3*z**2 + 4*x**3*z + x**3
sep(eq)
(y + 1)*(v**3 + 3*v**2*x + 3*v*x**2 + x**3)*(z**10 + 4*z**6 + 2*z**5 + 4*z**2 + 4*z + 1)
eq == _.expand()
True
(It always seems like `factor` is faster than this but factor can be slow, too. And I don't really need the separated factors "factored" as much as I just need them separated.
So maybe that sort of function will answer the question...
Any thoughts would be appreciated as to what might be the best way to know when you have a solution that is a whole factors (not a rational factor -- or whatever it should be called.)
/c