SymPy中二阶张量wrt本身的行列式和逆的导数

时间:2019-07-01 15:00:09

标签: python sympy tensor calculus

我已经在计算科学论坛中提出了这个问题。 https://scicomp.stackexchange.com/q/32973/24915已建议我在此论坛中提问。

我有一个二阶张量( F ),我需要为其计算行列式和逆w.r.t的导数。本身。这些基本上就是matrix cookbook中的方程式(49)和(60)。

我已经与SymPy合作了大约一周。我可以得到 F 本身的导数,但无法弄清楚如何获得其行列式和反函数的导数。作为参考,我将发布代码和输出以及错误消息。

Python代码

from sympy import *

i = tensor.Idx('i',3)
j = tensor.Idx('j',3)
k = tensor.Idx('k',3)
l = tensor.Idx('l',3)

F = MatrixSymbol('F', 3, 3)

print("Derivative of F wrt F")
print("---------------------")
print(diff(F[k,l], F[i,j]))
print("\n")


J = det(F)
print("Derivative of det(F) wrt F")
print("--------------------------")
print(diff(J, F[i,j]))
print("\n")

print("Derivative of inv(F) wrt F")
print("--------------------------")
Finv = Inverse(F)
print(Finv[i,j])
print(diff(Finv[k,l], F[i,j]))
print("\n")

输出

Derivative of F wrt F
---------------------------
KroneckerDelta(i, k)*KroneckerDelta(j, l)

Derivative of det(F) wrt F
-------------------------------
Derivative(Determinant(F), F[i, j])

Derivative of inv(F) wrt F
-------------------------------
Traceback (most recent call last):
  File "matdiffinverse.py", line 25, in <module>
    print(Finv[i,j])
  File "/usr/lib/python3/dist-packages/sympy/matrices/expressions/matexpr.py", line 248, in __getitem__
return self._entry(i, j)
  File "/usr/lib/python3/dist-packages/sympy/matrices/expressions/matpow.py", line 46, in _entry
    raise NotImplementedError(("(%d, %d) entry" % (int(i), int(j)))
  File "/usr/lib/python3/dist-packages/sympy/core/expr.py", line 207, in __int__
    raise TypeError("can't convert symbols to int")
TypeError: can't convert symbols to int

1 个答案:

答案 0 :(得分:1)

我在您的代码中没有发现任何错误。我假设您是通过IDE或其他方式引用不同的模块。尝试显式导入模块

    from sympy import MatrixSymbol, diff, det, Inverse
    from sympy.tensor import Idx
    import sympy

    print('SymPy version: {0}\n'.format(sympy.__version__))  # 1.3

    i = Idx('i', 3)
    j = Idx('j', 3)
    k = Idx('k', 3)
    l = Idx('l', 3)

    F = MatrixSymbol('F', 3, 3)

    print("Derivative of F wrt F")
    print("---------------------")
    print(diff(F[k, l], F[i, j]))
    print("\n")

    J = det(F)
    print("Derivative of det(F) wrt F")
    print("--------------------------")
    # no errors
    # print(diff(J, F[i, j]))

    # EDIT based on question --this is not equivalent
    # just an example by using a different function
    # it means: try with a different approach ¯\_(ツ)_/¯
    # try with an MDM
    mutable_dense_matrix = sympy.Matrix(F)
    print(diff(mutable_dense_matrix.det(), F[i, j]))
    print("\n")

    print("Derivative of inv(F) wrt F")
    print("--------------------------")
    Finv = Inverse(F)
    print(Finv[i, j])
    print(diff(Finv[k, l], F[i, j]))
    print("\n")

输出

    SymPy version: 1.3

    Derivative of F wrt F
    ---------------------
    KroneckerDelta(i, k)*KroneckerDelta(j, l)


    Derivative of det(F) wrt F
    --------------------------
    KroneckerDelta(0, i)*KroneckerDelta(0, j)*F[1, 1]*F[2, 2] - KroneckerDelta(0, i)*KroneckerDelta(0, j)*F[1, 2]*F[2, 1] - KroneckerDelta(0, i)*KroneckerDelta(1, j)*F[1, 0]*F[2, 2] + KroneckerDelta(0, i)*KroneckerDelta(1, j)*F[1, 2]*F[2, 0] + KroneckerDelta(0, i)*KroneckerDelta(2, j)*F[1, 0]*F[2, 1] - KroneckerDelta(0, i)*KroneckerDelta(2, j)*F[1, 1]*F[2, 0] - KroneckerDelta(0, j)*KroneckerDelta(1, i)*F[0, 1]*F[2, 2] + KroneckerDelta(0, j)*KroneckerDelta(1, i)*F[0, 2]*F[2, 1] + KroneckerDelta(0, j)*KroneckerDelta(2, i)*F[0, 1]*F[1, 2] - KroneckerDelta(0, j)*KroneckerDelta(2, i)*F[0, 2]*F[1, 1] + KroneckerDelta(1, i)*KroneckerDelta(1, j)*F[0, 0]*F[2, 2] - KroneckerDelta(1, i)*KroneckerDelta(1, j)*F[0, 2]*F[2, 0] - KroneckerDelta(1, i)*KroneckerDelta(2, j)*F[0, 0]*F[2, 1] + KroneckerDelta(1, i)*KroneckerDelta(2, j)*F[0, 1]*F[2, 0] - KroneckerDelta(1, j)*KroneckerDelta(2, i)*F[0, 0]*F[1, 2] + KroneckerDelta(1, j)*KroneckerDelta(2, i)*F[0, 2]*F[1, 0] + KroneckerDelta(2, i)*KroneckerDelta(2, j)*F[0, 0]*F[1, 1] - KroneckerDelta(2, i)*KroneckerDelta(2, j)*F[0, 1]*F[1, 0]


    Derivative of inv(F) wrt F
    --------------------------
    (F^-1)[i, j]
    -Sum(KroneckerDelta(_z1, i)*KroneckerDelta(_z2, j)*(F^-1)[_z2, l]*(F^-1)[k, _z1], (_z1, 0, 2), (_z2, 0, 2))