lambdify expressions with native sympy functions - python

I would like to lambdify sympy's exp, but I run into funny issues when trying to evaluate the function at a sympy.Symbol. This
import sympy
t = sympy.Symbol('t')
f = sympy.lambdify(t, t**2)
f(t) # no problem
works fine, but this
t = sympy.Symbol('t')
f = sympy.lambdify(t, sympy.exp(t))
f(t)
gives
AttributeError: 'Symbol' object has no attribute 'exp'
The same goes for all other native sympy functions I've tried (log, sin, etc.).
Any idea what's going on?

You should specify modules you want to use with modules argument of the lambdify function:
f = sympy.lambdify(t, sympy.exp(t), modules=["sympy"])

The main use of lambdify is to allow for a fast numerical evaluation of expressions.
This is achieved by replacing abstract and slow SymPy functions (like sympy.exp) with faster ones intended for numbers (like math.exp or numpy.exp).
These cannot handle SymPy symbols (like your t) as an argument, which is not what lambdify is intended for anyway.
If you call lambdify with dummify=False as an additional argument, you get a more meaningful error, when calling f(t), namely:
TypeError: can't convert expression to float
The expression that cannot be converted here is your argument t.
If you want to use a lambdified function with symbols as an argument for some reason, you need to pass modules=["sympy"] as an additional argument to lambdify.
This argument specifies which module lambdify uses to replace SymPy functions (like sympy.exp) – in this case, it’s sympy again, so nothing actually happens.

Related

parse_expr() in sympy not working no matter the arguments I include

I'm trying to make a program that takes user input to answer the correct mathematical expression using a variable 's' but every time I use parse_expr and then try to do mathematical operations on the user-inputted expression to determine equality, I get an error saying "can only concatenate str (not int) onto str", which lets me know that the parse_expr function did not do what it was supposed to do. I have tried including the relevant arguments but to no avail. What am I missing? (This is test code and not exactly what I'm including in my program but it still doesn't work)
import sympy as sp
from sympy.parsing.sympy_parser import parse_expr
s = sp.symbols('s')
expression = '25*s + 40 + 25*s'
parse_expr(expression, local_dict={'s': s})
expression += 10
print(expression)

Viewing class definition of built-in classes in Python like Symbol

I am very new to Python (switching from Matlab) and I am currently working with the SymPy package. I realised that I can calculate the derivate of a function with f.diff(x), even when I have not imported the diff function. So, basically f.diff(x) works but diff(f,x) returns an error.
from sympy import symbols
x = symbols('x')
f = x**2 + 1
f.diff(x)
The reason that I could think of was that diff is actually defined as a method attribute for the class Symbol and thus, f.diff(x) works as long as x is of Symbol type and f has been defined using x. Is there a way to somehow view the Symbol class definition in order to verify that a diff method attribute actually exists?
The reason that I could think of was that diff is actually defined as a method attribute for the class Symbol and thus, f.diff(x) works as long as x is of Symbol type and f has been defined using x.
This is mostly correct (corrections below).
In contrast to Matlab, Python uses namespaces. This means that you only have very basic functions, classes, etc. available by default and everything else needs to be imported into the main namespace or is only available with a “prefix” specifying the namespace. What you gain from this is that you avoid name clashes and it’s easy to trace from which module a function is coming. For instance, in your example, the reader can see that symbols was imported from the sympy module (into the main namespace). This module also has a diff function (not the method) that you could use after importing with from sympy import diff.
In this sense, each object comes along with its own namespace, which is for most practical purposes determined by its class¹.
Functions in this namespace are called methods and (usually) do something on the object itself or using the specifics of the object itself.
Now, for the promised corrections or clarifications:
It is f’s class which is relevant here, not x’s.
You can see the class of f with type(f) and it is Add (residing in sympy.core.add).
This is because it is primarily a sum (of x**2 and 1).
More importantly, Add is a subclass of Expr (expression), which is the parent class for all SymPy expressions.
For example, the class Symbol is also a subclass of Expr.
(You can see this with type(f).mro().)
And this is the important thing here: All SymPy expressions have the diff method.
It is actually not relevant that the argument of f.diff is a Symbol or Expr.
It only needs to be something that SymPy can reasonably interpret as one.
For example f.diff("x") also works, because SymPy can translate the string "x" to a Symbol that is equivalent to your x.
Is there a way to somehow view the Symbol class definition in order to verify that a diff method attribute actually exists?
Yes. The easiest way is the basic Python function dir, which returns a list of all attributes (everything accessible by the . operator) of an object. Typically, most of these are methods. In you case, you can just call dir(f). Note that this lists also contains quite some attributes starting with _, which indicates that they are not designated for user consumption. In any reasonable programming environment (IDE, IPython, Jupyter), this list is also shown to you when you use tab completion (F, ., Tab).
However, while learning about a class by going through all its methods is usually a good approach, for SymPy expressions this is not feasible.
There is a lot of things somebody could want to do with these expressions, but you will only ever use a fraction of them.
Instead, you can either guess the name of the method and thus narrow down your search considerable.
For example, you can guess that the method for differentiation starts with a d (be it for differentiate or derivative), and here the tab completion (F, ., D, Tab) only gives you four results instead of three hundred.
Another approach is that you start searching the documentation (or the Internet in general) with what your operation of interest (here differentiating) instead of your the object of your operation (here, SymPy expressions, i.e., instances of Expr). After all SymPy is all about the latter, so that is kind of a given.
Finally, normally there is a documentation of a class featuring all its methods.
For Expr, this is here.
Unfortunately, in case of Expr the documentation is not exhaustive, e.g., it lacks the diff method.
While this is not ideal, it is somewhat understandable given the amount of methods as well as the duality of methods and functions of SymPy: For most methods of Expr, an analogous function can be directly imported from sympy.
¹ You can also just add stuff there (symbols.wrzlprmft = "foo"), but that’s a pretty advanced and rare usage. Also some classes are made to block this, e.g., you cannot do f.wrzlprmft = "foo".

Incomplete gamma function does not accept complex value inputs

I'm trying to compute the upper incomplete gamma function defined like in this post. If I use
from scipy.special import gamma,gammainc
from numpy import linspace
a = 0
z = (2+3j)*np.linspace(0,10)
gamma(a)*(1-gammainc(a,z))
where z is a complex vector I get an error
TypeError: ufunc 'gammainc' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
Is there an alternative function to do the calculation? There doesn't seem to be a problem when I try to do this with WolframAlpha's Gamma function.
When SciPy is not enough for tricky special functions, mpmath usually comes to the rescue. Compare
>>> mpmath.gammainc(0, 2+3j)
mpc(real='-0.024826207944199364', imag='0.020316674911044622')
and the same from Wolfram Alpha.
Being written in Python, it is slower than SciPy; it is also not vectorized. So with your data it would work like
import mpmath
result = np.array([mpmath.gammainc(w) for w in z[1:]], dtype=np.complex)
Note that I avoid passing 0 as the argument (it's a pole). The return type of mpmath.gammainc is its own mpc object type, but it can be converted back to NumPy as above.

What does the "X2[,Out]" and " = <ufunc 'copysign'>" mean in this doc page?

numpy.copysign
I know how this function works, but I can't fully understand what this title description mean.
Like
x2[, out]
what does this parameter mean? Is it a datatype in python?
and
" = < ufunc 'copysign'> "
I have see something like this several times when I look through the documents.
Can anybody help? Thank you so much.
The brackets are standard Python documentation syntax for optional parameters to a function call. From the Python Language Reference Introduction:
a phrase enclosed in square brackets ([ ]) means zero or one occurrences (in other words, the enclosed phrase is optional)
You'll notice it all over the place in Python & its libraries' documentation.
The = <ufunc 'func_name'> bit is to let you know that the function is an instance of the numpy.ufunc class. From the NumPy docs on Universal Functions:
A universal function (or ufunc for short) is a function that operates
on ndarrays in an element-by-element fashion, supporting array
broadcasting, type casting, and several other standard features. That
is, a ufunc is a “vectorized” wrapper for a function that takes a
fixed number of scalar inputs and produces a fixed number of scalar
outputs.
In NumPy, universal functions are instances of the numpy.ufunc class. Many of the built-in functions are implemented in compiled C code, but ufunc instances can also be produced using the frompyfunc factory function.

Pass a formula as a function parameter in python

I want to pass a formula within a function parameter in Python where the formula is a combination of the other function parameters. In principle this would look like this:
myfunction(x=2,y=2,z=1,formula="x+2*y/z")
6
or more generaly:
def myformula(x,y,z,formula):
return formula(x,y,z)
This would allow the user to choose any arithmetic expression in terms of x, y, and z without having to create a new function.
One of the possibility I foresee is to convert the string in line of code within the function. Anything possible like that in Python? Or any other ideas?
Thanks
Using sympy, you could evaluate mathematical expressions:
import sympy as sy
def myformula(formula, **kwargs):
expr = sy.sympify(formula)
return expr.evalf(subs=kwargs)
print(myformula(x=2,y=2,z=1,formula="x+2*y/z"))
# 6.00000000000000
print(myformula(x=2,y=2,z=1,formula="sin(x+y-z)"))
# 0.141120008059867
But note that sympy.sympify does use eval which makes it unsafe to apply to arbitrary user input
since strings can be composed to trick eval into executing arbitrary Python code.
A safer alternative is to build a parser to parse a strictly limited mathematical expressions.
Here are a few examples
Parsing expressions using ast
Using Paul McGuire's pyparsing
Your "myFormula" isn't much different than a regular lambda expression, except with the added baggage of having to parse a string into executable Python.
(lambda x,y,z: x + 2*y/z)(5, 2, 10)
As such, you could simply define myFormula as
def myFormula(*args, formula):
formula(*args)
and call it as
myFormula(5, 2, 10, lambda x, y, z: x + 2*y/z)
You could try using a lambda function. Something like this might suit you:
def myFormula(x,y,z):
return lambda x,y,z: x+2*y/z
This way you don't have to define a new function and you don't have to pass anything extra as an argument.
Extra info about lambda functions: http://www.diveintopython.net/power_of_introspection/lambda_functions.html
http://pythonconquerstheuniverse.wordpress.com/2011/08/29/lambda_tutorial/
https://docs.python.org/2/reference/expressions.html#lambda

Categories