So I'm writing a script that evaluates Taylor Series. However, I want it to evaluate for all types of functions. So I tried, for example, using the function acot(x)
.
x = sy.Symbol('x')
f = acot(x)
...
func = taylor(f,0,3)
taylor_lambda = sy.lambdify(x, func, 'numpy')
The above runs without an exception (except if I use acsch
, for example, and it does not run).
But then when it reaches this line:
plt.plot(x1,taylor_lambda(x1),label='taylor approximation')
I get:
NameError: name 'acot' is not defined
I tried to replace numpy
with sympy
in the lambdify call but this seems to evaluate symbolically. This is happening with some (more rare functions) but not for others. Thank you!
My imports are as follows:
import sympy as sy
import numpy as np
from sympy.functions import *
from sympy import pi, E,acot
import matplotlib.pyplot as plt
import math
You can do so by simply assigning the expression to a variable f which will be your function. The sympy. symbols() method is used to declare variables for the mathematical function. The f(symbol(x)) will give a symbolic 2x.
lambdify() method. With the help of sympy. lambdify() method, we can convert a SymPy expression to an expression that can be numerically evaluated. lambdify acts like a lambda function, except it, converts the SymPy names to the names of the given numerical library, usually NumPy or math.
The subs() function in SymPy replaces all occurrences of the first parameter with the second. Substitution is the basic operations that must be performed in a mathematical expression. In this way, we can use subs() function in sympy.
When working with symbols in Sympy it would sometimes be useful for the library to understand that a symbol refers only to a certain subset of the complex numbers. Example: theta = sympy.
The main issue here is that the lambdify
function uses the modules
argument to define available modules for the supplied function. It seems acot
is not available within the numpy
namespace.
Lets reduce this down to something simple:
import sympy as sy
import numpy as np
from sympy.functions import *
x = sy.Symbol('x')
f = acot(x)
func_lambda = sy.lambdify(x, f, modules='numpy')
print(func_lambda(1))
This raises a NameError
as acot
is not defined in the numpy
namespace. Note the modules argument. If we extend the available modules to sympy
, we no longer get a NameError
:
func_lambda = sy.lambdify(x, f, modules=['numpy', 'sympy'])
print(func_lambda(1))
# Prints pi/4
If you're having trouble with odd functions, you can also add individual functions to the lambdify modules parameter as a dictionary of func_name
: function
pairs:
func_lambda = sy.lambdify(x, f, modules=['numpy', {'acot':acot}])
print(func_lambda(1))
# Prints pi/4
As far as plotting using matplotlib, vectorizing the equation and then plotting works for me:
import matplotlib.pyplot as plt
vfunc = np.vectorize(func_lambda)
x1 = np.linspace(-10, 10 , 1000)
plt.plot(x1, vfunc(x1),label='acot')
plt.show()
I did have similar problems before and have managed to solve them.Your line
plt.plot(x1,taylor_lambda(x1),label='taylor approximation')
looks OK.I am giving one my older code that works fine,you can just compare.
from sympy.abc import x
from sympy import sin, series
from sympy.utilities.lambdify import lambdify
import numpy as np
import matplotlib.pyplot as plt
func = sin(x)/x
taylor = series(func, n=6).removeO()
evalfunc = lambdify(x, func, modules=['numpy'])
evaltaylor = lambdify(x, taylor, modules=['numpy'])
t = np.linspace(-7.5, 7.5 , 100)
plt.plot(t, evalfunc(t), 'b', label='sin(x)/x')
plt.plot(t, evaltaylor(t), 'r', label='Taylor')
plt.legend(loc='best')
plt.show()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With