使用 sympy 扩展索引符号方程 [英] Expand index notation equation using sympy

查看:30
本文介绍了使用 sympy 扩展索引符号方程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面我有一个使用索引表示法编写的方程.这个方程可以用图中的六个方程来表示.

第一个方程使用索引符号展开(爱因斯坦符号:https://en.wikipedia.org/wiki/Einstein_notation).在 U_k,k 中,逗号是导数的约定.由于我们有重复的索引 (k,k),我们应用求和约定并得到 (du_1/dx_1 + du_2/dx_2 + du_3/dx_3).在图中,项 u_1、u_2 和 u_3 被写为 u、v 和 w,它们被 x_1、x_2 和 x_3(x、y 和 z)区分.

我是 python 和 Sympy 的新手,我看到有一个张量模块,但我看不到 Sympy 中是否已经实现了一些东西,我可以在其中编写第一个方程(带索引)并从中获得其他六个关系.

解决方案

目前,没有直接的方法可以满足您的要求.

我将建议一个应该有效的技巧,通过使用 IndexedBase(即由其他符号索引的符号),然后替换.

声明你的符号:

U = IndexedBase("U")l = 符号(拉姆达")var("mu u v w x y z i j k")

声明你的表达式(没有爱因斯坦求和,所以明确地输入一个求和):

sij = l*Sum(U[k, k], (k, 0, 2)) * KroneckerDelta(i, j) + mu*(U[i, j] + U[j, i])

定义一个替换函数:根据索引将U[0, 0]匹配到Derivative(u, x)等等:

def replace_U(uij):i1, i2 = uij.indices返回导数([u, v, w][i1], [x, y, z][i2])

现在,遍历所有 i, j 索引,首先用整数值替换 U[i, j],然后替换像 U[0, 0], ...

for ii in range(3):对于范围内的 ji(3):如果 ii <吉:继续pprint(sij.doit().xreplace({i: ii, j: ji}).replace(lambda v: v.base == U, replace_U))

记住:Sum.doit() 展开求和.条件 ii >= ji 用于避免打印相同的表达式两次(您的方程在 i, j 中是对称的).

注意上面代码中的U[i, j]只是一个符号,ij除了作为U 的索引.替换函数为它们分配导数.

我得到的输出是:

 ⎛d d d ⎞ dλ⋅⎜──(u) + ──(v) + ──(w)⎟ + 2⋅μ⋅──(u)⎝dx dy dz ⎠ dx⎛ d ⎞μ⋅⎜──(u) + ──(v)⎟⎝dy dx ⎠⎛d d d ⎞ dλ⋅⎜──(u) + ──(v) + ──(w)⎟ + 2⋅μ⋅──(v)⎝dx dy dz ⎠ dy⎛ d ⎞μ⋅⎜──(u) + ──(w)⎟⎝dz dx ⎠⎛ d ⎞μ⋅⎜──(v) + ──(w)⎟⎝dz dy ⎠⎛d d d ⎞ dλ⋅⎜──(u) + ──(v) + ──(w)⎟ + 2⋅μ⋅──(w)⎝dx dy dz ⎠ dz

<块引用>

我是 python 和 Sympy 的新手,我看到有一个张量模块但我看不到 Sympy 中是否已经实现了一些东西我可以在这里写出第一个方程(带索引)并从中获得其他六个关系.

sympy.tensor.tensor,它支持抽象索引符号(一种受限制的爱因斯坦求和).不幸的是,它不支持衍生工具.

如果你想处理组件,最近添加了一个:sympy.tensor.array.它提供多维数组、张量积和收缩以及数组导数.

Below I have an equation written using index notation. This equation can be expressed with the six equations on the figure.

The first equation is expanded using index notation (einstein notation: https://en.wikipedia.org/wiki/Einstein_notation). In U_k,k the comma is a convention for derivative. Since we have repeated indices (k,k) we apply the summation convention and get (du_1/dx_1 + du_2/dx_2 + du_3/dx_3). On the figure the terms u_1, u_2 and u_3 are written as u, v and w and they are differentiated by x_1, x_2 and x_3 (x, y, and z).

I am new to python and Sympy and I saw that there is a tensor module but I could not see if there is something already implemented in Sympy where I can write the first equation (with index) and from that obtain the other six relations.

解决方案

Currently, there is no straightforward way to do what you ask.

I shall suggest a trick that should work, by using IndexedBase (that is, symbols indexed by other symbols), followed by a replacement.

Declare your symbols:

U = IndexedBase("U")
l = symbols("lambda")
var("mu u v w x y z i j k")

Declare your expressions (no Einstein summation, so explicitly put a Sum):

sij = l*Sum(U[k, k], (k, 0, 2)) * KroneckerDelta(i, j) + mu*(U[i, j] + U[j, i])

Define a replacement function: will match U[0, 0] to Derivative(u, x) and so on according to the index:

def replace_U(uij):
    i1, i2 = uij.indices
    return Derivative([u, v, w][i1], [x, y, z][i2])

Now, run over all i, j indices replacing U[i, j] with integer values first, then replacing expressions like U[0, 0], ...

for ii in range(3):
    for ji in range(3):
        if ii < ji:
            continue
        pprint(sij.doit().xreplace({i: ii, j: ji}).replace(lambda v: v.base == U, replace_U))

Remember: Sum.doit() expands the summation. Condition ii >= ji is used to avoid printing the same expressions twice (your equation is symmetric in i, j).

Note that U[i, j] in the code above is just a symbol, i and j have no special meaning except as indices to U. The replacement function assigns derivatives to them.

The output I get is:

  ⎛d       d       d    ⎞       d    
λ⋅⎜──(u) + ──(v) + ──(w)⎟ + 2⋅μ⋅──(u)
  ⎝dx      dy      dz   ⎠       dx   
  ⎛d       d    ⎞
μ⋅⎜──(u) + ──(v)⎟
  ⎝dy      dx   ⎠
  ⎛d       d       d    ⎞       d    
λ⋅⎜──(u) + ──(v) + ──(w)⎟ + 2⋅μ⋅──(v)
  ⎝dx      dy      dz   ⎠       dy   
  ⎛d       d    ⎞
μ⋅⎜──(u) + ──(w)⎟
  ⎝dz      dx   ⎠
  ⎛d       d    ⎞
μ⋅⎜──(v) + ──(w)⎟
  ⎝dz      dy   ⎠
  ⎛d       d       d    ⎞       d    
λ⋅⎜──(u) + ──(v) + ──(w)⎟ + 2⋅μ⋅──(w)
  ⎝dx      dy      dz   ⎠       dz   

I am new to python and Sympy and I saw that there is a tensor module but I could not see if there is something already implemented in Sympy where I can write the first equation (with index) and from that obtain the other six relations.

There is sympy.tensor.tensor, which supports abstract index notation (a restricted kind of Einstein summation). Unfortunately, it does not support derivatives.

If you want to work on components, there's a recent addition: sympy.tensor.array. It provides multidimensional arrays, tensor products and contractions, and derivatives by arrays.

这篇关于使用 sympy 扩展索引符号方程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆