Is there a way to handle constant function parameters in SymPy?

ghz 12hours ago ⋅ 2 views

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)