如何计算梯度、散度或旋度¶
本教程将介绍SageMath在3维欧几里德空间中的一些向量演算功能。相应的工具已经通过 SageManifolds 项目。
The tutorial is also available as a Jupyter notebook, either
passive (nbviewer
)
or interactive (binder
).
第一阶段:介绍欧几里得三维空间¶
在评估某些向量场运算符之前,需要定义向量场所在的领域,即 3-dimensional Euclidean space mathbb{E}^3 。在SageMath中,我们将其与标准 Cartesian coordinates (x,y,z) 、VIA EuclideanSpace
**
sage: E.<x,y,z> = EuclideanSpace()
sage: E
Euclidean space E^3
多亏了这个符号 <x,y,z>
在上面的声明中,坐标 (x,y,z) 作为三个符号变量立即可用 x
, y
和 z
(不需要通过以下方式申报 var()
,即打字 x, y, z = var('x y z')
):
sage: x is E.cartesian_coordinates()[1]
True
sage: y is E.cartesian_coordinates()[2]
True
sage: z is E.cartesian_coordinates()[3]
True
sage: type(z)
<class 'sage.symbolic.expression.Expression'>
再说了, mathbb{E}^3 被赋予了 orthonormal vector frame (e_x, e_y, e_z) 与笛卡尔坐标关联:
sage: E.frames()
[Coordinate frame (E^3, (e_x,e_y,e_z))]
在这个阶段,这是 default 启用向量帧 mathbb{E}^3 (是迄今为止引入的唯一向量帧):
sage: E.default_frame()
Coordinate frame (E^3, (e_x,e_y,e_z))
定义向量场¶
我们在上定义了一个向量场 mathbb{E}^3 从它在向量坐标系中的分量 (e_x,e_y,e_z) **
sage: v = E.vector_field(-y, x, sin(x*y*z), name='v')
sage: v.display()
v = -y e_x + x e_y + sin(x*y*z) e_z
我们可以访问的组件 v 通过方括号运算符::
sage: v[1]
-y
sage: v[:]
[-y, x, sin(x*y*z)]
向量场可以在以下任一点求值 mathbb{E}^3 **
sage: p = E((3,-2,1), name='p')
sage: p
Point p on the Euclidean space E^3
sage: p.coordinates()
(3, -2, 1)
sage: vp = v.at(p)
sage: vp
Vector v at Point p on the Euclidean space E^3
sage: vp.display()
v = 2 e_x + 3 e_y - sin(6) e_z
可以绘制向量场::
sage: v.plot(max_range=1.5, scale=0.5)
Graphics3d Object
有关自定义绘图的信息,请参阅的文档中的选项列表 plot()
。例如,要获得的正交投影视图 v 在飞机上 y=1 ,DO::
sage: v.plot(fixed_coords={y: 1}, ambient_coords=(x,z), max_range=1.5,
....: scale=0.25)
Graphics object consisting of 81 graphics primitives
我们可以定义一个矢量场 u 使用通用组件 (u_x, u_y, y_z) **
sage: u = E.vector_field(function('u_x')(x,y,z),
....: function('u_y')(x,y,z),
....: function('u_z')(x,y,z),
....: name='u')
sage: u.display()
u = u_x(x, y, z) e_x + u_y(x, y, z) e_y + u_z(x, y, z) e_z
sage: u[:]
[u_x(x, y, z), u_y(x, y, z), u_z(x, y, z)]
它在当时的价值 p 然后::
sage: up = u.at(p)
sage: up.display()
u = u_x(3, -2, 1) e_x + u_y(3, -2, 1) e_y + u_z(3, -2, 1) e_z
如何计算各种向量积¶
点积¶
点(或标量)积 ucdot v 向量场的 u 和 v 是通过该方法获得的 dot_product()
,它承认 dot()
作为快捷方式别名::
sage: u.dot(v) == u[1]*v[1] + u[2]*v[2] + u[3]*v[3]
True
s= ucdot v is a scalar field, i.e. a map mathbb{E}^3 to mathbb{R}:
sage: s = u.dot(v)
sage: s
Scalar field u.v on the Euclidean space E^3
sage: s.display()
u.v: E^3 → ℝ
(x, y, z) ↦ -y*u_x(x, y, z) + x*u_y(x, y, z) + sin(x*y*z)*u_z(x, y, z)
它绘制了 mathbb{E}^3 到实数::
sage: s(p)
-sin(6)*u_z(3, -2, 1) + 2*u_x(3, -2, 1) + 3*u_y(3, -2, 1)
其坐标表达式为::
sage: s.expr()
-y*u_x(x, y, z) + x*u_y(x, y, z) + sin(x*y*z)*u_z(x, y, z)
常模¶
The norm |u| of the vector field u is defined in terms of the dot product by |u| = sqrt{ucdot u}:
sage: norm(u) == sqrt(u.dot(u))
True
它是上的标量域 mathbb{E}^3 **
sage: s = norm(u)
sage: s
Scalar field |u| on the Euclidean space E^3
sage: s.display()
|u|: E^3 → ℝ
(x, y, z) ↦ sqrt(u_x(x, y, z)^2 + u_y(x, y, z)^2 + u_z(x, y, z)^2)
sage: s.expr()
sqrt(u_x(x, y, z)^2 + u_y(x, y, z)^2 + u_z(x, y, z)^2)
为 v ,我们有:
sage: norm(v).expr()
sqrt(x^2 + y^2 + sin(x*y*z)^2)
叉积¶
叉积 utimes v 是通过该方法获得的 cross_product()
,它承认 cross()
作为快捷方式别名::
sage: s = u.cross(v)
sage: s
Vector field u x v on the Euclidean space E^3
sage: s.display()
u x v = (sin(x*y*z)*u_y(x, y, z) - x*u_z(x, y, z)) e_x
+ (-sin(x*y*z)*u_x(x, y, z) - y*u_z(x, y, z)) e_y
+ (x*u_x(x, y, z) + y*u_y(x, y, z)) e_z
我们可以检查用分量表示叉积的标准公式:
sage: all([s[1] == u[2]*v[3] - u[3]*v[2],
....: s[2] == u[3]*v[1] - u[1]*v[3],
....: s[3] == u[1]*v[2] - u[2]*v[1]])
True
标量三重积¶
让我们介绍第三个向量场, w 说。例如,我们不会将组件作为 vector_field()
,就像我们为 u 和 v ;相反,我们通过方括号运算符在第二阶段设置它们,任何未设置的分量都被假定为零::
sage: w = E.vector_field(name='w')
sage: w[1] = x*z
sage: w[2] = y*z
sage: w.display()
w = x*z e_x + y*z e_y
向量场的标量三重积 u , v 和 w 按如下方式获得:
sage: triple_product = E.scalar_triple_product()
sage: s = triple_product(u, v, w)
sage: s
Scalar field epsilon(u,v,w) on the Euclidean space E^3
sage: s.expr()
-(y*u_x(x, y, z) - x*u_y(x, y, z))*z*sin(x*y*z) - (x^2*u_z(x, y, z)
+ y^2*u_z(x, y, z))*z
让我们来检查一下标量三重积 u , v 和 w 是 ucdot(vtimes w) **
sage: s == u.dot(v.cross(w))
True
如何评价标准微分算子¶
标准运算符 mathrm{grad} , mathrm{div} , mathrm{curl} 等可作为标量场和矢量场上的方法访问(例如 v.div()
)。然而,为了允许使用标准的数学符号(例如 div(v)
),让我们导入函数 grad()
, div()
, curl()
和 laplacian()
**
sage: from sage.manifolds.operators import *
梯度¶
我们首先引入一个标量场,通过它在笛卡尔坐标下的表达式;在这个例子中,我们考虑一些未指定的函数 (x,y,z) **
sage: F = E.scalar_field(function('f')(x,y,z), name='F')
sage: F.display()
F: E^3 → ℝ
(x, y, z) ↦ f(x, y, z)
的价值 F 在某一时刻::
sage: F(p)
f(3, -2, 1)
的渐变 F **
sage: grad(F)
Vector field grad(F) on the Euclidean space E^3
sage: grad(F).display()
grad(F) = d(f)/dx e_x + d(f)/dy e_y + d(f)/dz e_z
sage: norm(grad(F)).display()
|grad(F)|: E^3 → ℝ
(x, y, z) ↦ sqrt((d(f)/dx)^2 + (d(f)/dy)^2 + (d(f)/dz)^2)
分歧¶
矢量场的散度 u **
sage: s = div(u)
sage: s.display()
div(u): E^3 → ℝ
(x, y, z) ↦ d(u_x)/dx + d(u_y)/dy + d(u_z)/dz
为 v 和 w ,我们有:
sage: div(v).expr()
x*y*cos(x*y*z)
sage: div(w).expr()
2*z
对任何标量字段有效的标识 F 以及任何向量场 u **
sage: div(F*u) == F*div(u) + u.dot(grad(F))
True
卷曲¶
矢量场的旋度 u **
sage: s = curl(u)
sage: s
Vector field curl(u) on the Euclidean space E^3
sage: s.display()
curl(u) = (-d(u_y)/dz + d(u_z)/dy) e_x + (d(u_x)/dz - d(u_z)/dx) e_y
+ (-d(u_x)/dy + d(u_y)/dx) e_z
使用记号的步骤 rot
而不是 curl
,只需执行以下操作:
sage: rot = curl
另一种选择是:
sage: from sage.manifolds.operators import curl as rot
我们那时有::
sage: rot(u).display()
curl(u) = (-d(u_y)/dz + d(u_z)/dy) e_x + (d(u_x)/dz - d(u_z)/dx) e_y
+ (-d(u_x)/dy + d(u_y)/dx) e_z
sage: rot(u) == curl(u)
True
为 v 和 w ,我们有:
sage: curl(v).display()
curl(v) = x*z*cos(x*y*z) e_x - y*z*cos(x*y*z) e_y + 2 e_z
sage: curl(w).display()
curl(w) = -y e_x + x e_y
渐变的旋度始终为零::
sage: curl(grad(F)).display()
curl(grad(F)) = 0
卷曲的散度始终为零::
sage: div(curl(u)).display()
div(curl(u)): E^3 → ℝ
(x, y, z) ↦ 0
对任何标量字段有效的标识 F 以及任何向量场 u 是
正如我们可以查看的:
sage: curl(F*u) == grad(F).cross(u) + F*curl(u)
True
拉普拉斯¶
拉普拉斯学派 Delta F 标量域的 F 是另一个标量字段::
sage: s = laplacian(F)
sage: s.display()
Delta(F): E^3 → ℝ
(x, y, z) ↦ d^2(f)/dx^2 + d^2(f)/dy^2 + d^2(f)/dz^2
以下身份成立:
正如我们可以查看的:
sage: laplacian(F) == div(grad(F))
True
拉普拉斯学派 Delta u 关于矢量场 u 是另一个向量场::
sage: Du = laplacian(u)
sage: Du
Vector field Delta(u) on the Euclidean space E^3
其组成部分为::
sage: Du.display()
Delta(u) = (d^2(u_x)/dx^2 + d^2(u_x)/dy^2 + d^2(u_x)/dz^2) e_x
+ (d^2(u_y)/dx^2 + d^2(u_y)/dy^2 + d^2(u_y)/dz^2) e_y
+ (d^2(u_z)/dx^2 + d^2(u_z)/dy^2 + d^2(u_z)/dz^2) e_z
在笛卡尔坐标系中, Delta u 只不过是组成的(标量)拉普拉斯 u ,我们可以查看::
sage: e = E.cartesian_frame()
sage: Du == sum(laplacian(u[[i]])*e[i] for i in E.irange())
True
在上面的公式中, u[[i]]
返回 i -第7个组件 u 作为标量字段,而 u[i]
将返回该标量字段的坐标表达式;此外, e
是笛卡尔坐标系::
sage: e[:]
(Vector field e_x on the Euclidean space E^3,
Vector field e_y on the Euclidean space E^3,
Vector field e_z on the Euclidean space E^3)
对于向量场 v 和 w ,我们有:
sage: laplacian(v).display()
Delta(v) = -(x^2*y^2 + (x^2 + y^2)*z^2)*sin(x*y*z) e_z
sage: laplacian(w).display()
Delta(w) = 0
我们有:
sage: curl(curl(u)).display()
curl(curl(u)) = (-d^2(u_x)/dy^2 - d^2(u_x)/dz^2 + d^2(u_y)/dxdy
+ d^2(u_z)/dxdz) e_x + (d^2(u_x)/dxdy - d^2(u_y)/dx^2 - d^2(u_y)/dz^2
+ d^2(u_z)/dydz) e_y + (d^2(u_x)/dxdz + d^2(u_y)/dydz - d^2(u_z)/dx^2
- d^2(u_z)/dy^2) e_z
sage: grad(div(u)).display()
grad(div(u)) = (d^2(u_x)/dx^2 + d^2(u_y)/dxdy + d^2(u_z)/dxdz) e_x
+ (d^2(u_x)/dxdy + d^2(u_y)/dy^2 + d^2(u_z)/dydz) e_y
+ (d^2(u_x)/dxdz + d^2(u_y)/dydz + d^2(u_z)/dz^2) e_z
一个著名的身份是
让我们检查一下::
sage: curl(curl(u)) == grad(div(u)) - laplacian(u)
True
如何定制各种符号¶
定制正交帧向量的符号¶
默认情况下,与笛卡尔坐标关联的标准正交框的向量表示 (e_x,e_y,e_z) **
sage: frame = E.cartesian_frame()
sage: frame
Coordinate frame (E^3, (e_x,e_y,e_z))
但这是可以改变的,这要归功于这种方法 set_name()
**
sage: frame.set_name('a', indices=('x', 'y', 'z'))
sage: frame
Coordinate frame (E^3, (a_x,a_y,a_z))
sage: v.display()
v = -y a_x + x a_y + sin(x*y*z) a_z
sage: frame.set_name(('hx', 'hy', 'hz'),
....: latex_symbol=(r'\mathbf{\hat{x}}', r'\mathbf{\hat{y}}',
....: r'\mathbf{\hat{z}}'))
sage: frame
Coordinate frame (E^3, (hx,hy,hz))
sage: v.display()
v = -y hx + x hy + sin(x*y*z) hz
自定义坐标符号¶
坐标符号在尖括号内定义 <...>
在欧几里得空间的构建上。上面我们做到了::
sage: E.<x,y,z> = EuclideanSpace()
这就产生了坐标符号 (x,y,z) 并在相应的Python变量中 x
, y
和 z
(SageMath符号表达式)。例如,使用其他符号 (X,Y,Z) ,它足以创造出 E
AS::
sage: E.<X,Y,Z> = EuclideanSpace()
我们那时有::
sage: E.atlas()
[Chart (E^3, (X, Y, Z))]
sage: E.cartesian_frame()
Coordinate frame (E^3, (e_X,e_Y,e_Z))
sage: v = E.vector_field(-Y, X, sin(X*Y*Z), name='v')
sage: v.display()
v = -Y e_X + X e_Y + sin(X*Y*Z) e_Z
默认情况下,坐标的 Latex 符号与尖括号内给出的字母一致。但这可以通过可选参数进行调整 symbols
该函数的 EuclideanSpace
,它必须是一个字符串,通常以 r (适用于 raw 字符串,以便允许LaTeX表达式的反斜杠字符)。此字符串包含用空格分隔的坐标字段;每个字段包含坐标的文本符号,也可能包含坐标的 Latex 符号(如果后者不同于文本符号),这两个符号都用冒号分隔 (:
):
sage: E.<xi,et,ze> = EuclideanSpace(symbols=r"xi:\xi et:\eta ze:\zeta")
sage: E.atlas()
[Chart (E^3, (xi, et, ze))]
sage: v = E.vector_field(-et, xi, sin(xi*et*ze), name='v')
sage: v.display()
v = -et e_xi + xi e_et + sin(et*xi*ze) e_ze