基本实施细节#
坐标系和矢量#
目前, sympy.vector 能够处理笛卡尔坐标系(也称为直角坐标系)、球面坐标系和其他曲线坐标系。
三维笛卡尔坐标系可以在 sympy.vector 作为
>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
构造函数的字符串参数表示分配给系统的名称,主要用于打印目的。
一旦是一个坐标系(本质上,一个 CoordSys3D 实例)已经定义,我们可以访问正交单位向量(即 \(\mathbf{{\hat{{i}}}}\) , \(\mathbf{{\hat{{j}}}}\) 和 \(\mathbf{{\hat{{k}}}}\) 向量)和坐标变量/基标量(即 \(\mathbf{{x}}\) , \(\mathbf{{y}}\) 和 \(\mathbf{{z}}\) 变量)与之对应。我们将在后面的部分讨论坐标变量。
的基向量 \(X\) , \(Y\) 和 \(Z\) 轴可以使用 i , j 和 k 属性。
>>> N.i
N.i
>>> type(N.i)
<class 'sympy.vector.vector.BaseVector'>
如上所述,基向量都是一个类的实例 BaseVector .
当A BaseVector 与标量相乘 Expr ),我们得到一个 VectorMul -基向量和标量的乘积。
>>> 3*N.i
3*N.i
>>> type(3*N.i)
<class 'sympy.vector.vector.VectorMul'>
添加 VectorMul 和 BaseVectors 导致形成 VectorAdd -当然,除了特殊情况。
>>> v = 2*N.i + N.j
>>> type(v)
<class 'sympy.vector.vector.VectorAdd'>
>>> v - N.j
2*N.i
>>> type(v - N.j)
<class 'sympy.vector.vector.VectorMul'>
零向量呢?可以使用 zero 分配给类的属性 Vector . 由于零向量的概念与所考虑的坐标系无关,因此我们使用 Vector.zero 无论何时需要这样的数量。
>>> from sympy.vector import Vector
>>> Vector.zero
0
>>> type(Vector.zero)
<class 'sympy.vector.vector.VectorZero'>
>>> N.i + Vector.zero
N.i
>>> Vector.zero == 2*Vector.zero
True
上面显示的所有类- BaseVector , VectorMul , VectorAdd 和 VectorZero 是的子类 Vector .
您不应该实例化的任何子类的对象 Vector . 使用 BaseVector 分配给 CoordSys3D 实例和(如果需要) Vector.zero 作为构造块,任何类型的向量表达式都可以用基本的数学运算符构造 + , - , * . 和 / .
>>> v = N.i - 2*N.j
>>> v/3
1/3*N.i + (-2/3)*N.j
>>> v + N.k
N.i + (-2)*N.j + N.k
>>> Vector.zero/2
0
>>> (v/3)*4
4/3*N.i + (-8/3)*N.j
除了基本的数学运算外,向量运算 dot 和 cross 也可以在 Vector .
>>> v1 = 2*N.i + 3*N.j - N.k
>>> v2 = N.i - 4*N.j + N.k
>>> v1.dot(v2)
-11
>>> v1.cross(v2)
(-1)*N.i + (-3)*N.j + (-11)*N.k
>>> v2.cross(v1)
N.i + 3*N.j + 11*N.k
这个 & 和 ^ 操作员已为 dot 和 cross 方法分别为。
>>> v1 & v2
-11
>>> v1 ^ v2
(-1)*N.i + (-3)*N.j + (-11)*N.k
但是,这不是执行这些操作的推荐方法。使用原始方法可以使代码更清晰、更易于理解。
除了这些运算,还可以计算 Vector 实例 sympy.vector . 稍后再谈。
向量的同调运算#
共同行动 simplify , trigsimp , diff 和 factor 从事 Vector 对象,使用标准的SymPy API。
本质上,这些方法工作在提供的向量表达式中的度量值(基向量的系数)。
>>> from sympy.abc import a, b, c
>>> from sympy import sin, cos, trigsimp, diff
>>> v = (a*b + a*c + b**2 + b*c)*N.i + N.j
>>> v.factor()
((a + b)*(b + c))*N.i + N.j
>>> v = (sin(a)**2 + cos(a)**2)*N.i - (2*cos(b)**2 - 1)*N.k
>>> trigsimp(v)
N.i + (-cos(2*b))*N.k
>>> v.simplify()
N.i + (-cos(2*b))*N.k
>>> diff(v, b)
(4*sin(b)*cos(b))*N.k
>>> from sympy import Derivative
>>> Derivative(v, b).doit()
(4*sin(b)*cos(b))*N.k
Integral 也适用于 Vector 实例,类似于 Derivative .
>>> from sympy import Integral
>>> v1 = a*N.i + sin(a)*N.j - N.k
>>> Integral(v1, a)
(Integral(a, a))*N.i + (Integral(sin(a), a))*N.j + (Integral(-1, a))*N.k
>>> Integral(v1, a).doit()
a**2/2*N.i + (-cos(a))*N.j + (-a)*N.k
点#
如前所述,每个坐标系对应一个唯一的原点。总的来说,这些要点已经在 sympy.vector 以 Point 班级。
要访问系统源,请使用 origin 性质 CoordSys3D 班级。
>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
>>> N.origin
N.origin
>>> type(N.origin)
<class 'sympy.vector.point.Point'>
可以使用 locate_new 方法 Point . 参数包括新的 Point ,以及相对于“父对象”的位置向量 Point .
>>> from sympy.abc import a, b, c
>>> P = N.origin.locate_new('P', a*N.i + b*N.j + c*N.k)
>>> Q = P.locate_new('Q', -b*N.j)
喜欢 Vector ,用户永远不必明确实例化 Point . 这是因为可以使用 origin A的 CoordSys3D 作为参考,然后使用 locate_new 关于它和随后的 Point 实例。
a的位置向量 Point 相对于另一个人 Point 可以使用 position_wrt 方法。
>>> P.position_wrt(Q)
b*N.j
>>> Q.position_wrt(N.origin)
a*N.i + c*N.k
此外,还可以获得 \(X\) , \(Y\) 和 \(Z\) a的坐标 Point 关于a CoordSys3D 以元组的形式。这是通过使用 express_coordinates 方法。
>>> Q.express_coordinates(N)
(a, 0, c)
并矢#
并矢张量或并矢张量是由向量对并置形成的二阶张量。因此,向量的外积导致并矢的形成。并矢张量在 sympy.vector 在 Dyadic 班级。
再一次,您永远不必实例化 Dyadic . 向量的外积可以用 outer 方法 Vector . 这个 | 运算符已为重载 outer .
>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
>>> N.i.outer(N.j)
(N.i|N.j)
>>> N.i|N.j
(N.i|N.j)
类似 Vector , Dyadic 也有后续的子类,比如 BaseDyadic , DyadicMul , DyadicAdd . 和一样 Vector ,零并矢可以从 Dyadic.zero .
所有基本的数学运算都与 Dyadic 也是。
>>> dyad = N.i.outer(N.k)
>>> dyad*3
3*(N.i|N.k)
>>> dyad - dyad
0
>>> dyad + 2*(N.j|N.i)
(N.i|N.k) + 2*(N.j|N.i)
dot 和 cross 也在 Dyadic 实例之间以及 Dyadic 和 Vector (反之亦然)根据各自的数学定义。就像 Vector , & 和 ^ 已经超载了 dot 和 cross .
>>> d = N.i.outer(N.j)
>>> d.dot(N.j|N.j)
(N.i|N.j)
>>> d.dot(N.i)
0
>>> d.dot(N.j)
N.i
>>> N.i.dot(d)
N.j
>>> N.k ^ d
(N.j|N.j)