Python符号计算之数组

数组

数组是编程语言中用于复杂计算的基本数据结构,而从数学和物理上的应用来看,不同维度的数组,对应着不同类别的代数空间,即一维数组对应向量;二维对应矩阵,高维对应张量。在sympy中,与高维数组相关的大部分函数,都封装在tensor中,但支持从从sympy中直接导入

import sympy
from sympy import print_latex
from sympy import Array
a1 = Array([[1, 2], [3, 4], [5, 6]])
a1.shape    # (3,2)
a1.rank()   # 2阶张量
print_latex(a1)

a 1 = [ 1 2 3 4 5 6 ] a_1 = \left[\begin{matrix}1 & 2\\3 & 4\\5 & 6\end{matrix}\right] a1= 135246

Array类型的元素也可以是符号,示例如下

from sympy.abc import *
a2 = Array([[[x, y], [z, x*z]], [[1, x*y], [1/x, x/y]]])
a2.shape    # (2,2,2)
a2.rank()   # 3阶张量
print_latex(a2)

a 2 = [ [ x y z x z ] [ 1 x y 1 x x y ] ] a_2=\left[\begin{matrix}\left[\begin{matrix}x & y\\z & x z\end{matrix}\right] & \left[\begin{matrix}1 & x y\\\frac{1}{x} & \frac{x}{y}\end{matrix}\right]\end{matrix}\right] a2=[[xzyxz][1x1xyyx]]

张量乘法

相同维度的数组,可以直接进行元素之间的加减乘除,其中加减法无需多言,但乘法却相对复杂。除了元素之间可以进行乘法计算,将数组看成向量和矩阵,也可以进行矩阵乘法的计算,示例如下

[ c d ] [ a b ] = [ c a c b d a d b ] [ a b ] [ c d ] = a c + b d \begin{bmatrix}c\\d\end{bmatrix}\begin{bmatrix}a&b\end{bmatrix} =\begin{bmatrix}ca&cb\\ da&db\end{bmatrix}\quad \begin{bmatrix}a&b\end{bmatrix} \begin{bmatrix}c\\d\end{bmatrix}=ac+bd [cd][ab]=[cadacbdb][ab][cd]=ac+bd

若将向量看作张量,那么前者是张量乘法,后者则是在乘法之后进行了缩并操作。在sympy中,tensorproduct即为张量乘法,tensorcontraction则为缩并

from sympy import tensorproduct, tensorcontraction
A = Array([a,b])
B = Array([c,d])
p = tensorproduct(A, B)
print(sympy.latex(p))
t = tensorcontraction(p, (0,1))
print_latex(t)    # ac + bd

其中,tensorcontraction的第二个参数 ( 0 , 1 ) (0,1) (0,1)表示被缩并的轴。

求导

sympy中实现了derive_by_array函数,这个函数可以作用在普通的标量函数表达式上,示例如下

from sympy import derive_by_array
from sympy import sin, exp
ex1 = derive_by_array(sin(x*y), x)
print_latex(ex1)

ex2 = derive_by_array(sin(x*y), [x, y, z])
print_latex(ex2)

ex1和ex2的输出分别是

∂ sin ⁡ ( x y ) ∂ x = y cos ⁡ ( x y ) ∇ sin ⁡ ( x y ) = [ y cos ⁡ ( x y ) x cos ⁡ ( x y ) 0 ] \frac{\partial\sin (xy)}{\partial x} = y \cos{\left(x y \right)}\\ \nabla\sin(xy)=\left[\begin{matrix}y \cos{\left(x y \right)} & x \cos{\left(x y \right)} & 0\end{matrix}\right] xsin(xy)=ycos(xy)sin(xy)=[ycos(xy)xcos(xy)0]

下面定义一阶张量 A m = [ e x , sin ⁡ ( y z ) , t ] A^m=[e^x, \sin(yz), t] Am=[ex,sin(yz),t],以及 x n = [ x , y , z ] x^n=[x,y,z] xn=[x,y,z],则 B n m = ∂ A m ∂ x n B^{nm}=\frac{\partial A^m}{\partial x^n} Bnm=xnAm,可以计算如下

xn = [x, y, z]
Am = [exp(x), sin(y*z), 0]
Bnm = derive_by_array(Am, xn)
print_latex(Bnm)

结果如下

[ e x 0 0 0 z cos ⁡ ( y z ) 0 0 y cos ⁡ ( y z ) 0 ] \left[\begin{matrix}e^{x} & 0 & 0\\0 & z \cos{\left(y z \right)} & 0\\0 & y \cos{\left(y z \right)} & 0\end{matrix}\right] ex000zcos(yz)ycos(yz)000

如果对运算结果进行缩并,那么就可以得到 A m A^m Am场的散度

div = tensorcontraction(Bnm, (0,1))
print_latex(div)

z cos ⁡ ( y z ) + e x z \cos{\left(y z \right)} + e^{x} zcos(yz)+ex

∇ ( e x , sin ⁡ ( y z ) , t ) = ∂ e x ∂ x + ∂ sin ⁡ ( y z ) ∂ y + 0 ∂ z = z cos ⁡ ( y z ) + e x \nabla (e^x, \sin(yz), t)=\frac{\partial e^x}{\partial x}+\frac{\partial \sin(yz)}{\partial y}+\frac{0}{\partial z}=z \cos{\left(y z \right)} + e^{x} (ex,sin(yz),t)=xex+ysin(yz)+z0=zcos(yz)+ex

矢量、矩阵和张量

如果只是从数据结构出发,那么数组和张量是等价的,而矢量、矩阵则为其特例。但在具体的物理应用中,矢量、向量、张量则可能存在数据结构之外的含义。所以sympy中额外给出了这三种数据结构。

首先,矢量从编程角度来说是一维数组,但在物理中,则可用于描述指代有方向的物理量。以三维矢量为例,往往用 i ^ , j ^ , k ^ \hat i,\hat j,\hat k i^,j^,k^或者 e ^ x , e ^ y , e ^ z \hat e_x, \hat e_y, \hat e_z e^x,e^y,e^z来代表 x , y , z x,y,z x,y,z这三个轴向的单位矢量。正因如此,sympy中提供了专门的三维矢量坐标coordSys3D

from sympy.vector import CoordSys3D
N = CoordSys3D('N')
v = (x*y + x*z)*N.i + (y**2 + y*z)*N.j
print_latex(v)

( x y + x z ) i ^ N + ( y 2 + y z ) j ^ N \left(x y + x z\right)\mathbf{\hat{i}_{N}} + \left(y^{2} + y z\right)\mathbf{\hat{j}_{N}} (xy+xz)i^N+(y2+yz)j^N

其次,矩阵除了作为一种数据组织形式外,也有丰富的物理内涵,可以表示刚体旋转等,并且在图像处理领域有着广泛应用。sympy也为其单独提供了Matrix类型

from sympy.matrices import Matrix
M = Matrix([[1,0,0], [0,0,0]])
print_latex(M)
print_latex(Matrix([M, (0, 0, -1)]))
print_latex(Matrix([[1, 2, 3]]))
print_latex(Matrix([1, 2, 3]))
m = Matrix(3,4, lambda i,j : i**2+j**2)
print_latex(m)

其中 m m m是通过lambda表达式创建的矩阵,其每个元素都遵照给定函数的规则而创建,效果如下

[ 1 0 0 0 0 0 ] [ 1 0 0 0 0 0 0 0 − 1 ] [ 1 2 3 ] [ 1 2 3 ] [ 0 1 4 9 1 2 5 10 4 5 8 13 ] \left[\begin{matrix}1 & 0 & 0\\0 & 0 & 0\end{matrix}\right]\quad \left[\begin{matrix}1 & 0 & 0\\0 & 0 & 0\\0 & 0 & -1\end{matrix}\right]\quad\left[\begin{matrix}1 & 2 & 3\end{matrix}\right]\quad \left[\begin{matrix}1\\2\\3\end{matrix}\right]\quad \left[\begin{matrix}0 & 1 & 4 & 9\\1 & 2 & 5 & 10\\4 & 5 & 8 & 13\end{matrix}\right] [100000] 100000001 [123] 123 01412545891013

Array类型提供了tomatrix方法,可以将二维数组输出为Matrix类型,但高阶数组将会报错

a1.tomatrix()       # 返回Matrix数据
a2.tomatrix()       # 报错

最后,张量在广义相对论中也有着频繁的使用,和高维数组相比,除了在形式上多了类似 μ ν \mu\nu μν之类的上下指标外,还有协变、逆变的区别,并且基于此提供了协变导数、逆变导数等运算,sympy中为此提供了TensorIndexType类型,其初始化参数有

  • name : 张量类型的名字
  • dummy_name : 张量指标的名字
  • dim : 维度,可以是符号、整数或者None
  • eps_dim : epsilon张量的维度
  • metric_symmetry : 对称性
  • metric_name : 矩阵名字

实例如下

from sympy.tensor.tensor import TensorIndexType
Lorentz = TensorIndexType('Lorentz', dummy_name='L')
Lorentz.metric
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微小冷

请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值