欧几里德平面上的向量演算

本教程介绍了SageMath在二维欧几里得空间框架中的一些向量演算功能。相应的工具已经通过 SageManifolds 项目。

The tutorial is also available as a Jupyter notebook, either passive (nbviewer) or interactive (binder).

1定义欧几里得平面

我们定义了欧几里德平面 mathbb{{E}}^2 作为二维欧几里德空间,具有笛卡尔坐标 (x,y) ,通过函数 EuclideanSpace ::

sage: E.<x,y> = EuclideanSpace()
sage: E
Euclidean plane E^2

感谢使用 <x,y> 在上面的命令中,Python变量 xy 分配给符号变量 xy 描述笛卡尔坐标(不需要通过 var() ,即键入 x, y = var('x y') ):

sage: type(y)
<type 'sage.symbolic.expression.Expression'>

而不是使用变量 xy ,也可以通过其在笛卡尔坐标图中的索引来获取坐标:

sage: cartesian = E.cartesian_coordinates()
sage: cartesian
Chart (E^2, (x, y))
sage: cartesian[1]
x
sage: cartesian[2]
y
sage: y is cartesian[2]
True

每个笛卡尔坐标跨越整个实线:

sage: cartesian.coord_range()
x: (-oo, +oo); y: (-oo, +oo)

2矢量场

欧几里得平面 mathbb{{E}}^2 典型地被赋予与笛卡尔坐标相关的向量框架:

sage: E.default_frame()
Coordinate frame (E^2, (e_x,e_y))

向量场打开 mathbb{{E}}^2 然后从它们在该框架中的组件定义:

sage: v = E.vector_field(-y, x, name='v')
sage: v.display()
v = -y e_x + x e_y

对单个组件的访问由方括号运算符执行:

sage: v[1]
-y
sage: v[:]
[-y, x]

矢量场图 v (这是带有默认参数的,请参阅的文档 plot() 对于各种选项)::

sage: v.plot()
Graphics object consisting of 80 graphics primitives

也可以通过在第二阶段设置组件来定义向量场:

sage: w = E.vector_field(name='w')
sage: w[1] = function('w_x')(x,y)
sage: w[2] = function('w_y')(x,y)
sage: w.display()
w = w_x(x, y) e_x + w_y(x, y) e_y

注意,在上面的示例中 w 是的未指定函数 (x,y) ,与 v .

标准的线性代数运算可以在向量场上执行:

sage: s = 2*v + x*w
sage: s.display()
(x*w_x(x, y) - 2*y) e_x + (x*w_y(x, y) + 2*x) e_y

标量积与范数

点(或标量)积 ucdot v 向量场的 uv 由操作员获得 dot_product() ,它在 mathbb{{E}}^2 ::

sage: s = v.dot_product(w)
sage: s
Scalar field v.w on the Euclidean plane E^2

的快捷别名 dot_product()dot ::

sage: s == v.dot(w)
True
sage: s.display()
v.w: E^2 --> R
   (x, y) |--> -y*w_x(x, y) + x*w_y(x, y)

表示标量字段的符号表达式 vcdot w 通过该方法得到 expr() ::

sage: s.expr()
-y*w_x(x, y) + x*w_y(x, y)

向量场的欧几里德范数 v 是上的标量字段 mathbb{{E}}^2 ::

sage: s = norm(v)
sage: s.display()
|v|: E^2 --> R
   (x, y) |--> sqrt(x^2 + y^2)

再次,通过 expr() ::

sage: s.expr()
sqrt(x^2 + y^2)
sage: norm(w).expr()
sqrt(w_x(x, y)^2 + w_y(x, y)^2)

我们当然有 |v|^2 = vcdot v ::

sage: norm(v)^2 == v.dot(v)
True

给定点的值

我们介绍一点 pin mathbb{{E}}^2 通过通用的SageMath语法从其父元素创建元素(这里是 mathbb{{E}}^2 ),即呼叫接线员 () ,以点的笛卡尔坐标作为第一个参数:

sage: p = E((-2,3), name='p')
sage: p
Point p on the Euclidean plane E^2

的坐标 p 由方法返回 coord() ::

sage: p.coord()
(-2, 3)

或者让图表 cartesian 按重点行动:

sage: cartesian(p)
(-2, 3)

标量字段的值 s = norm(v)p 是::

sage: s(p)
sqrt(13)

向量场的值 p 通过该方法得到 at() (因为接线员 () 是为标量字段上的操作保留的,请参见 向量场作为导数 以下):

sage: vp = v.at(p)
sage: vp
Vector v at Point p on the Euclidean plane E^2
sage: vp.display()
v = -3 e_x - 2 e_y
sage: wp = w.at(p)
sage: wp.display()
w = w_x(-2, 3) e_x + w_y(-2, 3) e_y
sage: s = v.at(p) + pi*w.at(p)
sage: s.display()
(pi*w_x(-2, 3) - 3) e_x + (pi*w_y(-2, 3) - 2) e_y

三。微分算子

标准操作员 mathrm{{grad}}mathrm{{div}} 向量演算中涉及到的方法可以作为标量场和向量场上的方法(例如。 v.div() ). 然而,使用标准的数学符号(例如。 div(v) ),让我们导入函数 grad()div()laplacian() 在全局命名空间中:

sage: from sage.manifolds.operators import *

发散

向量场的散度由函数返回 div() ;输出是上的标量字段 mathbb{{E}}^2 ::

sage: div(v)
Scalar field div(v) on the Euclidean plane E^2
sage: div(v).display()
div(v): E^2 --> R
   (x, y) |--> 0

在本案中, mathrm{{div}}, v 相同地消失:

sage: div(v) == 0
True

相反 w 是::

sage: div(w).display()
div(w): E^2 --> R
   (x, y) |--> d(w_x)/dx + d(w_y)/dy
sage: div(w).expr()
diff(w_x(x, y), x) + diff(w_y(x, y), y)

梯度

标量场的梯度,例如。 s = norm(v) ,由函数返回 grad() ;输出为向量场:

sage: s = norm(v)
sage: grad(s)
Vector field grad(|v|) on the Euclidean plane E^2
sage: grad(s).display()
grad(|v|) = x/sqrt(x^2 + y^2) e_x + y/sqrt(x^2 + y^2) e_y
sage: grad(s)[2]
y/sqrt(x^2 + y^2)

对于一般标量字段,例如:

sage: F = E.scalar_field(function('f')(x,y), name='F')

我们有::

sage: grad(F).display()
grad(F) = d(f)/dx e_x + d(f)/dy e_y
sage: grad(F)[:]
[d(f)/dx, d(f)/dy]

当然,我们可以合并 grad()div() ::

sage: grad(div(w)).display()
grad(div(w)) = (d^2(w_x)/dx^2 + d^2(w_y)/dxdy) e_x + (d^2(w_x)/dxdy + d^2(w_y)/dy^2) e_y

拉普拉斯算子

拉普拉斯算子 Delta 由函数获得 laplacian() ;作用于标量字段:

sage: laplacian(F).display()
Delta(F): E^2 --> R
   (x, y) |--> d^2(f)/dx^2 + d^2(f)/dy^2

以及向量场:

sage: laplacian(w).display()
Delta(w) = (d^2(w_x)/dx^2 + d^2(w_x)/dy^2) e_x + (d^2(w_y)/dx^2 + d^2(w_y)/dy^2) e_y

对于标量场,我们有恒等式

\[Delta F=mathrm{div}左(mathrm{grad},F右),\]

我们可以查到:

sage: laplacian(F) == div(grad(F))
True

4极坐标

极坐标 (r,phi) 介绍 mathbb{{E}}^2 签署人:

sage: polar.<r,ph> = E.polar_coordinates()
sage: polar
Chart (E^2, (r, ph))
sage: polar.coord_range()
r: (0, +oo); ph: [0, 2*pi] (periodic)

它们通过以下变换与笛卡尔坐标相关:

sage: E.coord_change(polar, cartesian).display()
x = r*cos(ph)
y = r*sin(ph)
sage: E.coord_change(cartesian, polar).display()
r = sqrt(x^2 + y^2)
ph = arctan2(y, x)

正交向量框架 (e_r, e_phi) 方法返回与极坐标关联的 polar_frame() ::

sage: polar_frame = E.polar_frame()
sage: polar_frame
Vector frame (E^2, (e_r,e_ph))
sage: er = polar_frame[1]
sage: er.display()
e_r = x/sqrt(x^2 + y^2) e_x + y/sqrt(x^2 + y^2) e_y

以上显示在默认框架(笛卡尔坐标系)中,具有默认坐标系(笛卡尔坐标系)。让我们要求在同一帧中显示,但组件用极坐标表示:

sage: er.display(cartesian.frame(), polar)
e_r = cos(ph) e_x + sin(ph) e_y

类似::

sage: eph = polar_frame[2]
sage: eph.display()
e_ph = -y/sqrt(x^2 + y^2) e_x + x/sqrt(x^2 + y^2) e_y
sage: eph.display(cartesian.frame(), polar)
e_ph = -sin(ph) e_x + cos(ph) e_y

我们可以查一下 (e_r, e_phi) 是正交框架:

sage: all([er.dot(er) == 1, er.dot(eph) == 0, eph.dot(eph) == 1])
True

标量场可以用极坐标表示:

sage: F.display()
F: E^2 --> R
   (x, y) |--> f(x, y)
   (r, ph) |--> f(r*cos(ph), r*sin(ph))
sage: F.display(polar)
F: E^2 --> R
   (r, ph) |--> f(r*cos(ph), r*sin(ph))

我们可以用极坐标系求向量场的分量:

sage: v.display()  # default frame and default coordinates (both Cartesian ones)
v = -y e_x + x e_y
sage: v.display(polar_frame)  # polar frame and default coordinates
v = sqrt(x^2 + y^2) e_ph
sage: v.display(polar_frame, polar)  # polar frame and polar coordinates
v = r e_ph
sage: w.display()
w = w_x(x, y) e_x + w_y(x, y) e_y
sage: w.display(polar_frame, polar)
w = (cos(ph)*w_x(r*cos(ph), r*sin(ph)) + sin(ph)*w_y(r*cos(ph), r*sin(ph))) e_r
+ (-sin(ph)*w_x(r*cos(ph), r*sin(ph)) + cos(ph)*w_y(r*cos(ph), r*sin(ph))) e_ph

极坐标梯度

让我们用极坐标定义一个通用标量场:

sage: H = E.scalar_field({polar: function('h')(r,ph)}, name='H')
sage: H.display(polar)
H: E^2 --> R
   (r, ph) |--> h(r, ph)

坡度 H 然后是:

sage: grad(H).display(polar_frame, polar)
grad(H) = d(h)/dr e_r + d(h)/dph/r e_ph

如果一个向量中的一个没有被指定,那么它们就可以通过一个括号来指定这个向量

sage: grad(H).display(cartesian.frame(), polar)
grad(H) = (r*cos(ph)*d(h)/dr - sin(ph)*d(h)/dph)/r e_x + (r*sin(ph)*d(h)/dr
 + cos(ph)*d(h)/dph)/r e_y
sage: grad(H)[polar_frame, 2, polar]
d(h)/dph/r

极坐标发散

让我们用极坐标定义一个通用向量场:

sage: u = E.vector_field(function('u_r')(r,ph),
....:                    function('u_ph', latex_name=r'u_\phi')(r,ph),
....:                    frame=polar_frame, chart=polar, name='u')
sage: u.display(polar_frame, polar)
u = u_r(r, ph) e_r + u_ph(r, ph) e_ph

它的分歧是:

sage: div(u).display(polar)
div(u): E^2 --> R
   (r, ph) |--> (r*d(u_r)/dr + u_r(r, ph) + d(u_ph)/dph)/r
sage: div(u).expr(polar)
(r*diff(u_r(r, ph), r) + u_r(r, ph) + diff(u_ph(r, ph), ph))/r
sage: div(u).expr(polar).expand()
u_r(r, ph)/r + diff(u_ph(r, ph), ph)/r + diff(u_r(r, ph), r)

默认情况下使用极坐标:

为了避免指定参数 polar_framepolar 在里面 display()expr()[] ,我们可以通过 set_default_chart()set_default_frame() ::

sage: E.set_default_chart(polar)
sage: E.set_default_frame(polar_frame)

然后我们有:

sage: u.display()
u = u_r(r, ph) e_r + u_ph(r, ph) e_ph
sage: u[1]
u_r(r, ph)
sage: v.display()
v = r e_ph
sage: v[2]
r
sage: w.display()
w = (cos(ph)*w_x(r*cos(ph), r*sin(ph)) + sin(ph)*w_y(r*cos(ph), r*sin(ph))) e_r + (-sin(ph)*w_x(r*cos(ph), r*sin(ph)) + cos(ph)*w_y(r*cos(ph), r*sin(ph))) e_ph
sage: div(u).expr()
(r*diff(u_r(r, ph), r) + u_r(r, ph) + diff(u_ph(r, ph), ph))/r

5进阶主题:欧几里德平面作为黎曼流形

mathbb{{E}}^2 实际上是一个 黎曼流形 (见 pseudo_riemannian ),即具有正定度量张量的光滑实流形:

sage: E.category()
Category of smooth manifolds over Real Field with 53 bits of precision
sage: E.base_field() is RR
True

事实上 RR is used here as a proxy for the real field (this should be replaced in the future, see the discussion at #24456 )53位的精度当然对符号计算没有任何作用。

用户图集 mathbb{{E}}^2 有两个图表:

sage: E.atlas()
[Chart (E^2, (x, y)), Chart (E^2, (r, ph))]

有三个向量帧定义在 mathbb{{E}}^2 ::

sage: E.frames()
[Coordinate frame (E^2, (e_x,e_y)),
 Coordinate frame (E^2, (d/dr,d/dph)),
 Vector frame (E^2, (e_r,e_ph))]

实际上,有两个与极坐标相关的框架:坐标系 (frac{{partial}}{{partial r}}, frac{{partial}}{{partial phi}}) 以及正交坐标系 (e_r, e_phi) .

黎曼度量

的默认度量张量 mathbb{{E}}^2 是::

sage: g = E.metric()
sage: g
Riemannian metric g on the Euclidean plane E^2
sage: g.display()
g = e^r*e^r + e^ph*e^ph

在上面的显示中, e^r = e^re^ph = e^phi 定义余帧的1-形式与正交极坐标系是对偶的吗 (e_r, e_phi) ,这是启用的默认向量帧 mathbb{{E}}^2 ::

sage: polar_frame.coframe()
Coframe (E^2, (e^r,e^ph))

当然,我们可能会要求一些与默认帧不同的显示:

sage: g.display(cartesian.frame())
g = dx*dx + dy*dy
sage: g.display(polar.frame())
g = dr*dr + r^2 dph*dph
sage: g[:]
[1 0]
[0 1]
sage: g[polar.frame(),:]
[  1   0]
[  0 r^2]

g 是一个 flat 度量:它的(Riemann)曲率张量(参见 riemann() )为零:

sage: g.riemann()
Tensor field Riem(g) of type (1,3) on the Euclidean plane E^2
sage: g.riemann().display()
Riem(g) = 0

公制 g 正在定义点积 mathbb{{E}}^2 ::

sage: v.dot(w) == g(v,w)
True
sage: norm(v) == sqrt(g(v,v))
True

向量场作为导数

向量场作为标量场的导数:

sage: v(F)
Scalar field v(F) on the Euclidean plane E^2
sage: v(F).display()
v(F): E^2 --> R
   (x, y) |--> -y*d(f)/dx + x*d(f)/dy
   (r, ph) |--> -r*sin(ph)*d(f)/d(r*cos(ph)) + r*cos(ph)*d(f)/d(r*sin(ph))
sage: v(F) == v.dot(grad(F))
True
sage: dF = F.differential()
sage: dF
1-form dF on the Euclidean plane E^2
sage: v(F) == dF(v)
True

布景 mathfrak{{X}}(mathbb{{E}}^2) 所有向量场的 mathbb{{E}}^2 光滑标量场交换代数上秩为2的自由模 mathbb{{E}}^2C^infty(mathbb{{E}}^2) ::

sage: XE = v.parent()
sage: XE
Free module X(E^2) of vector fields on the Euclidean plane E^2
sage: XE.category()
Category of finite dimensional modules over Algebra of differentiable
 scalar fields on the Euclidean plane E^2
sage: XE.base_ring()
Algebra of differentiable scalar fields on the Euclidean plane E^2
sage: CE = F.parent()
sage: CE
Algebra of differentiable scalar fields on the Euclidean plane E^2
sage: CE is XE.base_ring()
True
sage: CE.category()
Category of commutative algebras over Symbolic Ring
sage: rank(XE)
2

自由模的基 mathfrak{{X}}(mathbb{{E}}^2) 只不过是定义在 mathbb{{E}}^2 ::

sage: XE.bases()
[Coordinate frame (E^2, (e_x,e_y)),
 Coordinate frame (E^2, (d/dr,d/dph)),
 Vector frame (E^2, (e_r,e_ph))]

切线空间

在点$p$处计算的向量场是切线空间中的向量 T_pmathbb{{E}}^2 ::

sage: vp = v.at(p)
sage: vp.display()
v = -3 e_x - 2 e_y
sage: Tp = vp.parent()
sage: Tp
Tangent space at Point p on the Euclidean plane E^2
sage: Tp.category()
Category of finite dimensional vector spaces over Symbolic Ring
sage: dim(Tp)
2
sage: isinstance(Tp, FiniteRankFreeModule)
True
sage: sorted(Tp.bases(), key=str)
[Basis (d/dr,d/dph) on the Tangent space at Point p on the Euclidean plane E^2,
 Basis (e_r,e_ph) on the Tangent space at Point p on the Euclidean plane E^2,
 Basis (e_x,e_y) on the Tangent space at Point p on the Euclidean plane E^2]

Levi-Civita连接

与欧几里德度量有关的Levi-Civita联系 g 是::

sage: nabla = g.connection()
sage: nabla
Levi-Civita connection nabla_g associated with the Riemannian metric g on the Euclidean plane E^2

与极坐标相关的Christoffel符号有:

sage: g.christoffel_symbols_display()
Gam^r_ph,ph = -r
Gam^ph_r,ph = 1/r

默认情况下,只显示非零值和非冗余值(例如 Gamma^phi_{{, phi r}} 被跳过,因为它可以从 Gamma^phi_{{, r phi}} 最后两个指数的对称性)。

关于笛卡尔坐标的克里斯托弗符号都是零:

sage: g.christoffel_symbols_display(chart=cartesian, only_nonzero=False)
Gam^x_xx = 0
Gam^x_xy = 0
Gam^x_yy = 0
Gam^y_xx = 0
Gam^y_xy = 0
Gam^y_yy = 0

nabla_g 微分运算符中是否涉及连接:

sage: grad(F) == nabla(F).up(g)
True
sage: nabla(F) == grad(F).down(g)
True
sage: div(v) == nabla(v).trace()
True
sage: div(w) == nabla(w).trace()
True
sage: laplacian(F) == nabla(nabla(F).up(g)).trace()
True
sage: laplacian(w) == nabla(nabla(w).up(g)).trace(1,2)
True