【问题标题】:Derivatives of the determinant and inverse of 2nd-order tensor wrt itself in SymPySymPy中二阶张量本身的行列式和逆的导数
【发布时间】:2019-07-01 15:00:09
【问题描述】:

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

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

我已经使用 SymPy 大约一周了。我可以得到 F wrt 本身的导数,但不知道如何得到它的行列式和逆的导数。作为参考,我将代码和输出与错误消息一起发布。

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

【问题讨论】:

    标签: python sympy tensor calculus


    【解决方案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))
    

    【讨论】:

    • 谢谢@jonathan。我试过你的建议;没有帮助。我认为我们有不同版本的 SymPy。我有版本 1.1.1 您使用的 SymPy 版本是什么?另外,有什么方法可以让 SymPy 打印行列式的导数的正确表达式,而不是 Derivative(Determinant(F), F[i, j])
    • 不客气,@Chenna。抱歉回答有点晚了。我正在使用 1.3,关于这个问题,这是 sympy.tensor.indexed.Idx 函数的已知“问题”之一。我用 MDM 编辑了答案,让你看看你是否也可以在你的项目中使用它。至少你看到克罗内克三角函数再次上升。希望能帮助到你。如果您需要更多详细信息,请告诉我
    • 谢谢@jonathan。我会看看我是否使用 MDM 来利用你的建议。
    • yw,@ChennaK (:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    相关资源
    最近更新 更多