Search code examples
pythonnumberssympysymbolsfactorization

SymPy - Treating numbers as symbols


How can I treat numbers as symbols in SymPy?

For example, if I am performing a factorization with symbols I get:

from sympy import factor
factor('a*c*d + a*c*e + a*c*f + b*c*d + b*c*e + b*c*f')
c*(a + b)*(d + e + f)

I would like the same behaviour when I am using numbers in the expression. Instead of

from sympy import factor
factor('2006*c*d + 2006*c*e + 2006*c*f + 2007*c*d + 2007*c*e + 2007*c*f')
4013*c*(d + e + f)

I would like to get

from sympy import factor
factor('2006*c*d + 2006*c*e + 2006*c*f + 2007*c*d + 2007*c*e + 2007*c*f')
c*(2006 + 2007)*(d + e + f)

Solution

  • Symbol trickery to the rescue: replace your numbers with Symbols having a name given by the number. In your case you don't have to watch for negative versions so the following is straightforward:

    >>> s = '2006*c*d + 2006*c*e + 2006*c*f + 2007*c*d + 2007*c*e + 2007*c*f'
    >>> eq = S(s, evaluate=False); eq
    2006*c*d + 2007*c*d + 2006*c*e + 2007*c*e + 2006*c*f + 2007*c*f
    >>> reps = dict([(i,Symbol(str(i))) for i in _.atoms(Integer)]); reps
    {2006: 2006, 2007: 2007}
    >>> factor(eq.subs(reps))
    c*(2006 + 2007)*(d + e + f)
    

    Note: the evaluate=False is used to keep the like-terms from combining to give 4013*c*d + 4013*c*e + 4013*c*f.