在 SymPy 中替换 derive_by_array 结果中的变量值

Substitute values for variables in the result of derive_by_array in SymPy

我目前正在做一些关于多变量函数微积分的练习,我想我可以尝试制作自己的函数来确定任何函数在定义点处的梯度和 hessian。我目前在尝试用任意函数的坐标值替换结果矩阵时遇到问题。我已经设法解决了具体的例子,但是我尝试创建一个函数来解决用户定义的函数并没有正常工作。

def multivariable_function(function, variables, substitute=(0,0)):
"""Determines Gradient and Hessian vectors for multivariable function.

  Args:
    function: Enter the multivariable function
    variables: Enter list of variable names
    substitute: Default = (0,0)

  Returns:
    gradient/hessian matrices for given coordinate 

  To do:
    Include sympy symbol() generation within function
  """

  #derive_by_array returns a gradient matrix for multivariable function
  Gradient = simplify(derive_by_array(function, variables))

  #derive_by_array returns a Hessian matrix for multivariable function                   
  Hessian = simplify(derive_by_array(derive_by_array(function, variables), variables))

  #Line currently isn't doing anything
  Gradient.subs(zip(variables, substitute))

  return Gradient, Hessian

这是目前运行的基本功能。

multivariable_function((x**2)*(y**3) + exp(2*x + x*y - 1) - (x**3 + 3*y**2)**2, (x,y))`

产生以下 result, I am however aiming to substitute the desired values into the gradient and hessian matrices to achieve the following desired result。我设法使用以下方法实现了预期的结果。

from sympy import *

x, y, z, K, T, r, σ, h, a, f, μ, c, t, m, x1, x2, x3 = symbols('x, y, z, K, T, r, σ, h, a, f, μ, c, t, m, x1, x2, x3') # Variables used must be defined in sympy.
init_printing(use_unicode=False) #Print the answers in unicode characters

function = (x**2)*(y**3) + exp(2*x + x*y - 1) - (x**3 + 3*y**2)**2

Gradient_1 = simplify(derive_by_array(function, (x, y)))
Hessian_1 = simplify(derive_by_array(derive_by_array(function, (x, y)), (x, y)))

Gradient_1.subs(x, 0).subs(y,0), Hessian_1.subs(x,0).subs(y,0)

查看 here 提出的问题后,似乎压缩两个列表应该可以使 subs() 函数工作,但目前不适合我。我试图循环遍历 'variables 和 'substitute' 以顺序应用 .subs(),但是我发现该函数仅在该方法为所有替换变量链接时才有效,如上例所示。

有谁知道如何为给定坐标应用 .subs() n 次以产生相关的 gradient/hessian 矩阵?

变量Gradient的类型是

sympy.tensor.array.dense_ndim_array.ImmutableDenseNDimArray

与几乎所有 SymPy 对象一样,除了可变矩阵,它是不可变的。方法subs并没有原地修改;它 returns 一个新对象,需要分配。

  Gradient = Gradient.subs(zip(variables, substitute))
  Hessian = Hessian.subs(zip(variables, substitute))

然后函数按预期运行,返回

([2*exp(-1), 0], [[4*exp(-1), exp(-1)], [exp(-1), 0]])

但我建议不要将生成器传递给 subs;这方面有一些悬而未决的问题。为了安全起见,请先转换为列表或字典。 (这里也有区别:替换应该是连续的还是同时的,虽然这在用数字替换符号时无关紧要。)

  subs_dict = dict(zip(variables, substitute))
  Gradient = Gradient.subs(subs_dict)
  Hessian = Hessian.subs(subs_dict)