计算包含矩阵的符号函数的梯度和 Hessian

Calculating the Gradient and Hessian of a symbolic function containing Matrices

我有以下功能:

我想用它做几件事:

  1. 将其翻译成 SymPy 函数(完成)

    x = MatrixSymbol('x', 2, 1)
    fx = x.T * MatMul(Matrix([[1, 2], [4, 7]]), x) + x.T * Matrix([3, 5]) + 6*Identity(1)
    
    • 使用 display() 的输出似乎证实它正在工作:

  2. 计算点处的梯度和Hessian:

    • 在这一点上我尝试了以下渐变函数:

      v = list(ordered(fx.free_symbols))
      gradient = lambda f, v: Matrix([f]).jacobian(v)
      fxd = gradient(fx, v)
      

      然而,这输出 [0, 0] 作为不正确的结果。结果应该是:

    • 对于 hessian,我使用 SymPy 的内置函数尝试了以下操作:

      v = list(ordered(fx.free_symbols))
      fxdd = hessian(fx, v)
      

      但是,这个函数给我以下错误:

      ShapeError: Matrix size mismatch: (2, 2) + (2, 1)

      输出应该是:

所以,我的问题是,第二步的操作如何进行?

你可以用diff得到渐变。我不确定如何在不通过 as_explicit:

的情况下获得 Hessian
In [49]: x = MatrixSymbol('x', 2, 1)
    ...: fx = x.T * MatMul(Matrix([[1, 2], [4, 7]]), x) + x.T * Matrix([3, 5]) + 6*Identity(1)

In [50]: fx.diff(x) # gradient
Out[50]: 
⎡1  2⎤     ⎡1  4⎤     ⎡3⎤
⎢    ⎥⋅x + ⎢    ⎥⋅x + ⎢ ⎥
⎣4  7⎦     ⎣2  7⎦     ⎣5⎦

In [51]: hessian(fx.as_explicit(), x.as_explicit())  # Hessian
Out[51]: 
⎡2  6 ⎤
⎢     ⎥
⎣6  14⎦