How to convert exp() symbol from an expression to a numerical value? - python

I have this code:
from sympy import *
x = Symbol('x')
f = exp(x)+exp(x-0.1)+exp(-x-1) #Random Function
d = diff(f,x) #Differentiate f w.r.t x
a = d.subs({x:2}) #Put x=2
print(a)
The output is:
-exp(-3) + 1.90483741803596*exp(2)
But here, I don't want exp() to appear as a symbol. Rather, I want the numerical value of it.
Expected Output:
14.025163472842058
How do I replace the exp() symbol to fetch the numerical value?

Here is the Documentation for it: Documentation
But essentially a is an expression-object, in order to evaluate it you have to call something like evalf on it. Since you already did the substitution step you just need to call a.evalf() to get a number.
There are also other methods but those might need other dependencies.
For Example:
from sympy import *
x = Symbol('x')
f = exp(x)+exp(x-0.1)+exp(-x-1) #Random Function
d = diff(f,x) #Differentiate f w.r.t x
a = d.subs({x:2}) #Put x=2
print(a.evalf()) # prints: 14.0251634728421

Related

evalf and subs in sympy on single variable expression returns expression instead of expected float value

I'm new to sympy and I'm trying to use it to get the values of higher order Greeks of options (basically higher order derivatives). My goal is to do a Taylor series expansion. The function in question is the first derivative.
f(x) = N(d1)
N(d1) is the P(X <= d1) of a standard normal distribution. d1 in turn is another function of x (x in this case is the price of the stock to anybody who's interested).
d1 = (np.log(x/100) + (0.01 + 0.5*0.11**2)*0.5)/(0.11*np.sqrt(0.5))
As you can see, d1 is a function of only x. This is what I have tried so far.
import sympy as sp
from math import pi
from sympy.stats import Normal,P
x = sp.symbols('x')
u = (sp.log(x/100) + (0.01 + 0.5*0.11**2)*0.5)/(0.11*np.sqrt(0.5))
N = Normal('N',0,1)
f = sp.simplify(P(N <= u))
print(f.evalf(subs={x:100})) # This should be 0.5155
f1 = sp.simplify(sp.diff(f,x))
f1.evalf(subs={x:100}) # This should also return a float value
The last line of code however returns an expression, not a float value as I expected like in the case with f. I feel like I'm making a very simple mistake but I can't find out why. I'd appreciate any help.
Thanks.
If you define x with positive=True (which is implied by the log in the definition of u assuming u is real which is implied by the definition of f) it looks like you get almost the expected result (also using f1.subs({x:100}) in the version without the positive x assumption shows the trouble is with unevaluated polar_lift(0) terms):
import sympy as sp
from sympy.stats import Normal, P
x = sp.symbols('x', positive=True)
u = (sp.log(x/100) + (0.01 + 0.5*0.11**2)*0.5)/(0.11*sp.sqrt(0.5)) # changed np to sp
N = Normal('N',0,1)
f = sp.simplify(P(N <= u))
print(f.evalf(subs={x:100})) # 0.541087287864516
f1 = sp.simplify(sp.diff(f,x))
print(f1.evalf(subs={x:100})) # 0.0510177033783834

Python equation inputed by user

I'm trying to make some program which involves typing formulas in input by a user.
My code for now looks like so:
import numpy as np
n = int(input('Dim = '))
g = np.zeros((n, n))
for a in range(0, n):
print('Define the metric. \n g_', a, a,'=')
metric_component = 'lambda x, y: ' + str(input())
g[a, a] = eval(metric_component)
print(g)
I tried to search for answers but those i found didn't work. eval() function gives me error there: float() argument must be a string or a number, not 'function': sympify() gives basically the same "can't convert expression to float"
Also i want to work on those constants not their numeric values, so i'm interesting to keep them through all program and have the final output expressed by them. Is it even possible?
input() will return a string
>>> type(input()) # I type 1
1
<class 'str'>
So if you are expecting numeric input from the user and it can be non-integer, then just wrap the input with float.
import numpy as np
n = int(input('Dim = '))
g = np.zeros((n, n))
for a in range(0, n):
print('Define the metric. \n g_', a, a,'=')
g[a, a] = float(input())
print(g)
It's hard to tell what you want to be able to interpret from the user. If the user is going to give some expression of x and y and you are going to replace both those values with a you would either have to build a lambda that could be evaluated or do a substitution into a sympified expression:
>>> eval('(lambda x,y:'+'x + 2*y'+')(%s,%s)'%(a,a))
3*a
>>> sympify('x+2*y').subs(dict(x=a,y=a))
3*a
If you want the user to input expressions and then do something to them later, SymPy is ideally suited for this. Here, the user is prompted to fill items in a list and then those items are differentiated wrt x. It's just a toy example:
>>> from sympy import S # shortcut for sympify
>>> from sympy.abc import x
>>> [S(input('?')) for i in range(2)]
?R**2
?R**2*sin(x)**2
[R**2, R**2*sin(x)**2]
>>> [i.diff(x) for i in _]
[0, 2*R**2*sin(x)*cos(x)]

How to know whether a function is continuous with sympy?

I need to define a function that checks if the input function is continuous at a point with sympy.
I searched the sympy documents with the keyword "continuity" and there is no existing function for that.
I think maybe I should consider doing it with limits, but I'm not sure how.
def check_continuity(f, var, a):
try:
f = sympify(f)
except SympifyError:
return("Invaild input")
else:
x1 = Symbol(var, positive = True)
x2 = Symbol(var, negative = True)
//I don't know what to do after this
I would suggest you use the function continuous_domain. This is defined in the calculus.util module.
Example usage:
>>> from sympy import Symbol, S
>>> from sympy.calculus.util import continuous_domain
>>> x = Symbol("x")
>>> f = sin(x)/x
>>> continuous_domain(f, x, S.Reals)
Union(Interval.open(-oo, 0), Interval.open(0, oo))
This is documented in the SymPy docs here. You can also view the source code here.
Yes, you need to use the limits.
The formal definition of continuity at a point has three conditions that must be met.
A function f(x) is continuous at a point where x = c if
lim x —> c f(x) exists
f(c) exists (That is, c is in the domain of f.)
lim x —> c f(x) = f(c)
SymPy can compute symbolic limits with the limit function.
>>> limit(sin(x)/x, x, 0)
1
See: https://docs.sympy.org/latest/tutorial/calculus.html#limits
Here is a more simple way to check if a function is continues for a specific value:
import sympy as sp
x = sp.Symbol("x")
f = 1/x
value = 0
def checkifcontinus(func,x,symbol):
return (sp.limit(func, symbol, x).is_real)
print(checkifcontinus(f,value,x))
This code output will be - False

SymPy: how can i get the partial derivatives of one equation input beforehand by the user?

Im trying to build a constrained optimization calculator in python using the sympy module. The idea is that a user can enter two functions, "f" and "g", which then are put together to form the equation "L".
I want SymPy to give me the partial derivatives of x, y and lambda in "L", however my code does not seem to be working. When trying to get their partial derivatives i get the following results:
0
0
-x - 4*y + 500
I used x+100*y-y**2 as function 1 and x+4*y-500 and function 2.
Heres the code so far:
import sympy as sp
from sympy.parsing import sympy_parser
x, y = sp.symbols("x y", real=True)
lam = sp.symbols('lambda', real=True)
insert = input("Insert function 1:") #function 1
f = sympy_parser.parse_expr(insert) #transforming the function into a sympy expression
print(f)
insert2 = input("Insert function 2:") #function2
g = sympy_parser.parse_expr(insert2) #transforming function 2
L = f - lam*g #getting the equation "L"
xx = sp.diff(L, x) #partial derivative L'x
yy = sp.diff(L, y) #partial derivative L'y
ll = sp.diff(L, lam) #partial derivative L'lam
print(xx)
print(yy)
print(ll)
I have tried both the "parse_expr" and "simpify" commands to transform the functions input by the user from string to sympy expressions. I might be missing something else.
Your local x and y are real but those that the parser returns are vanilla, they have not assumptions. Since symbols match by name and assumptions, your input functions don't have (the same) x and y:
>>> f.has(x)
False
So either don't make your local symbols real
>>> var('x')
x
>>> f = sympy_parser.parse_expr(insert)
>>> f.has(x)
True
Or pass your local symbols to the parser so it can use them to build your functions:
>>> f = sympy_parser.parse_expr(insert, dict(x=x,y=y))
>>> f.has(x)
True
And once you are using the same symbols, the rest of your issues should move to a new level :-)

Sympy "global" substitution

I have a number of symbolic expressions in sympy, and I may come to realize that one of the coefficients is zero. I would think, perhaps because I am used to mathematica, that the following makes sense:
from sympy import Symbol
x = Symbol('x')
y = Symbol('y')
f = x + y
x = 0
f
Surprisingly, what is returned is x + y. Is there any way, aside from explicitly calling "subs" on every equation, for f to return just y?
I think subs is the only way to do this. It looks like a sympy expression is something unto itself. It does not reference the pieces that made it up. That is f only has the expression x+y, but doesn't know it has any link back to the python objects x and y. Consider the code below:
from sympy import Symbol
x = Symbol('x')
y = Symbol('y')
z = Symbol('z')
f1 = x + y
f2 = z + f1
f1 = f1.subs(x,0)
print(f1)
print(f2)
The output from this is
y
x + y + z
So even though f1 has changed f2 hasn't. To my knowledge subs is the only way to get done what you want.
I don't think there is a way to do that automatically (or at least no without modifying SymPy).
The following question from SymPy's FAQ explains why:
Why doesn't changing one variable change another that depends it?
The short answer is "because it doesn't depend on it." :-) Even though
you are working with equations, you are still working with Python
objects. The equations you are typing use the values present at the
time of creation to "fill in" values, just like regular python
definitions. They are not altered by changes made afterwards. Consider
the following:
>>> a = Symbol('a') # create an object with name 'a' for variable a to point to
>>> b = a + 1; b # create another object that refers to what 'a' refers to
a + 1
>>> a = 4; a # a now points to the literal integer 4, not Symbol('a')
4
>>> b # but b is still pointing at Symbol('a')
a + 1
Changing quantity a does not change b; you are not working with a set
of simultaneous equations. It might be helpful to remember that the
string that gets printed when you print a variable refering to a sympy
object is the string that was give to it when it was created; that
string does not have to be the same as the variable that you assign it
to:
>>> r, t, d = symbols('rate time short_life')
>>> d = r*t; d
rate*time
>>> r=80; t=2; d # we haven't changed d, only r and t
rate*time
>>> d=r*t; d # now d is using the current values of r and t
160
Maybe this is not what you're looking for (as it was already explained by others), but this is my solution to substitute several values at once.
def GlobalSubs(exprNames, varNames, values=[]):
if ( len(values) == 0 ): # Get the values from the
for varName in varNames: # variables when not defined
values.append( eval(varName) ) # as argument.
# End for.
# End if.
for exprName in exprNames: # Create a temp copy
expr = eval(exprName) # of each expression
for i in range(len(varNames)): # and substitute
expr = expr.subs(varNames[i], values[i]) # each variable.
# End for.
yield expr # Return each expression.
# End for.
It works even for matrices!
>>> x, y, h, k = symbols('x, y, h, k')
>>> A = Matrix([[ x, -h],
... [ h, x]])
>>> B = Matrix([[ y, k],
... [-k, y]])
>>> x = 2; y = 4; h = 1; k = 3
>>> A, B = GlobalSubs(['A', 'B'], ['x', 'h', 'y', 'k'])
>>> A
Matrix([
[2, -1],
[1, 2]])
>>> B
Matrix([
[ 4, 3],
[-3, 4]])
But don't try to make a module with this. It won't work. This will only work when the expressions, the variables and the function are defined into the same file, so everything is global for the function and it can access them.

Categories

Resources