如何更改坐标

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

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

从笛卡尔坐标开始

在本教程中,我们选择从笛卡尔坐标开始 (x,y,z) 。因此,我们宣布三维欧几里得空间 mathbb{E}^3 AS::

sage: E.<x,y,z> = EuclideanSpace()
sage: E
Euclidean space E^3

默认情况下,即不带可选参数 coordinates 在……里面 EuclideanSpacemathbb{E}^3 用笛卡尔坐标图表进行了初始化:

sage: E.atlas()
[Chart (E^3, (x, y, z))]

请参阅教程 如何在曲线坐标下实现向量微积分 例如,使用球坐标或柱坐标而不是笛卡尔坐标来初始化欧几里得空间。

让我们用以下符号表示 cartesian 笛卡尔坐标图表::

sage: cartesian = E.cartesian_coordinates()
sage: cartesian
Chart (E^3, (x, y, z))

通过方括号运算符执行对各个坐标的访问:

sage: cartesian[1]
x
sage: cartesian[:]
(x, y, z)

由于使用了 <x,y,z> 在声明时 E 、Python变量 xyz 已经被创建来存储坐标 (x,y,z) 作为象征性的表达。不需要通过以下方式声明它们 var() ,即打字 x, y, z = var('x y z') ;它们立即可用:

sage: y is cartesian[2]
True
sage: type(y)
<class 'sage.symbolic.expression.Expression'>

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

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

作为到目前为止创建的唯一坐标图表, cartesian 默认图表是否打开 E **

sage: cartesian is E.default_chart()
True

mathbb{E}^3 被赋予了正交化向量框架 (e_x, e_y, e_z) 与笛卡尔坐标关联:

sage: E.frames()
[Coordinate frame (E^3, (e_x,e_y,e_z))]

让我们用这个词来表示 cartesian_frame **

sage: cartesian_frame = E.cartesian_frame()
sage: cartesian_frame
Coordinate frame (E^3, (e_x,e_y,e_z))
sage: cartesian_frame is E.default_frame()
True

该帧的每个元素都是一个单位向量场;例如,我们有 e_xcdot e_x = 1 **

sage: e_x = cartesian_frame[1]
sage: e_x
Vector field e_x on the Euclidean space E^3
sage: e_x.dot(e_x).expr()
1

以及 e_xcdot e_y = 0 **

sage: e_y = cartesian_frame[2]
sage: e_x.dot(e_y).expr()
0

介绍球面坐标

通过以下方式引入球面坐标:

sage: spherical.<r,th,ph> = E.spherical_coordinates()
sage: spherical
Chart (E^3, (r, th, ph))

我们有:

sage: spherical[:]
(r, th, ph)
sage: spherical.coord_range()
r: (0, +oo); th: (0, pi); ph: [0, 2*pi] (periodic)

mathbb{E}^3 现在有两个坐标图表:

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

在上述调用期间,已自动实施了坐标变化公式 E.spherical_coordinates() **

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

如果我们要求以笛卡尔坐标绘制球面坐标的网格,则会自动使用这些公式:

sage: spherical.plot(cartesian, color={r:'red', th:'green', ph:'orange'})
Graphics3d Object

请注意

  • 红线是那些沿着 r 各不相同,而 (theta,phi) 保持固定;

  • 网格线是那些沿着 theta 各不相同,而 (r,phi) 保持固定;

  • 橙色的线条是沿着 phi 各不相同,而 (r,theta) 都是固定的。

有关自定义绘图的信息,请参阅的文档中的选项列表 plot() 。例如,我们可以画出平面中的球面坐标 theta=pi/2 就坐标而言 (x, y) **

sage: spherical.plot(cartesian, fixed_coords={th: pi/2}, ambient_coords=(x,y),
....:                color={r:'red', th:'green', ph:'orange'})
Graphics object consisting of 18 graphics primitives

类似地,半平面中的球面坐标网格 phi=0 以坐标的形式绘制 (x, z) 通过以下方式获得:

sage: spherical.plot(cartesian, fixed_coords={ph: 0}, ambient_coords=(x,z),
....:                color={r:'red', th:'green', ph:'orange'})
Graphics object consisting of 18 graphics primitives

笛卡尔向量标架与球面向量标架的关系

在这个阶段, mathbb{E}^3 被赋予三个向量帧:

sage: E.frames()
[Coordinate frame (E^3, (e_x,e_y,e_z)),
 Coordinate frame (E^3, (∂/∂r,∂/∂th,∂/∂ph)),
 Vector frame (E^3, (e_r,e_th,e_ph))]

The second one is the coordinate frame left(frac{partial}{partial r}, frac{partial}{partialtheta}, frac{partial}{partial phi}right) of spherical coordinates, while the third one is the standard orthonormal frame (e_r,e_theta,e_phi) associated with spherical coordinates. For Cartesian coordinates, the coordinate frame and the orthonormal frame coincide: it is (e_x,e_y,e_z). For spherical coordinates, the orthonormal frame is returned by the method spherical_frame():

sage: spherical_frame = E.spherical_frame()
sage: spherical_frame
Vector frame (E^3, (e_r,e_th,e_ph))

我们可以检查它是不是一个正交化框架,即它是否服从 e_icdot e_j = delta_{ij} **

sage: es = spherical_frame
sage: [[es[i].dot(es[j]).expr() for j in E.irange()] for i in E.irange()]
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]

通过该方法 display ,我们可以用笛卡尔坐标来表示正交球坐标系::

sage: for vec in spherical_frame:
....:     vec.display(cartesian_frame, spherical)
e_r = cos(ph)*sin(th) e_x + sin(ph)*sin(th) e_y + cos(th) e_z
e_th = cos(ph)*cos(th) e_x + cos(th)*sin(ph) e_y - sin(th) e_z
e_ph = -sin(ph) e_x + cos(ph) e_y

反之亦然:

sage: for vec in cartesian_frame:
....:     vec.display(spherical_frame, spherical)
e_x = cos(ph)*sin(th) e_r + cos(ph)*cos(th) e_th - sin(ph) e_ph
e_y = sin(ph)*sin(th) e_r + cos(th)*sin(ph) e_th + cos(ph) e_ph
e_z = cos(th) e_r - sin(th) e_th

We may also express the orthonormal frame (e_r,e_theta,e_phi) in terms on the coordinate frame left(frac{partial}{partial r}, frac{partial}{partialtheta}, frac{partial}{partial phi}right) (the latter being returned by the method frame() acting on the chart spherical):

sage: for vec in spherical_frame:
....:     vec.display(spherical.frame(), spherical)
e_r = ∂/∂r
e_th = 1/r ∂/∂th
e_ph = 1/(r*sin(th)) ∂/∂ph

介绍柱面坐标

柱面坐标的引入方式类似于球面坐标:

sage: cylindrical.<rh,ph,z> = E.cylindrical_coordinates()
sage: cylindrical
Chart (E^3, (rh, ph, z))

我们有:

sage: cylindrical[:]
(rh, ph, z)
sage: rh is cylindrical[1]
True
sage: cylindrical.coord_range()
rh: (0, +oo); ph: [0, 2*pi] (periodic); z: (-oo, +oo)

mathbb{E}^3 现在有三个坐标图表:

sage: E.atlas()
[Chart (E^3, (x, y, z)), Chart (E^3, (r, th, ph)), Chart (E^3, (rh, ph, z))]

将柱面坐标链接到笛卡尔坐标的变换包括:

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

现在,在上定义了五个向量帧 mathbb{E}^3 **

sage: E.frames()
[Coordinate frame (E^3, (e_x,e_y,e_z)),
 Coordinate frame (E^3, (∂/∂r,∂/∂th,∂/∂ph)),
 Vector frame (E^3, (e_r,e_th,e_ph)),
 Coordinate frame (E^3, (∂/∂rh,∂/∂ph,∂/∂z)),
 Vector frame (E^3, (e_rh,e_ph,e_z))]

与柱面坐标关联的正交化框架为 (e_rho, e_phi, e_z) **

sage: cylindrical_frame = E.cylindrical_frame()
sage: cylindrical_frame
Vector frame (E^3, (e_rh,e_ph,e_z))

我们可以检查它是否为正交帧::

sage: ec = cylindrical_frame
sage: [[ec[i].dot(ec[j]).expr() for j in E.irange()] for i in E.irange()]
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]

并以笛卡尔坐标系的形式表示:

sage: for vec in cylindrical_frame:
....:     vec.display(cartesian_frame, cylindrical)
e_rh = cos(ph) e_x + sin(ph) e_y
e_ph = -sin(ph) e_x + cos(ph) e_y
e_z = e_z

反之亦然:

sage: for vec in cartesian_frame:
....:     vec.display(cylindrical_frame, cylindrical)
e_x = cos(ph) e_rh - sin(ph) e_ph
e_y = sin(ph) e_rh + cos(ph) e_ph
e_z = e_z

当然,我们可以用球面框架来表示正交柱形框架::

sage: for vec in cylindrical_frame:
....:     vec.display(spherical_frame, spherical)
e_rh = sin(th) e_r + cos(th) e_th
e_ph = e_ph
e_z = cos(th) e_r - sin(th) e_th

伴随着反向转换::

sage: for vec in spherical_frame:
....:     vec.display(cylindrical_frame, spherical)
e_r = sin(th) e_rh + cos(th) e_z
e_th = cos(th) e_rh - sin(th) e_z
e_ph = e_ph

The orthonormal frame (e_rho,e_phi,e_z) can be expressed in terms on the coordinate frame left(frac{partial}{partialrho}, frac{partial}{partialphi}, frac{partial}{partial z}right) (the latter being returned by the method frame() acting on the chart cylindrical):

sage: for vec in cylindrical_frame:
....:     vec.display(cylindrical.frame(), cylindrical)
e_rh = ∂/∂rh
e_ph = 1/rh ∂/∂ph
e_z = ∂/∂z

如何在不同的系统中计算一个点的坐标

让我们介绍一下这一点 pin mathbb{E}^3 通过通用的SageMath语法从其父元素(此处为 mathbb{E}^3 ),即呼叫运营商 () ,以点的坐标作为第一个参数::

sage: p = E((-1, 1,0), chart=cartesian, name='p')
sage: p
Point p on the Euclidean space E^3

实际上,由于笛卡尔坐标是默认坐标,因此 chart=cartesian 可以省略::

sage: p = E((-1, 1,0), name='p')
sage: p
Point p on the Euclidean space E^3

的坐标 p 在给定坐标图表中,通过让相应的图表作用于 p **

sage: cartesian(p)
(-1, 1, 0)
sage: spherical(p)
(sqrt(2), 1/2*pi, 3/4*pi)
sage: cylindrical(p)
(sqrt(2), 3/4*pi, 0)

以下是根据其球面坐标定义的点的一些示例:

sage: q = E((4,pi/3,pi), chart=spherical, name='q')
sage: q
Point q on the Euclidean space E^3

我们那时有::

sage: spherical(q)
(4, 1/3*pi, pi)
sage: cartesian(q)
(-2*sqrt(3), 0, 2)
sage: cylindrical(q)
(2*sqrt(3), pi, 2)

如何在不同的坐标系中表示标量场

让我们在上定义一个标量字段 mathbb{E}^3 从它在笛卡尔坐标中的表达式:

sage: f = E.scalar_field(x^2+y^2 - z^2, name='f')

请注意,由于笛卡尔坐标是默认坐标,因此我们没有在上面的定义中指定它们。多亏了已知的坐标变换,表达式 f 根据其他坐标自动计算::

sage: f.display()
f: E^3 → ℝ
   (x, y, z) ↦ x^2 + y^2 - z^2
   (r, th, ph) ↦ -2*r^2*cos(th)^2 + r^2
   (rh, ph, z) ↦ rh^2 - z^2

我们可以将输出限制在单个坐标系中:

sage: f.display(cartesian)
f: E^3 → ℝ
   (x, y, z) ↦ x^2 + y^2 - z^2
sage: f.display(cylindrical)
f: E^3 → ℝ
   (rh, ph, z) ↦ rh^2 - z^2

通过该方法得到给定坐标系下的坐标表达式 expr() **

sage: f.expr()  # expression in the default chart (Cartesian coordinates)
x^2 + y^2 - z^2
sage: f.expr(spherical)
-2*r^2*cos(th)^2 + r^2
sage: f.expr(cylindrical)
rh^2 - z^2

的价值 f 在各点上 pq 是::

sage: f(p)
2
sage: f(q)
8

当然,我们可以在非默认图表中根据其坐标表达式定义标量字段::

sage: g = E.scalar_field(r^2, chart=spherical, name='g')

不使用关键字参数 chart ,可以将字典作为第一个参数传递,图表作为键::

sage: g = E.scalar_field({spherical: r^2}, name='g')

的表达式的计算 g 在其他坐标系中由该方法触发 display() **

sage: g.display()
g: E^3 → ℝ
   (x, y, z) ↦ x^2 + y^2 + z^2
   (r, th, ph) ↦ r^2
   (rh, ph, z) ↦ rh^2 + z^2

如何在不同的坐标系中表示矢量场

我们在上引入一个向量场 mathbb{E}^3 通过它在笛卡尔坐标系中的分量。因为后者是默认的矢量帧 mathbb{E}^3 ,它足以写下::

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

等同地,矢量场可以从它在笛卡尔坐标系上的展开直接定义:

sage: ex, ey, ez = cartesian_frame[:]
sage: v = -y*ex + x*ey + z^2*ez
sage: v.display()
-y e_x + x e_y + z^2 e_z

让我们提供 v 有一些名字,如上::

sage: v.set_name('v')
sage: v.display()
v = -y e_x + x e_y + z^2 e_z

的组件 v 由方括号运算符返回::

sage: v[1]
-y
sage: v[:]
[-y, x, z^2]

的表达式的计算 v 根据该方法触发的正交球坐标系 display() **

sage: v.display(spherical_frame)
v = z^3/sqrt(x^2 + y^2 + z^2) e_r
 - sqrt(x^2 + y^2)*z^2/sqrt(x^2 + y^2 + z^2) e_th + sqrt(x^2 + y^2) e_ph

我们注意到,组件仍然使用默认图表(笛卡尔坐标)表示。要在球形图中表示它们,只需将后者作为第二个参数传递给 display() **

sage: v.display(spherical_frame, spherical)
v = r^2*cos(th)^3 e_r - r^2*cos(th)^2*sin(th) e_th + r*sin(th) e_ph

再说一次, v 通过将向量框架指定为第一个参数,将坐标图表指定为最后一个参数,通过方括号运算符获得:

sage: v[spherical_frame, 1]
z^3/sqrt(x^2 + y^2 + z^2)
sage: v[spherical_frame, 1, spherical]
r^2*cos(th)^3
sage: v[spherical_frame, :, spherical]
[r^2*cos(th)^3, -r^2*cos(th)^2*sin(th), r*sin(th)]

类似地,表达 v 就圆柱形框架而言是:

sage: v.display(cylindrical_frame, cylindrical)
v = rh e_ph + z^2 e_z
sage: v[cylindrical_frame, :, cylindrical]
[0, rh, z^2]

向量场的值 v 在点上 p 是::

sage: vp = v.at(p)
sage: vp
Vector v at Point p on the Euclidean space E^3
sage: vp.display()
v = -e_x - e_y
sage: vp.display(spherical_frame.at(p))
v = sqrt(2) e_ph
sage: vp.display(cylindrical_frame.at(p))
v = sqrt(2) e_ph

向量场的值 v 在点上 q 是::

sage: vq = v.at(q)
sage: vq
Vector v at Point q on the Euclidean space E^3
sage: vq.display()
v = -2*sqrt(3) e_y + 4 e_z
sage: vq.display(spherical_frame.at(q))
v = 2 e_r - 2*sqrt(3) e_th + 2*sqrt(3) e_ph
sage: vq.display(cylindrical_frame.at(q))
v = 2*sqrt(3) e_ph + 4 e_z

如何更改默认坐标和默认向量框架

任何时候,用户都可以通过该方法更改默认坐标 set_default_chart() **

sage: E.set_default_chart(spherical)

然后::

sage: f.expr()
-2*r^2*cos(th)^2 + r^2
sage: v.display()
v = -r*sin(ph)*sin(th) e_x + r*cos(ph)*sin(th) e_y + r^2*cos(th)^2 e_z

请注意,默认的矢量坐标系仍然是笛卡尔坐标系;要更改为正交球坐标系,请使用 set_default_frame() **

sage: E.set_default_frame(spherical_frame)

然后::

sage: v.display()
v = r^2*cos(th)^3 e_r - r^2*cos(th)^2*sin(th) e_th + r*sin(th) e_ph
sage: v.display(cartesian_frame, cartesian)
v = -y e_x + x e_y + z^2 e_z