简体   繁体   中英

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?

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

Think of "symbolic" functions as nouns and "non symbolic" as verbs.

noun-like        verb-like
----------       ---------
Integral         integrate
Derivative       diff
Sum              summation
Product          product

Those that are Python functions (I think what you mean by non-symbolic) emit some evaluated form of something that could also exist in an unevaluated form, eg prod(x, (x, 1, 5)) -> 120; Product(x, (x, 1, 5)) -> no change prod(x, (x, 1, 5)) -> 120; Product(x, (x, 1, 5)) -> no change .

It would be better to refer to them in some other way. What I think you mean is "evaluated" vs "non-evaluated" (since almost all of SymPy's functions will return SymPy objects with "symbols", even if numeric).

If the type(thing) -> function it is not a class itself, it is a Python function. If you check the type of cos or Sum you will not get function as the result.

Whereas some of the evaluates and unevaluated forms may have different names (Sum vs summation) others, like Add are evaluative by default but you can use the evaluate=False arg to stop that: Add(x, x) = x + x,= Add(x,x,evaluate=False) . Those which are evaluative can be made non-evaluative by passing evaluate=True , eg Derivative(x, x, evaluate=True) -> 1 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM