I am generating symbolic functions and using SymPy to simplify them. Now I would like a way to "simplify" symbols that represent constant parameters in a function that is yet to be fitted. For example, if I am generating a polynomial, I might generate a string like this
C*x*x + C*x + C*x + C,
which SymPy would turn into
C*x^2 + 2*C*x + C.
Now I would like to find a way to get this:
C*x^2 + C*x + C.
In other words, is there a way to tell SymPy that a certain symbol is constant and undefined, so that
C+C -> C, C*C -> C, etc. Or more generally: f(C) = C, for any f(C)?
My first idea was that perhaps there is an assumption (such as Q.positive) that describes this property and I might be able to use refine. However, this does not seem to be the case. If nothing else, I'm sure there is a way to use preorder_traversal to do what I want, but I can't come up with a strategy to do it. Any help or ideas are appreciated.
Answer
To simplify expressions where a symbol (like C
in your example) behaves as a constant parameter, SymPy has a couple of ways to handle this. In your case, you want to tell SymPy that C
is a constant and "simplify" expressions involving C
accordingly, like treating C + C
as C
or C * C
as C
.
While there is no direct way in SymPy to treat a symbol as a "constant" in the sense of ignoring all its algebraic properties (like addition and multiplication), we can work around this in a few ways.
Solution 1: Use Subs
to Replace C
by a Constant
One straightforward approach is to substitute C
with an arbitrary constant (say 1
or any other number you choose). This can make the expression behave as though it's a constant while still preserving the symbolic structure.
For example, you can do the following:
import sympy as sp
# Define the symbol C
C = sp.symbols('C')
# Define the expression
expr = C*x*x + C*x + C*x + C
# Substitute C with a constant value, say 1
expr_simplified = expr.subs(C, 1)
# Print the result
print(expr_simplified) # Output: x**2 + 2*x + 1
However, this may not always be what you're looking for if you need to keep C
symbolic.
Solution 2: Use Custom Simplification with preorder_traversal
You can define a custom simplification strategy using preorder_traversal
, which recursively traverses the expression and applies your desired simplifications. Specifically, you can treat expressions involving C
(like C + C
, C * C
) as reducing to just C
.
Here’s how you can implement this:
import sympy as sp
# Define the symbol C and x
C, x = sp.symbols('C x')
# Define the expression
expr = C*x*x + C*x + C*x + C
# Define a custom simplification function
def simplify_constants(expr):
# Perform a preorder traversal of the expression
def simplifier(e):
# If the expression is a sum or product involving C, simplify it
if isinstance(e, sp.Add):
# Simplify sums involving C
return C + C # You could also do C + C --> C manually if you wish
elif isinstance(e, sp.Mul):
# Simplify multiplications involving C
return C # Reduce C*C --> C
else:
return e
return sp.simplify(e, rational=True) # Optional
simplified_expr = simplify_constants(expr)
print(simplified_expr)