【问题标题】:Taylor series sympy expression of a python functionpython函数的泰勒级数sympy表达式
【发布时间】:2019-05-27 14:10:48
【问题描述】:

我有一个非常复杂的非线性函数 f。我想以值 x 的函数 f 的 sympy 表达式的形式获得泰勒级数直到 n 级。 f 是一个常规的 python 函数,而不是一个 sympy 表达式。 get_polynomial 的输出应该是一个 sympy 表达式。

有没有可以得到泰勒级数的函数?

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

输出:

get_polynomial(sin, 0, 3) ---> 0 + x + 0*x**2 + (1/6)*x**3
get_polynomial(lambda x: e**x, 0, 1) --> 1 + x

以类似的方式我想计算get_polynomial(f, 0, 3)

【问题讨论】:

  • 我认为你希望你的 input 函数是一个常规的 Python 函数但你希望你的 output 多项式是一个 sympy 多项式是正确的吗?如果是这样,您如何期望 sympy 中的精确输出来自 Python 中的近似函数(因为 Python 中的浮点计算只是近似值)?或者您是否希望您的输入函数成为一个 sympy 函数,如“可能重复”评论中的链接?
  • 是的,输入函数应该是一个普通的python函数,输出应该是一个sympy表达式@RoryDaulton
  • 那么实际上不可能得到 sin 的多项式中的值 1/6。 Python 浮点甚至无法准确存储该值,更不用说计算它了。 Python 例程可以得到一个接近 1/6 的常数,但不完全等于它。您可以将该值近似为一个分数,但您需要给出某种公差,并且您可能会得到一个实际上应该是非理性的值的错误分数。
  • 输出多项式应该有多精确?由于您只需要 taylor 系列的前 n 个成员,因此您已经接受了一些错误。

标签: python math sympy taylor-series


【解决方案1】:

以下代码与您要查找的代码接近。它是做什么来解析您希望展开为泰勒级数的函数的代码,使用 Sympy 将其转换为符号表示,然后计算泰勒展开式。

一个限制是您需要有一个明确的函数定义,因此您不能使用 lambda 表达式。这可以通过进一步的工作来解决。否则,代码会按照您的要求执行。请注意,当您定义一个函数时,它必须包含y = ... 形式的行,此代码才能工作

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))

【讨论】:

  • 感谢您的努力。您的解决方案似乎效果很好。如果我们能得到简化的系数值,那就太好了。例如在 get_polynomial(my_exp,0,5) 中,如果我们可以得到 x**2 的 co-eff 为 (1/2) 或 0.5 或 ~0.5 而不是 log(e)**2/2
  • 写函数的时候用E代替e,比如用y = E**x代替y=e**x
猜你喜欢
  • 2014-07-11
  • 1970-01-01
  • 2017-04-02
  • 2022-06-18
  • 2016-01-24
  • 2017-06-29
  • 2014-04-03
  • 2017-06-14
  • 1970-01-01
相关资源
最近更新 更多