Search code examples
sympysymbolic-mathisinstance

sympy: sympy function symbolic or non-symbolic


I am trying to understand about sympy's symbolic functions:

import sympy from sympy.abc import x,y,z

with sympy.evaluate(False):
    print(sympy.sympify("diff(x,x)").func)
    print(sympy.parse_expr("diff(x, x)", local_dict={'diff':sympy.Derivative}).func)
    print(sympy.sympify("Derivative(x,x)").func)
    pass

This puts out:

Piecewise
<class 'sympy.core.function.Derivative'>
<class 'sympy.core.function.Derivative'>

This example should illustrate that diff is not a symbolic function yet Derivative is. sympy.sympify("diff(x,x)").func results in Piecewise. What exactly makes a function in sympy 'symbolic'? Why don't both of the functions belong to <class 'sympy.core.function.Derivative'>?

I tried to test on a few examples if a function is symbolic using:

list_of_funcs = [sin, cos, tan, sec, csc, cot, sinh, cosh, tanh, sech, csch, coth, asin, acos, atan, asec, acsc, acot, asinh, acosh, atanh, asech, acsch, acoth, log, log, log, exp, <class 'sympy.concrete.summations.Sum'>, <class 'sympy.concrete.products.Product'>, Piecewise, jacobi, Piecewise]
with sympy.evaluate(False):
    for f in list_of_funcs:
        if issubclass(f, sympy.Basic):
            print(f'{f}: True')

It returned True for all yet as far as I understood Piecewise is not symbolic. Could you help me finding a way to test if a function is symbolic?


Solution

  • Answering this question without going too deep into coding concepts is not easy, but I can give it a try.

    SymPy exposes many functions:

    • cos, sin, exp, Derivative, Integral... we can think of them as symbolic functions. Let's say you provide one or more arguments, then:
      • the function might evaluate to some symbolic numerical value. For example, cos(0) will return the symbolic number 1.
      • the function might return an "unevaluated" object. For example, cos(x) returns cos(x): this is a symbolic expression of type cos (as you have seen by running the func attribute). Similarly, you can create a derivative object Derivative(expr, x): this is a symbolic expression that represents a derivative, it doesn't actually compute the derivative!
    • Unevaluate functions, for example Function("f")(x), which will render as f(x): this is a symbolic expression of type f.
    • diff, integrate, series, limit, ... : those are ordinary python functions (for example, created with def diff(...)) that are going to apply some operation to a symbolic expression. When you call diff(expr, x) you are asking SymPy to compute the derivative of expr with respect to x. What if you wanted to represent the derivative without actually computing it? You write Derivative(expr, x).

    So, going back to your example:

    sympy.parse_expr("diff(x, x)", local_dict={'diff':sympy.Derivative})
    

    this can be easily simplified to:

    sympy.parse_expr("Derivative(x, x)")
    

    A few more "relationships":

    • diff and Derivative
    • integrate and Integral
    • limit and Limit