【问题标题】:Computing taylor series of multivariate function with sympy用 sympy 计算多变量函数的泰勒级数
【发布时间】:2014-07-11 06:49:00
【问题描述】:

我正在尝试使用 SymPy 计算依赖于三角函数 sinc (here) 的函数的泰勒级数,为了简化我的问题,我们可以假设我需要 Taylor 的函数系列是:

f(x1, x2) = sinc(x1) * sinc(x2)

我的问题是在导入 sympy.mpmath 时经常出现错误:

无法从...创建 mpf

我曾尝试使用taylor-series 近似值或this other solution(第 1 号),但它们似乎都失败了。例如,对于后一种选择,该行:

(sinc(x)*sinc(y)).series(x,0,3).removeO().series(y,0,3).removeO()

返回:

无法从 x 创建 mpf

我也尝试将函数定义为表达式和 lambda 函数。但似乎没有任何效果。

任何帮助将不胜感激。

【问题讨论】:

    标签: python sympy taylor-series


    【解决方案1】:

    您不能将 mpmath 函数与符号 SymPy 对象一起使用。您需要象征性地定义sinc

    一种方法是将其定义为返回等效项的 Python 函数(这里 sinsympy.sin):

    def sinc(x):
        return sin(x)/x
    

    或者,您可以为它编写自己的 SymPy 类。

    class sinc(Function):
        @classmethod
        def eval(cls, x):
            if x == 0:
                return 1
            # Should also include oo and -oo here
            sx = sin(x)
            # Return only if sin simplifies
            if not isinstance(sx, sin):
                return sx/x
    
        # You'd also need to define fdiff or _eval_derivative here so that it knows what the derivative is
    

    后者让你可以写sinc(x),它会像那样打印出来,你也可以用它定义自定义行为,比如衍生的样子,系列的工作方式等等。这也可以让您在 0、oo 等处定义正确的值。

    但是为了进行系列,仅使用sin(x)/x(即第一个解决方案)就可以正常工作,因为您的最终答案无论如何都不会包含sinc,并且系列方法在在像 0 这样的点进行评估。

    【讨论】:

    • 还有一个开放的 SymPy 问题要实现 sinc github.com/sympy/sympy/issues/5051
    • 谢谢,我担心第一个解决方案因为 0 的限制而无法工作。但它确实如此。谢谢
    【解决方案2】:

    这是我刚刚编写的用于 Sympy 的多元泰勒级数展开式:

    def Taylor_polynomial_sympy(function_expression, variable_list, evaluation_point, degree):
        """
        Mathematical formulation reference:
        https://math.libretexts.org/Bookshelves/Calculus/Supplemental_Modules_(Calculus)/Multivariable_Calculus/3%3A_Topics_in_Partial_Derivatives/Taylor__Polynomials_of_Functions_of_Two_Variables
        :param function_expression: Sympy expression of the function
        :param variable_list: list. All variables to be approximated (to be "Taylorized")
        :param evaluation_point: list. Coordinates, where the function will be expressed
        :param degree: int. Total degree of the Taylor polynomial
        :return: Returns a Sympy expression of the Taylor series up to a given degree, of a given multivariate expression, approximated as a multivariate polynomial evaluated at the evaluation_point
        """
        from sympy import factorial, Matrix, prod
        import itertools
    
        n_var = len(variable_list)
        point_coordinates = [(i, j) for i, j in (zip(variable_list, evaluation_point))]  # list of tuples with variables and their evaluation_point coordinates, to later perform substitution
    
        deriv_orders = list(itertools.product(range(degree + 1), repeat=n_var))  # list with exponentials of the partial derivatives
        deriv_orders = [deriv_orders[i] for i in range(len(deriv_orders)) if sum(deriv_orders[i]) <= degree]  # Discarding some higher-order terms
        n_terms = len(deriv_orders)
        deriv_orders_as_input = [list(sum(list(zip(variable_list, deriv_orders[i])), ())) for i in range(n_terms)]  # Individual degree of each partial derivative, of each term
    
        polynomial = 0
        for i in range(n_terms):
            partial_derivatives_at_point = function_expression.diff(*deriv_orders_as_input[i]).subs(point_coordinates)  # e.g. df/(dx*dy**2)
            denominator = prod([factorial(j) for j in deriv_orders[i]])  # e.g. (1! * 2!)
            distances_powered = prod([(Matrix(variable_list) - Matrix(evaluation_point))[j] ** deriv_orders[i][j] for j in range(n_var)])  # e.g. (x-x0)*(y-y0)**2
            polynomial += partial_derivatives_at_point / denominator * distances_powered
        return polynomial
    

    这是一个二变量问题的验证,遵循以下练习和答案:https://math.libretexts.org/Bookshelves/Calculus/Supplemental_Modules_(Calculus)/Multivariable_Calculus/3%3A_Topics_in_Partial_Derivatives/Taylor__Polynomials_of_Functions_of_Two_Variables

    # Solving the exercises in section 13.7 of https://math.libretexts.org/Bookshelves/Calculus/Supplemental_Modules_(Calculus)/Multivariable_Calculus/3%3A_Topics_in_Partial_Derivatives/Taylor__Polynomials_of_Functions_of_Two_Variables
    from sympy import symbols, sqrt, atan, ln
    
    # Exercise 1
    x = symbols('x')
    y = symbols('y')
    function_expression = x*sqrt(y)
    variable_list = [x,y]
    evaluation_point = [1,4]
    degree=1
    print(Taylor_polynomial_sympy(function_expression, variable_list, evaluation_point, degree))
    degree=2
    print(Taylor_polynomial_sympy(function_expression, variable_list, evaluation_point, degree))
    
    # Exercise 3
    x = symbols('x')
    y = symbols('y')
    function_expression = atan(x+2*y)
    variable_list = [x,y]
    evaluation_point = [1,0]
    degree=1
    print(Taylor_polynomial_sympy(function_expression, variable_list, evaluation_point, degree))
    degree=2
    print(Taylor_polynomial_sympy(function_expression, variable_list, evaluation_point, degree))
    
    # Exercise 5
    x = symbols('x')
    y = symbols('y')
    function_expression = x**2*y + y**2
    variable_list = [x,y]
    evaluation_point = [1,3]
    degree=1
    print(Taylor_polynomial_sympy(function_expression, variable_list, evaluation_point, degree))
    degree=2
    print(Taylor_polynomial_sympy(function_expression, variable_list, evaluation_point, degree))
    
    # Exercise 7
    x = symbols('x')
    y = symbols('y')
    function_expression = ln(x**2+y**2+1)
    variable_list = [x,y]
    evaluation_point = [0,0]
    degree=1
    print(Taylor_polynomial_sympy(function_expression, variable_list, evaluation_point, degree))
    degree=2
    print(Taylor_polynomial_sympy(function_expression, variable_list, evaluation_point, degree))
    

    对结果执行simplify() 会很有用。

    【讨论】:

      猜你喜欢
      • 2017-06-29
      • 2019-05-27
      • 1970-01-01
      • 2016-04-26
      • 2020-03-01
      • 2015-05-15
      • 1970-01-01
      • 1970-01-01
      • 2017-03-20
      相关资源
      最近更新 更多