如何使用 Sympy 推导矩阵元素
How to derive with respect to a Matrix element with Sympy
给定矩阵和向量的乘积
A.v
形状为 (m,n) 的 A 和 dim n 的 v,其中 m 和 n 是符号,我需要计算关于矩阵元素的导数。
我还没有找到使用合适向量的方法,所以我从 2 MatrixSymbol
:
开始
n, m = symbols('n m')
j = tensor.Idx('j')
i = tensor.Idx('i')
l = tensor.Idx('l')
h = tensor.Idx('h')
A = MatrixSymbol('A', n,m)
B = MatrixSymbol('B', m,1)
C=A*B
现在,如果我尝试使用索引对 A 的一个元素进行推导,我会得到未计算的表达式:
diff(C, A[i,j])
>>>> Derivative(A*B, A[i, j])
如果我也在 C 中引入索引(它不会让我在结果向量中只使用一个索引),我会得到表示为 Sum 的乘积:
C[l,h]
>>>> Sum(A[l, _k]*B[_k, h], (_k, 0, m - 1))
如果我根据矩阵元素得出这个结果,我最终得到 0 而不是带有 KroneckerDelta
的表达式,这是我想要得到的结果:
diff(C[l,h], A[i,j])
>>>> 0
我想知道我是否不应该首先使用 MatrixSymbols。我应该如何实现我想要的行为?
SymPydoes not yet know matrix calculus;特别是,无法区分 MatrixSymbol
个对象。您可以使用充满符号数组的 Matrix
对象进行此类计算;缺点是矩阵大小必须明确才能起作用。
示例:
from sympy import *
A = Matrix(symarray('A', (4, 5)))
B = Matrix(symarray('B', (5, 3)))
C = A*B
print(C.diff(A[1, 2]))
输出:
Matrix([[0, 0, 0], [B_2_0, B_2_1, B_2_2], [0, 0, 0], [0, 0, 0]])
SymPy 的 git 版本(以及下一个版本)处理得更好:
In [55]: print(diff(C[l,h], A[i,j]))
Sum(KroneckerDelta(_k, j)*KroneckerDelta(i, l)*B[_k, h], (_k, 0, m - 1))
给定矩阵和向量的乘积
A.v
形状为 (m,n) 的 A 和 dim n 的 v,其中 m 和 n 是符号,我需要计算关于矩阵元素的导数。
我还没有找到使用合适向量的方法,所以我从 2 MatrixSymbol
:
n, m = symbols('n m')
j = tensor.Idx('j')
i = tensor.Idx('i')
l = tensor.Idx('l')
h = tensor.Idx('h')
A = MatrixSymbol('A', n,m)
B = MatrixSymbol('B', m,1)
C=A*B
现在,如果我尝试使用索引对 A 的一个元素进行推导,我会得到未计算的表达式:
diff(C, A[i,j])
>>>> Derivative(A*B, A[i, j])
如果我也在 C 中引入索引(它不会让我在结果向量中只使用一个索引),我会得到表示为 Sum 的乘积:
C[l,h]
>>>> Sum(A[l, _k]*B[_k, h], (_k, 0, m - 1))
如果我根据矩阵元素得出这个结果,我最终得到 0 而不是带有 KroneckerDelta
的表达式,这是我想要得到的结果:
diff(C[l,h], A[i,j])
>>>> 0
我想知道我是否不应该首先使用 MatrixSymbols。我应该如何实现我想要的行为?
SymPydoes not yet know matrix calculus;特别是,无法区分 MatrixSymbol
个对象。您可以使用充满符号数组的 Matrix
对象进行此类计算;缺点是矩阵大小必须明确才能起作用。
示例:
from sympy import *
A = Matrix(symarray('A', (4, 5)))
B = Matrix(symarray('B', (5, 3)))
C = A*B
print(C.diff(A[1, 2]))
输出:
Matrix([[0, 0, 0], [B_2_0, B_2_1, B_2_2], [0, 0, 0], [0, 0, 0]])
SymPy 的 git 版本(以及下一个版本)处理得更好:
In [55]: print(diff(C[l,h], A[i,j]))
Sum(KroneckerDelta(_k, j)*KroneckerDelta(i, l)*B[_k, h], (_k, 0, m - 1))