Reputation: 140
I have a very complicated non-linear function f. I want to get taylor series till degree n in a form of sympy expression for the function f at value x. f is a regular python function not a sympy expression. Output of get_polynomial should be a sympy expression.
Is there any function that will get taylor-series of a function?
from math import sin, cos, log, e
def f(x):
# a very complicated function
y = sin(x) + cos(x) + log(abs(x)+2)**2/e**2 + sin(cos(x/2)**2) + 1
return y
def get_polynomial(function, x, degree):
# .......
# using Taylor Series
# .......
return sympy_expression_for_function_at_value_x
Output:
get_polynomial(sin, 0, 3) ---> 0 + x + 0*x**2 + (1/6)*x**3
get_polynomial(lambda x: e**x, 0, 1) --> 1 + x
In a similar manner I wanna calculate get_polynomial(f, 0, 3)
Upvotes: 0
Views: 2836
Reputation: 3347
The following code is close to what you're looking for. What this does it to parse the code the of the function you wish you expand into a Taylor series, convert it into a symbolic representation using Sympy and then compute the Taylor expansion.
One limitation is that you need to have an explicit function definition so you can't use lambda expressions. This can be solved with further work. Otherwise the code does what you ask for. Note that when you define a function, it has to contain a line of the form y = ...
for this code to work
from inspect import *
import sympy
def f(x):
# a very complicated function
y = sin(x) + cos(x) + log(abs(x)+2)**2/e**2 + sin(cos(x/2)**2) + 1
return y
def my_sin(x):
y = sin(x)
return y
def my_exp(x):
y = e**x
return y
x = sympy.Symbol('x')
def get_polynomial(function, x0, degree):
# parse function definition code
lines_list = getsource(function).split("\n")
for line in lines_list:
if '=' in line:
func_def = line
elements = func_def.split('=')
line = ' '.join(elements[1:])
sympy_function = sympy.sympify(line)
# compute taylor expansion symbolically
i = 0
taylor_exp = sympy.Integer(0)
while i <= degree:
taylor_exp = taylor_exp + (sympy.diff(sympy_function,x,i).subs(x,x0))/(sympy.factorial(i))*(x-x0)**i
i += 1
return taylor_exp
print (get_polynomial(my_sin,0,5))
print (get_polynomial(my_exp,0,5))
print (get_polynomial(f,0,5))
Upvotes: 2