SymPy-1-13-中文文件-十三-

绝不原创的飞龙發表於2024-06-27

SymPy 1.13 中文文件(十三)

原文:docs.sympy.org/latest/index.html

矩陣類別

原文連結:docs.sympy.org/latest/modules/matrices/kind.html

class sympy.matrices.kind.MatrixKind(element_kind=NumberKind)

SymPy 中所有矩陣的類別。

此類的基本類是MatrixBaseMatrixExpr,但任何表示矩陣的表示式都可以具有這種類別。

引數:

元素類別:類別

元素型別。預設是sympy.core.kind.NumberKind,表示矩陣只包含數字。

示例

任何矩陣類的例項均具有MatrixKind類別:

>>> from sympy import MatrixSymbol
>>> A = MatrixSymbol('A', 2, 2)
>>> A.kind
MatrixKind(NumberKind) 

表示矩陣的表示式可能不是 Matrix 類的例項,但它將具有MatrixKind類別:

>>> from sympy import MatrixExpr, Integral
>>> from sympy.abc import x
>>> intM = Integral(A, x)
>>> isinstance(intM, MatrixExpr)
False
>>> intM.kind
MatrixKind(NumberKind) 

使用isinstance()檢查是否為MatrixKind,無需指定元素型別。使用is來檢查包括元素型別的類別:

>>> from sympy import Matrix
>>> from sympy.core import NumberKind
>>> from sympy.matrices import MatrixKind
>>> M = Matrix([1, 2])
>>> isinstance(M.kind, MatrixKind)
True
>>> M.kind is MatrixKind(NumberKind)
True 

另請參見

sympy.core.kind.NumberKindsympy.core.kind.UndefinedKindsympy.core.containers.TupleKindsympy.sets.sets.SetKind

__weakref__

對物件的弱引用列表

密集矩陣

原文連結:docs.sympy.org/latest/modules/matrices/dense.html

sympy.matrices.dense.Matrix

別名 MutableDenseMatrix

class sympy.matrices.dense.DenseMatrix

基於 DomainMatrix 的矩陣實現作為內部表示

LDLdecomposition(hermitian=True)

返回矩陣 A 的 LDL 分解 (L, D),使得當 hermitian 標誌為 True 時,L * D * L.H == A;當 hermitian 為 False 時,L * D * L.T == A。此方法消除了平方根的使用。此外,確保 L 的所有對角線條目都為 1。如果 hermitian 為 True,則 A 必須是 Hermite 正定矩陣;否則必須是對稱矩陣。

示例

>>> from sympy import Matrix, eye
>>> A = Matrix(((25, 15, -5), (15, 18, 0), (-5, 0, 11)))
>>> L, D = A.LDLdecomposition()
>>> L
Matrix([
[   1,   0, 0],
[ 3/5,   1, 0],
[-1/5, 1/3, 1]])
>>> D
Matrix([
[25, 0, 0],
[ 0, 9, 0],
[ 0, 0, 9]])
>>> L * D * L.T * A.inv() == eye(A.rows)
True 

矩陣可以有複數條目:

>>> from sympy import I
>>> A = Matrix(((9, 3*I), (-3*I, 5)))
>>> L, D = A.LDLdecomposition()
>>> L
Matrix([
[   1, 0],
[-I/3, 1]])
>>> D
Matrix([
[9, 0],
[0, 4]])
>>> L*D*L.H == A
True 

另請參閱

sympy.matrices.dense.DenseMatrix.choleskysympy.matrices.matrixbase.MatrixBase.LUdecompositionQRdecomposition

as_immutable()

返回此矩陣的不可變版本

as_mutable()

返回此矩陣的可變版本

示例

>>> from sympy import ImmutableMatrix
>>> X = ImmutableMatrix([[1, 2], [3, 4]])
>>> Y = X.as_mutable()
>>> Y[1, 1] = 5 # Can set values in Y
>>> Y
Matrix([
[1, 2],
[3, 5]]) 
cholesky(hermitian=True)

返回矩陣 A 的 Cholesky 分解 L,使得當 hermitian 標誌為 True 時,L * L.H == A;當 hermitian 為 False 時,L * L.T == A。

如果 hermitian 為 True,則 A 必須是 Hermite 正定矩陣;如果為 False,則必須是對稱矩陣。

示例

>>> from sympy import Matrix
>>> A = Matrix(((25, 15, -5), (15, 18, 0), (-5, 0, 11)))
>>> A.cholesky()
Matrix([
[ 5, 0, 0],
[ 3, 3, 0],
[-1, 1, 3]])
>>> A.cholesky() * A.cholesky().T
Matrix([
[25, 15, -5],
[15, 18,  0],
[-5,  0, 11]]) 

矩陣可以有複數條目:

>>> from sympy import I
>>> A = Matrix(((9, 3*I), (-3*I, 5)))
>>> A.cholesky()
Matrix([
[ 3, 0],
[-I, 2]])
>>> A.cholesky() * A.cholesky().H
Matrix([
[   9, 3*I],
[-3*I,   5]]) 

當矩陣非正定時,非 Hermite Cholesky 分解可能是有用的。

>>> A = Matrix([[1, 2], [2, 1]])
>>> L = A.cholesky(hermitian=False)
>>> L
Matrix([
[1,         0],
[2, sqrt(3)*I]])
>>> L*L.T == A
True 

另請參閱

sympy.matrices.dense.DenseMatrix.LDLdecompositionsympy.matrices.matrixbase.MatrixBase.LUdecompositionQRdecomposition

lower_triangular_solve(rhs)

解決 Ax = B,其中 A 是一個下三角矩陣。

另請參閱

upper_triangular_solve, gauss_jordan_solve, cholesky_solve, diagonal_solve, LDLsolve, LUsolve, QRsolve, pinv_solve, cramer_solve

upper_triangular_solve(rhs)

解決Ax = B,其中 A 是上三角矩陣。

另見

lower_triangular_solve, gauss_jordan_solve, cholesky_solve, diagonal_solve, LDLsolve, LUsolve, QRsolve, pinv_solve, cramer_solve

class sympy.matrices.dense.MutableDenseMatrix(*args, **kwargs)
simplify(**kwargs)

對矩陣元素應用簡化操作。

這是一個 M.applyfunc(lambda x: simplify(x, ratio, measure))的快捷方式。

另見

sympy.simplify.simplify.simplify

class sympy.matrices.immutable.ImmutableDenseMatrix(*args, **kwargs)

建立矩陣的不可變版本。

示例

>>> from sympy import eye, ImmutableMatrix
>>> ImmutableMatrix(eye(3))
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
>>> _[0, 0] = 42
Traceback (most recent call last):
...
TypeError: Cannot set values of ImmutableDenseMatrix 

稀疏矩陣

原文:docs.sympy.org/latest/modules/matrices/sparse.html

稀疏矩陣類參考文件

sympy.matrices.sparse.SparseMatrix

別名為MutableSparseMatrix

class sympy.matrices.sparse.MutableSparseMatrix(*args, **kwargs)

不可變稀疏矩陣類參考文件

class sympy.matrices.immutable.ImmutableSparseMatrix(*args, **kwargs)

建立不可變版本的稀疏矩陣。

示例

>>> from sympy import eye, ImmutableSparseMatrix
>>> ImmutableSparseMatrix(1, 1, {})
Matrix([[0]])
>>> ImmutableSparseMatrix(eye(3))
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
>>> _[0, 0] = 42
Traceback (most recent call last):
...
TypeError: Cannot set values of ImmutableSparseMatrix
>>> _.shape
(3, 3) 

稀疏工具

原文連結:docs.sympy.org/latest/modules/matrices/sparsetools.html

sympy.matrices.sparsetools._doktocsr()

將稀疏矩陣轉換為壓縮稀疏行(CSR)格式。

引數:

A:按鍵(行,列)排序的非零元素

JA:JA[i] 是與 A[i]對應的列

IA:IA[i] 包含 A 中第一個非零元素的索引

對於行[i]的非零元素數。因此,IA[i+1] - IA[i] 給出行[i]的非零元素數。IA 的長度始終比矩陣中的行數多 1。

示例

>>> from sympy.matrices.sparsetools import _doktocsr
>>> from sympy import SparseMatrix, diag
>>> m = SparseMatrix(diag(1, 2, 3))
>>> m[2, 0] = -1
>>> _doktocsr(m)
[[1, 2, -1, 3], [0, 1, 0, 2], [0, 1, 2, 4], [3, 3]] 
sympy.matrices.sparsetools._csrtodok()

將 CSR 表示轉換為 DOK 表示。

示例

>>> from sympy.matrices.sparsetools import _csrtodok
>>> _csrtodok([[5, 8, 3, 6], [0, 1, 2, 1], [0, 0, 2, 3, 4], [4, 3]])
Matrix([
[0, 0, 0],
[5, 8, 0],
[0, 0, 3],
[0, 6, 0]]) 
sympy.matrices.sparsetools.banded(**kwargs)

從描述矩陣對角線的給定字典返回稀疏矩陣。鍵為正值表示上對角線,負值表示主對角線以下。值可以是:

  • 表示式或單引數函式,

  • 值的列表或元組,

  • 矩陣

如果沒有給出尺寸,則返回的矩陣大小將足夠大,以包含提供的最大非零值。

Kwargs

矩陣的對角線;如果計算

未給出。

矩陣的列數;如果計算

未給出。

示例

>>> from sympy import banded, ones, Matrix
>>> from sympy.abc import x 

如果元組中給出了顯式值,則矩陣將自動調整大小以包含所有值,否則將單個值填充到整個對角線上:

>>> banded({1: (1, 2, 3), -1: (4, 5, 6), 0: x})
Matrix([
[x, 1, 0, 0],
[4, x, 2, 0],
[0, 5, x, 3],
[0, 0, 6, x]]) 

接受單個引數的函式可用於根據對角線索引(從 0 開始)填充對角線。必須提供矩陣的大小(或形狀)以獲得超過 1x1 的矩陣:

>>> s = lambda d: (1 + d)**2
>>> banded(5, {0: s, 2: s, -2: 2})
Matrix([
[1, 0, 1,  0,  0],
[0, 4, 0,  4,  0],
[2, 0, 9,  0,  9],
[0, 2, 0, 16,  0],
[0, 0, 2,  0, 25]]) 

放置在對角線上的矩陣的對角線將與指定的對角線重合:

>>> vert = Matrix([1, 2, 3])
>>> banded({0: vert}, cols=3)
Matrix([
[1, 0, 0],
[2, 1, 0],
[3, 2, 1],
[0, 3, 2],
[0, 0, 3]]) 
>>> banded(4, {0: ones(2)})
Matrix([
[1, 1, 0, 0],
[1, 1, 0, 0],
[0, 0, 1, 1],
[0, 0, 1, 1]]) 

如果指定的大小無法容納所有值的整數倍,則會引發錯誤。這裡,行被指定為奇數(但需要偶數才能容納對角線上的 2x2 非對角線元素):

>>> banded({0: 2, 1: ones(2)}, rows=5)
Traceback (most recent call last):
...
ValueError:
sequence does not fit an integral number of times in the matrix 

在這裡,提供了偶數行…但是正方形矩陣也有偶數列。正如我們在上一個示例中看到的,需要奇數行:

>>> banded(4, {0: 2, 1: ones(2)})  # trying to make 4x4 and cols must be odd
Traceback (most recent call last):
...
ValueError:
sequence does not fit an integral number of times in the matrix 

避免計算行數的方法是將矩陣元素封裝在元組中,並指示所需的元素數量放在右邊:

>>> banded({0: 2, 2: (ones(2),)*3})
Matrix([
[2, 0, 1, 1, 0, 0, 0, 0],
[0, 2, 1, 1, 0, 0, 0, 0],
[0, 0, 2, 0, 1, 1, 0, 0],
[0, 0, 0, 2, 1, 1, 0, 0],
[0, 0, 0, 0, 2, 0, 1, 1],
[0, 0, 0, 0, 0, 2, 1, 1]]) 

如果給定的條目寫入了多個值,將引發錯誤。這裡,如果將它們放置在第一個對角線上,這些 1 將與主對角線重疊:

>>> banded({0: (2,)*5, 1: (ones(2),)*3})
Traceback (most recent call last):
...
ValueError: collision at (1, 1) 

透過在全一的 2x2 矩陣左下角放置 0,可以避免碰撞:

>>> u2 = Matrix([
... [1, 1],
... [0, 1]])
>>> banded({0: [2]*5, 1: [u2]*3})
Matrix([
[2, 1, 1, 0, 0, 0, 0],
[0, 2, 1, 0, 0, 0, 0],
[0, 0, 2, 1, 1, 0, 0],
[0, 0, 0, 2, 1, 0, 0],
[0, 0, 0, 0, 2, 1, 1],
[0, 0, 0, 0, 0, 0, 1]]) 

不可變矩陣

原文連結:docs.sympy.org/latest/modules/matrices/immutablematrices.html

在 SymPy 中,標準的Matrix類是可變的。出於效能考慮這一點非常重要,但這也意味著標準矩陣不能很好地與 SymPy 的其他部分互動。這是因為大多數 SymPy 類繼承自不可變的Basic物件。

ImmutableDenseMatrix 類的使命是解決效能/可變性與安全性/不可變性之間的張力。不可變矩陣幾乎可以完成普通矩陣的所有功能,但它們繼承自Basic,因此可以更自然地與 SymPy 的其他部分互動。ImmutableMatrix 還繼承自MatrixExpr,允許它與 SymPy 的矩陣表示式模組自由互動。

透過呼叫建構函式,您可以將任何類似於矩陣的物件轉換為ImmutableMatrix

>>> from sympy import Matrix, ImmutableMatrix
>>> M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> M[1, 1] = 0
>>> IM = ImmutableMatrix(M)
>>> IM
Matrix([
[1, 2, 3],
[4, 0, 6],
[7, 8, 9]])
>>> IM[1, 1] = 5
Traceback (most recent call last):
...
TypeError: Can not set values in Immutable Matrix. Use Matrix instead. 

ImmutableMatrix 類參考

sympy.matrices.immutable.ImmutableMatrix

ImmutableDenseMatrix 的別名。

class sympy.matrices.immutable.ImmutableDenseMatrix(*args, **kwargs)

建立一個矩陣的不可變版本。

示例

>>> from sympy import eye, ImmutableMatrix
>>> ImmutableMatrix(eye(3))
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
>>> _[0, 0] = 42
Traceback (most recent call last):
...
TypeError: Cannot set values of ImmutableDenseMatrix 

矩陣表示式

原文:docs.sympy.org/latest/modules/matrices/expressions.html

矩陣表示式模組允許使用者編寫如下語句

>>> from sympy import MatrixSymbol, Matrix
>>> X = MatrixSymbol('X', 3, 3)
>>> Y = MatrixSymbol('Y', 3, 3)
>>> (X.T*X).I*Y
X**(-1)*X.T**(-1)*Y 
>>> Matrix(X)
Matrix([
[X[0, 0], X[0, 1], X[0, 2]],
[X[1, 0], X[1, 1], X[1, 2]],
[X[2, 0], X[2, 1], X[2, 2]]]) 
>>> (X*Y)[1, 2]
X[1, 0]*Y[0, 2] + X[1, 1]*Y[1, 2] + X[1, 2]*Y[2, 2] 

其中XYMatrixSymbol,而不是標量符號。

支援矩陣表示式的導數。一個矩陣關於另一個矩陣的導數通常是一個四維陣列,但如果一些維度是平凡的或對角的,導數演算法將嘗試將結果表示為矩陣表示式:

>>> a = MatrixSymbol("a", 3, 1)
>>> b = MatrixSymbol("b", 3, 1)
>>> (a.T*X**2*b).diff(X)
a*b.T*X.T + X.T*a*b.T 
>>> X.diff(X)
PermuteDims(ArrayTensorProduct(I, I), (3)(1 2)) 

最後的輸出是一個陣列表示式,因為返回的符號是四維的。

矩陣表示式核心參考

class sympy.matrices.expressions.MatrixExpr(*args, **kwargs)

矩陣表示式的超類

MatrixExprs 表示在特定基礎內表示的抽象矩陣,線性變換。

示例

>>> from sympy import MatrixSymbol
>>> A = MatrixSymbol('A', 3, 3)
>>> y = MatrixSymbol('y', 3, 1)
>>> x = (A.T*A).I * A * y 

參見

MatrixSymbolMatAddMatMulTransposeInverse

property T

矩陣轉置

as_coeff_Mul(rational=False)

高效提取乘積的係數。

as_explicit()

返回一個明確表示元素的密集矩陣

返回一個型別為 ImmutableDenseMatrix 的物件。

示例

>>> from sympy import Identity
>>> I = Identity(3)
>>> I
I
>>> I.as_explicit()
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]) 

參見

as_mutable

返回可變矩陣型別

as_mutable()

返回一個密集的可變矩陣,其元素明確表示

示例

>>> from sympy import Identity
>>> I = Identity(3)
>>> I
I
>>> I.shape
(3, 3)
>>> I.as_mutable()
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]) 

參見

as_explicit

返回 ImmutableDenseMatrix

equals(other)

測試矩陣之間的逐元素相等性,可能是不同型別的矩陣

>>> from sympy import Identity, eye
>>> Identity(3).equals(eye(3))
True 
static from_index_summation(expr, first_index=None, last_index=None, dimensions=None)

將具有明確求和索引的矩陣表示式解析為沒有索引的矩陣表示式,如果可能的話。

此轉換以數學符號表示:

(\sum_{j=0}^{N-1} A_{i,j} B_{j,k} \Longrightarrow \mathbf{A}\cdot \mathbf{B})

可選引數first_index:指定用作表示式起始的自由索引。

示例

>>> from sympy import MatrixSymbol, MatrixExpr, Sum
>>> from sympy.abc import i, j, k, l, N
>>> A = MatrixSymbol("A", N, N)
>>> B = MatrixSymbol("B", N, N)
>>> expr = Sum(A[i, j]*B[j, k], (j, 0, N-1))
>>> MatrixExpr.from_index_summation(expr)
A*B 

檢測到轉置:

>>> expr = Sum(A[j, i]*B[j, k], (j, 0, N-1))
>>> MatrixExpr.from_index_summation(expr)
A.T*B 

檢測跡:

>>> expr = Sum(A[i, i], (i, 0, N-1))
>>> MatrixExpr.from_index_summation(expr)
Trace(A) 

更復雜的表示式:

>>> expr = Sum(A[i, j]*B[k, j]*A[l, k], (j, 0, N-1), (k, 0, N-1))
>>> MatrixExpr.from_index_summation(expr)
A*B.T*A.T 
class sympy.matrices.expressions.MatrixSymbol(name, n, m)

矩陣物件的符號表示

建立一個 SymPy 符號來表示一個矩陣。此矩陣具有形狀,並可包含在矩陣表示式中

示例

>>> from sympy import MatrixSymbol, Identity
>>> A = MatrixSymbol('A', 3, 4) # A 3 by 4 Matrix
>>> B = MatrixSymbol('B', 4, 3) # A 4 by 3 Matrix
>>> A.shape
(3, 4)
>>> 2*A*B + Identity(3)
I + 2*A*B 
class sympy.matrices.expressions.MatAdd(*args, evaluate=False, check=None, _sympify=True)

矩陣表示式的和

MatAdd 繼承自並像 SymPy Add 操作

示例

>>> from sympy import MatAdd, MatrixSymbol
>>> A = MatrixSymbol('A', 5, 5)
>>> B = MatrixSymbol('B', 5, 5)
>>> C = MatrixSymbol('C', 5, 5)
>>> MatAdd(A, B, C)
A + B + C 
class sympy.matrices.expressions.MatMul(*args, evaluate=False, check=None, _sympify=True)

矩陣表示式的乘積

示例

>>> from sympy import MatMul, MatrixSymbol
>>> A = MatrixSymbol('A', 5, 4)
>>> B = MatrixSymbol('B', 4, 3)
>>> C = MatrixSymbol('C', 3, 6)
>>> MatMul(A, B, C)
A*B*C 
class sympy.matrices.expressions.MatPow(base, exp, evaluate=False, **options)
sympy.matrices.expressions.hadamard_product(*matrices)

返回矩陣的逐元素(又名 Hadamard)乘積。

示例

>>> from sympy import hadamard_product, MatrixSymbol
>>> A = MatrixSymbol('A', 2, 3)
>>> B = MatrixSymbol('B', 2, 3)
>>> hadamard_product(A)
A
>>> hadamard_product(A, B)
HadamardProduct(A, B)
>>> hadamard_product(A, B)[0, 1]
A[0, 1]*B[0, 1] 
class sympy.matrices.expressions.HadamardProduct(*args, evaluate=False, check=None)

矩陣表示式的逐元素乘積

示例

矩陣符號的 Hadamard 乘積:

>>> from sympy import hadamard_product, HadamardProduct, MatrixSymbol
>>> A = MatrixSymbol('A', 5, 5)
>>> B = MatrixSymbol('B', 5, 5)
>>> isinstance(hadamard_product(A, B), HadamardProduct)
True 

注意

這是一個簡單儲存其引數而不進行評估的符號物件。要實際計算乘積,請使用函式 hadamard_product()HadamardProduct.doit

class sympy.matrices.expressions.HadamardPower(base, exp)

矩陣表示式的逐元素乘冪

引數:

base:標量或矩陣

exp:標量或矩陣

注意事項

有四種可用的哈達瑪乘方的定義。讓我們將 (A, B) 視為 ((m, n)) 矩陣,(a, b) 視為標量。

矩陣的標量乘方:

[\begin{split}A^{\circ b} = \begin{bmatrix} A_{0, 0}^b & A_{0, 1}^b & \cdots & A_{0, n-1}^b \ A_{1, 0}^b & A_{1, 1}^b & \cdots & A_{1, n-1}^b \ \vdots & \vdots & \ddots & \vdots \ A_{m-1, 0}^b & A_{m-1, 1}^b & \cdots & A_{m-1, n-1}^b \end{bmatrix}\end{split}]

矩陣的標量乘方:

[\begin{split}a^{\circ B} = \begin{bmatrix} a^{B_{0, 0}} & a^{B_{0, 1}} & \cdots & a^{B_{0, n-1}} \ a^{B_{1, 0}} & a^{B_{1, 1}} & \cdots & a^{B_{1, n-1}} \ \vdots & \vdots & \ddots & \vdots \ a^{B_{m-1, 0}} & a^{B_{m-1, 1}} & \cdots & a^{B_{m-1, n-1}} \end{bmatrix}\end{split}]

矩陣的矩陣乘方:

[\begin{split}A^{\circ B} = \begin{bmatrix} A_{0, 0}^{B_{0, 0}} & A_{0, 1}^{B_{0, 1}} & \cdots & A_{0, n-1}^{B_{0, n-1}} \ A_{1, 0}^{B_{1, 0}} & A_{1, 1}^{B_{1, 1}} & \cdots & A_{1, n-1}^{B_{1, n-1}} \ \vdots & \vdots & \ddots & \vdots \ A_{m-1, 0}^{B_{m-1, 0}} & A_{m-1, 1}^{B_{m-1, 1}} & \cdots & A_{m-1, n-1}^{B_{m-1, n-1}} \end{bmatrix}\end{split}]

標量的標量乘方:

[a^{\circ b} = a^b]

class sympy.matrices.expressions.Inverse(mat, exp=-1)

矩陣表示式的乘法逆

這是一個簡單儲存其引數而不進行評估的符號物件。要實際計算逆矩陣,請使用矩陣的 .inverse() 方法。

示例

>>> from sympy import MatrixSymbol, Inverse
>>> A = MatrixSymbol('A', 3, 3)
>>> B = MatrixSymbol('B', 3, 3)
>>> Inverse(A)
A**(-1)
>>> A.inverse() == Inverse(A)
True
>>> (A*B).inverse()
B**(-1)*A**(-1)
>>> Inverse(A*B)
(A*B)**(-1) 
class sympy.matrices.expressions.Transpose(*args, **kwargs)

矩陣表示式的轉置。

這是一個簡單儲存其引數而不進行評估的符號物件。要實際計算轉置,請使用 transpose() 函式或矩陣的 .T 屬性。

示例

>>> from sympy import MatrixSymbol, Transpose, transpose
>>> A = MatrixSymbol('A', 3, 5)
>>> B = MatrixSymbol('B', 5, 3)
>>> Transpose(A)
A.T
>>> A.T == transpose(A) == Transpose(A)
True
>>> Transpose(A*B)
(A*B).T
>>> transpose(A*B)
B.T*A.T 
class sympy.matrices.expressions.Trace(mat)

矩陣跡

表示矩陣表示式的跡。

示例

>>> from sympy import MatrixSymbol, Trace, eye
>>> A = MatrixSymbol('A', 3, 3)
>>> Trace(A)
Trace(A)
>>> Trace(eye(3))
Trace(Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]))
>>> Trace(eye(3)).simplify()
3 
class sympy.matrices.expressions.FunctionMatrix(rows, cols, lamda)

使用一個函式(Lambda)表示矩陣,該函式根據每個矩陣條目的座標給出輸出。

引數:

rows:非負整數。可以是符號。

cols:非負整數。可以是符號。

lamda:函式、Lambda 或字串

如果它是 SymPy 的 FunctionLambda 例項,則應能接受表示矩陣座標的兩個引數。

如果它是一個純粹包含 Python lambda 語義的字串,則由 SymPy 解析器解釋,並轉換為 SymPy 的 Lambda 例項。

示例

Lambda 建立 FunctionMatrix

>>> from sympy import FunctionMatrix, symbols, Lambda, MatPow
>>> i, j, n, m = symbols('i,j,n,m')
>>> FunctionMatrix(n, m, Lambda((i, j), i + j))
FunctionMatrix(n, m, Lambda((i, j), i + j)) 

從 SymPy 函式建立 FunctionMatrix

>>> from sympy import KroneckerDelta
>>> X = FunctionMatrix(3, 3, KroneckerDelta)
>>> X.as_explicit()
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]) 

從 SymPy 未定義函式建立 FunctionMatrix

>>> from sympy import Function
>>> f = Function('f')
>>> X = FunctionMatrix(3, 3, f)
>>> X.as_explicit()
Matrix([
[f(0, 0), f(0, 1), f(0, 2)],
[f(1, 0), f(1, 1), f(1, 2)],
[f(2, 0), f(2, 1), f(2, 2)]]) 

從 Python lambda 建立 FunctionMatrix

>>> FunctionMatrix(n, m, 'lambda i, j: i + j')
FunctionMatrix(n, m, Lambda((i, j), i + j)) 

矩陣乘積的惰性求值示例:

>>> Y = FunctionMatrix(1000, 1000, Lambda((i, j), i + j))
>>> isinstance(Y*Y, MatPow) # this is an expression object
True
>>> (Y**2)[10,10] # So this is evaluated lazily
342923500 

注意事項

該類提供了一種用最稀疏方式表示序列形式的極度密集矩陣的替代方法。

class sympy.matrices.expressions.PermutationMatrix(perm)

一個置換矩陣

引數:

perm:置換

矩陣使用的置換。

置換確定矩陣大小的大小。

參閱sympy.combinatorics.permutations.Permutation文件,瞭解如何建立置換物件的詳細資訊。

示例

>>> from sympy import Matrix, PermutationMatrix
>>> from sympy.combinatorics import Permutation 

建立置換矩陣:

>>> p = Permutation(1, 2, 0)
>>> P = PermutationMatrix(p)
>>> P = P.as_explicit()
>>> P
Matrix([
[0, 1, 0],
[0, 0, 1],
[1, 0, 0]]) 

置換矩陣的行和列:

>>> M = Matrix([0, 1, 2])
>>> Matrix(P*M)
Matrix([
[1],
[2],
[0]]) 
>>> Matrix(M.T*P)
Matrix([[2, 0, 1]]) 

另請參閱

sympy.combinatorics.permutations.Permutation

class sympy.matrices.expressions.MatrixPermute(mat, perm, axis=0)

用於置換矩陣行或列的符號表示。

引數:

perm:置換,置換矩陣

用於置換矩陣的置換。置換可以調整為合適的大小,

axis:0 或 1

要與之一起置換的軸。如果為(0),它將置換矩陣行。如果為(1),它將置換矩陣列。

注意事項

這遵循與sympy.matrices.matrixbase.MatrixBase.permute()中使用的相同符號。

示例

>>> from sympy import Matrix, MatrixPermute
>>> from sympy.combinatorics import Permutation 

置換矩陣的行:

>>> p = Permutation(1, 2, 0)
>>> A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> B = MatrixPermute(A, p, axis=0)
>>> B.as_explicit()
Matrix([
[4, 5, 6],
[7, 8, 9],
[1, 2, 3]]) 

置換矩陣的列:

>>> B = MatrixPermute(A, p, axis=1)
>>> B.as_explicit()
Matrix([
[2, 3, 1],
[5, 6, 4],
[8, 9, 7]]) 

另請參閱

sympy.matrices.matrixbase.MatrixBase.permute

class sympy.matrices.expressions.Identity(n)

矩陣單位矩陣 I - 乘法單位元素

示例

>>> from sympy import Identity, MatrixSymbol
>>> A = MatrixSymbol('A', 3, 5)
>>> I = Identity(3)
>>> I*A
A 
class sympy.matrices.expressions.ZeroMatrix(m, n)

矩陣零 0 - 加法單位元素

示例

>>> from sympy import MatrixSymbol, ZeroMatrix
>>> A = MatrixSymbol('A', 3, 5)
>>> Z = ZeroMatrix(3, 5)
>>> A + Z
A
>>> Z*A.T
0 
class sympy.matrices.expressions.CompanionMatrix(poly)

多項式的符號伴隨矩陣。

示例

>>> from sympy import Poly, Symbol, symbols
>>> from sympy.matrices.expressions import CompanionMatrix
>>> x = Symbol('x')
>>> c0, c1, c2, c3, c4 = symbols('c0:5')
>>> p = Poly(c0 + c1*x + c2*x**2 + c3*x**3 + c4*x**4 + x**5, x)
>>> CompanionMatrix(p)
CompanionMatrix(Poly(x**5 + c4*x**4 + c3*x**3 + c2*x**2 + c1*x + c0,
x, domain='ZZ[c0,c1,c2,c3,c4]')) 
class sympy.matrices.expressions.MatrixSet(n, m, set)

MatrixSet 表示形狀為(n, m)的矩陣集合。

示例

>>> from sympy.matrices import MatrixSet
>>> from sympy import S, I, Matrix
>>> M = MatrixSet(2, 2, set=S.Reals)
>>> X = Matrix([[1, 2], [3, 4]])
>>> X in M
True
>>> X = Matrix([[1, 2], [I, 4]])
>>> X in M
False 

塊矩陣

塊矩陣允許您使用較小的子塊構建較大的矩陣。它們可以與MatrixExprImmutableMatrix物件一起使用。

class sympy.matrices.expressions.blockmatrix.BlockMatrix(*args, **kwargs)

塊矩陣是由其他矩陣組成的矩陣。

子矩陣儲存在 SymPy 矩陣物件中,但作為矩陣表示式的一部分訪問。

>>> from sympy import (MatrixSymbol, BlockMatrix, symbols,
...     Identity, ZeroMatrix, block_collapse)
>>> n,m,l = symbols('n m l')
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m, m)
>>> Z = MatrixSymbol('Z', n, m)
>>> B = BlockMatrix([[X, Z], [ZeroMatrix(m,n), Y]])
>>> print(B)
Matrix([
[X, Z],
[0, Y]]) 
>>> C = BlockMatrix([[Identity(n), Z]])
>>> print(C)
Matrix([[I, Z]]) 
>>> print(block_collapse(C*B))
Matrix([[X, Z + Z*Y]]) 

一些矩陣可能由塊的行組成,每行中的矩陣具有相同的高度,並且所有行具有相同的總列數,但在每行中的每個矩陣中不具有相同數量的列。在這種情況下,矩陣不是塊矩陣,並且應透過 Matrix 進行例項化。

>>> from sympy import ones, Matrix
>>> dat = [
... [ones(3,2), ones(3,3)*2],
... [ones(2,3)*3, ones(2,2)*4]]
...
>>> BlockMatrix(dat)
Traceback (most recent call last):
...
ValueError:
Although this matrix is comprised of blocks, the blocks do not fill
the matrix in a size-symmetric fashion. To create a full matrix from
these arguments, pass them directly to Matrix.
>>> Matrix(dat)
Matrix([
[1, 1, 2, 2, 2],
[1, 1, 2, 2, 2],
[1, 1, 2, 2, 2],
[3, 3, 3, 4, 4],
[3, 3, 3, 4, 4]]) 

另請參閱

sympy.matrices.matrixbase.MatrixBase.irregular

LDUdecomposition()

返回一個 2x2 塊矩陣的塊 LDU 分解。

返回:

(L, D, U):矩陣

L:下三角矩陣 D:對角矩陣 U:上三角矩陣

引發:

ShapeError

如果塊矩陣不是 2x2 矩陣

NonInvertibleMatrixError

如果矩陣“A”是不可逆的

示例

>>> from sympy import symbols, MatrixSymbol, BlockMatrix, block_collapse
>>> m, n = symbols('m n')
>>> A = MatrixSymbol('A', n, n)
>>> B = MatrixSymbol('B', n, m)
>>> C = MatrixSymbol('C', m, n)
>>> D = MatrixSymbol('D', m, m)
>>> X = BlockMatrix([[A, B], [C, D]])
>>> L, D, U = X.LDUdecomposition()
>>> block_collapse(L*D*U)
Matrix([
[A, B],
[C, D]]) 

另請參閱

sympy.matrices.expressions.blockmatrix.BlockMatrix.UDLdecomposition, sympy.matrices.expressions.blockmatrix.BlockMatrix.LUdecomposition

LUdecomposition()

返回 2x2 塊矩陣的塊 LU 分解

返回:

(L, U):矩陣

L:下對角矩陣 U:上對角矩陣

丟擲:

ShapeError

如果塊矩陣不是 2x2 矩陣

NonInvertibleMatrixError

如果矩陣“A”是非可逆的

示例

>>> from sympy import symbols, MatrixSymbol, BlockMatrix, block_collapse
>>> m, n = symbols('m n')
>>> A = MatrixSymbol('A', n, n)
>>> B = MatrixSymbol('B', n, m)
>>> C = MatrixSymbol('C', m, n)
>>> D = MatrixSymbol('D', m, m)
>>> X = BlockMatrix([[A, B], [C, D]])
>>> L, U = X.LUdecomposition()
>>> block_collapse(L*U)
Matrix([
[A, B],
[C, D]]) 

參見

sympy.matrices.expressions.blockmatrix.BlockMatrix.UDLdecomposition, sympy.matrices.expressions.blockmatrix.BlockMatrix.LDUdecomposition

UDLdecomposition()

返回 2x2 塊矩陣的塊 UDL 分解

返回:

(U, D, L):矩陣

U:上對角矩陣 D:對角矩陣 L:下對角矩陣

丟擲:

ShapeError

如果塊矩陣不是 2x2 矩陣

NonInvertibleMatrixError

如果矩陣“D”是非可逆的

示例

>>> from sympy import symbols, MatrixSymbol, BlockMatrix, block_collapse
>>> m, n = symbols('m n')
>>> A = MatrixSymbol('A', n, n)
>>> B = MatrixSymbol('B', n, m)
>>> C = MatrixSymbol('C', m, n)
>>> D = MatrixSymbol('D', m, m)
>>> X = BlockMatrix([[A, B], [C, D]])
>>> U, D, L = X.UDLdecomposition()
>>> block_collapse(U*D*L)
Matrix([
[A, B],
[C, D]]) 

參見

sympy.matrices.expressions.blockmatrix.BlockMatrix.LDUdecomposition, sympy.matrices.expressions.blockmatrix.BlockMatrix.LUdecomposition

schur(mat='A', generalized=False)

返回 2x2 塊矩陣的舒爾補

引數:

mat:字串,可選

用於計算舒爾補的矩陣。“預設情況下使用“A”

generalized:布林值,可選

如果為 True,則返回使用摩爾-彭羅斯逆的廣義舒爾補

返回:

M:矩陣

舒爾補矩陣

丟擲:

ShapeError

如果塊矩陣不是 2x2 矩陣

NonInvertibleMatrixError

如果給定的矩陣是非可逆的

示例

>>> from sympy import symbols, MatrixSymbol, BlockMatrix
>>> m, n = symbols('m n')
>>> A = MatrixSymbol('A', n, n)
>>> B = MatrixSymbol('B', n, m)
>>> C = MatrixSymbol('C', m, n)
>>> D = MatrixSymbol('D', m, m)
>>> X = BlockMatrix([[A, B], [C, D]]) 

預設的舒爾補是使用“A”進行評估的

>>> X.schur()
-C*A**(-1)*B + D
>>> X.schur('D')
A - B*D**(-1)*C 

非可逆矩陣的舒爾補沒有定義。相反,可以計算使用摩爾-彭羅斯逆的廣義舒爾補。為此,必須將 generalized 設定為 True

>>> X.schur('B', generalized=True)
C - D*(B.T*B)**(-1)*B.T*A
>>> X.schur('C', generalized=True)
-A*(C.T*C)**(-1)*C.T*D + B 

參見

sympy.matrices.matrixbase.MatrixBase.pinv

參考文獻

[R608]

維基百科關於舒爾補的文章

transpose()

返回矩陣的轉置。

示例

>>> from sympy import MatrixSymbol, BlockMatrix, ZeroMatrix
>>> from sympy.abc import m, n
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m, m)
>>> Z = MatrixSymbol('Z', n, m)
>>> B = BlockMatrix([[X, Z], [ZeroMatrix(m,n), Y]])
>>> B.transpose()
Matrix([
[X.T,  0],
[Z.T, Y.T]])
>>> _.transpose()
Matrix([
[X, Z],
[0, Y]]) 
class sympy.matrices.expressions.blockmatrix.BlockDiagMatrix(*mats)

一個帶有塊矩陣的稀疏矩陣

示例

>>> from sympy import MatrixSymbol, BlockDiagMatrix, symbols
>>> n, m, l = symbols('n m l')
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m, m)
>>> BlockDiagMatrix(X, Y)
Matrix([
[X, 0],
[0, Y]]) 

注意事項

如果您想獲取單獨的對角塊,請使用 get_diag_blocks()

參見

sympy.matrices.dense.diag

get_diag_blocks()

返回矩陣的對角塊列表。

示例

>>> from sympy import BlockDiagMatrix, Matrix 
>>> A = Matrix([[1, 2], [3, 4]])
>>> B = Matrix([[5, 6], [7, 8]])
>>> M = BlockDiagMatrix(A, B) 

如何從塊對角矩陣獲取對角塊:

>>> diag_blocks = M.get_diag_blocks()
>>> diag_blocks[0]
Matrix([
[1, 2],
[3, 4]])
>>> diag_blocks[1]
Matrix([
[5, 6],
[7, 8]]) 
sympy.matrices.expressions.blockmatrix.block_collapse(expr)

評估塊矩陣表示式

>>> from sympy import MatrixSymbol, BlockMatrix, symbols, Identity, ZeroMatrix, block_collapse
>>> n,m,l = symbols('n m l')
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m, m)
>>> Z = MatrixSymbol('Z', n, m)
>>> B = BlockMatrix([[X, Z], [ZeroMatrix(m, n), Y]])
>>> print(B)
Matrix([
[X, Z],
[0, Y]]) 
>>> C = BlockMatrix([[Identity(n), Z]])
>>> print(C)
Matrix([[I, Z]]) 
>>> print(block_collapse(C*B))
Matrix([[X, Z + Z*Y]]) 

矩陣正則形式

原文連結:docs.sympy.org/latest/modules/matrices/normalforms.html

sympy.matrices.normalforms.smith_normal_form(m, domain=None)

返回矩陣 (m) 在環 (domain) 上的 Smith 正則形式。這隻適用於環是主理想域的情況。

示例

>>> from sympy import Matrix, ZZ
>>> from sympy.matrices.normalforms import smith_normal_form
>>> m = Matrix([[12, 6, 4], [3, 9, 6], [2, 16, 14]])
>>> print(smith_normal_form(m, domain=ZZ))
Matrix([[1, 0, 0], [0, 10, 0], [0, 0, -30]]) 
sympy.matrices.normalforms.hermite_normal_form(A, *, D=None, check_rank=False)

計算整數矩陣 A 的 Hermite 正則形式。

引數:

A : (m \times n) 整數 Matrix

D : int, 可選

假設 (W) 是 A 的 HNF。如果事先已知,可提供正整數 D,它是 (\det(W)) 的任意倍數。在這種情況下,如果 A 的秩也是 (m),那麼我們可以使用另一種演算法,該演算法在 mod D 下工作,以防止係數膨脹。

check_rank : 布林值, 可選 (預設為 False)

基本假設是,如果您傳遞了 D 的值,則已相信 A 的秩是 (m),因此我們不會浪費時間為您檢查它。如果您希望進行檢查(並且如果檢查失敗,則使用普通的非模 D 演算法),則將 check_rank 設定為 True

返回:

Matrix

矩陣 A 的 Hermite 正則形式。

引發:

DMDomainError

如果矩陣的域不是 ZZ。

DMShapeError

如果使用 mod D 演算法但矩陣的行數多於列數。

示例

>>> from sympy import Matrix
>>> from sympy.matrices.normalforms import hermite_normal_form
>>> m = Matrix([[12, 6, 4], [3, 9, 6], [2, 16, 14]])
>>> print(hermite_normal_form(m))
Matrix([[10, 0, 2], [0, 15, 3], [0, 0, 2]]) 

參考文獻

[R647]

Cohen, H. 計算代數數論課程. (見演算法 2.4.5 和 2.4.8。)

張量

原文連結:docs.sympy.org/latest/modules/tensor/index.html

一個用於處理包括張量在內的帶有指數的符號物件的模組。

內容

  • N 維陣列

  • N 維陣列表示式

  • 索引物件

  • 方法

  • 張量

  • 張量運算子

N 維陣列

原文連結:docs.sympy.org/latest/modules/tensor/array.html

SymPy 的 N 維陣列模組。

提供了四個類來處理 N 維陣列,根據稠密/稀疏(即是否將所有元素或僅非零元素儲存在記憶體中)和可變/不可變的組合(不可變類是 SymPy 物件,但在建立後不能更改)。

示例

以下示例展示了Array的使用。這是ImmutableDenseNDimArray的縮寫,即一個不可變的稠密 N 維陣列,其他類似。

可以檢測巢狀列表和元組的形狀來構造陣列

>>> from sympy import Array
>>> a1 = Array([[1, 2], [3, 4], [5, 6]])
>>> a1
[[1, 2], [3, 4], [5, 6]]
>>> a1.shape
(3, 2)
>>> a1.rank()
2
>>> from sympy.abc import x, y, z
>>> a2 = Array([[[x, y], [z, x*z]], [[1, x*y], [1/x, x/y]]])
>>> a2
[[[x, y], [z, x*z]], [[1, x*y], [1/x, x/y]]]
>>> a2.shape
(2, 2, 2)
>>> a2.rank()
3 

或者可以傳遞一個 1 維陣列,然後是一個形狀元組:

>>> m1 = Array(range(12), (3, 4))
>>> m1
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
>>> m2 = Array(range(12), (3, 2, 2))
>>> m2
[[[0, 1], [2, 3]], [[4, 5], [6, 7]], [[8, 9], [10, 11]]]
>>> m2[1,1,1]
7
>>> m2.reshape(4, 3)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]] 

切片支援:

>>> m2[:, 1, 1]
[3, 7, 11] 

按元素求導:

>>> from sympy.abc import x, y, z
>>> m3 = Array([x**3, x*y, z])
>>> m3.diff(x)
[3*x**2, y, 0]
>>> m3.diff(z)
[0, 0, 1] 

與其他 SymPy 表示式的乘法是按元素應用的:

>>> (1+x)*m3
[x**3*(x + 1), x*y*(x + 1), z*(x + 1)] 

若要對 N 維陣列的每個元素應用函式,請使用applyfunc

>>> m3.applyfunc(lambda x: x/2)
[x**3/2, x*y/2, z/2] 

N 維陣列可以透過tolist()方法轉換為巢狀列表:

>>> m2.tolist()
[[[0, 1], [2, 3]], [[4, 5], [6, 7]], [[8, 9], [10, 11]]]
>>> isinstance(m2.tolist(), list)
True 

如果秩為 2,可以用tomatrix()將它們轉換為矩陣:

>>> m1.tomatrix()
Matrix([
[0, 1,  2,  3],
[4, 5,  6,  7],
[8, 9, 10, 11]]) 

乘積和收縮

陣列(A_{i_1,\ldots,i_n})和(B_{j_1,\ldots,j_m})之間的張量積建立定義為組合陣列(P = A \otimes B)的張量積,定義為

(P_{i_1,\ldots,i_n,j_1,\ldots,j_m} := A_{i_1,\ldots,i_n}\cdot B_{j_1,\ldots,j_m}.)

可透過tensorproduct(...)獲得:

>>> from sympy import Array, tensorproduct
>>> from sympy.abc import x,y,z,t
>>> A = Array([x, y, z, t])
>>> B = Array([1, 2, 3, 4])
>>> tensorproduct(A, B)
[[x, 2*x, 3*x, 4*x], [y, 2*y, 3*y, 4*y], [z, 2*z, 3*z, 4*z], [t, 2*t, 3*t, 4*t]] 

如果不想立即計算張量積,可以使用ArrayTensorProduct,它建立一個未評估的張量積表示式:

>>> from sympy.tensor.array.expressions import ArrayTensorProduct
>>> ArrayTensorProduct(A, B)
ArrayTensorProduct([x, y, z, t], [1, 2, 3, 4]) 

ArrayTensorProduct上呼叫.as_explicit()相當於直接呼叫tensorproduct(...)

>>> ArrayTensorProduct(A, B).as_explicit()
[[x, 2*x, 3*x, 4*x], [y, 2*y, 3*y, 4*y], [z, 2*z, 3*z, 4*z], [t, 2*t, 3*t, 4*t]] 

秩為 1 的陣列與矩陣的張量積建立一個秩為 3 的陣列:

>>> from sympy import eye
>>> p1 = tensorproduct(A, eye(4))
>>> p1
[[[x, 0, 0, 0], [0, x, 0, 0], [0, 0, x, 0], [0, 0, 0, x]], [[y, 0, 0, 0], [0, y, 0, 0], [0, 0, y, 0], [0, 0, 0, y]], [[z, 0, 0, 0], [0, z, 0, 0], [0, 0, z, 0], [0, 0, 0, z]], [[t, 0, 0, 0], [0, t, 0, 0], [0, 0, t, 0], [0, 0, 0, t]]] 

現在,要獲取(A_0 \otimes \mathbf{1}),可以透過切片訪問(p_{0,m,n}):

>>> p1[0,:,:]
[[x, 0, 0, 0], [0, x, 0, 0], [0, 0, x, 0], [0, 0, 0, x]] 

張量收縮對指定的軸求和,例如收縮位置(a)和(b)意味著

(A_{i_1,\ldots,i_a,\ldots,i_b,\ldots,i_n} \implies \sum_k A_{i_1,\ldots,k,\ldots,k,\ldots,i_n})

請記住,Python 索引從零開始,因此要收縮第 a 和第 b 個軸,需要指定(a-1)和(b-1)

>>> from sympy import tensorcontraction
>>> C = Array([[x, y], [z, t]]) 

矩陣的跡等價於一個秩為 2 的陣列的收縮:

(A_{m,n} \implies \sum_k A_{k,k})

>>> tensorcontraction(C, (0, 1))
t + x 

要建立一個表示不立即評估的張量收縮的表示式,請使用ArrayContraction,如果跟隨.as_explicit(),則等效於tensorcontraction(...)

>>> from sympy.tensor.array.expressions import ArrayContraction
>>> ArrayContraction(C, (0, 1))
ArrayContraction([[x, y], [z, t]], (0, 1))
>>> ArrayContraction(C, (0, 1)).as_explicit()
t + x 

矩陣乘積等價於兩個秩為 2 的陣列的張量積,然後收縮第 2 和第 3 個軸(在 Python 中索引軸號為 1、2)。

(A_{m,n}\cdot B_{i,j} \implies \sum_k A_{m, k}\cdot B_{k, j})

>>> D = Array([[2, 1], [0, -1]])
>>> tensorcontraction(tensorproduct(C, D), (1, 2))
[[2*x, x - y], [2*z, -t + z]] 

可以驗證矩陣乘積是等價的:

>>> from sympy import Matrix
>>> Matrix([[x, y], [z, t]])*Matrix([[2, 1], [0, -1]])
Matrix([
[2*x,  x - y],
[2*z, -t + z]]) 

或者等價地

>>> C.tomatrix()*D.tomatrix()
Matrix([
[2*x,  x - y],
[2*z, -t + z]]) 

對角線運算子

tensordiagonal 函式的行為方式與 tensorcontraction 類似,但連線的索引不進行求和,例如對位置 (a) 和 (b) 進行對角化意味著

(A_{i_1,\ldots,i_a,\ldots,i_b,\ldots,i_n} \implies A_{i_1,\ldots,k,\ldots,k,\ldots,i_n} \implies \tilde{A}{i_1,\ldots,i,i_{a+1},\ldots,i_{b-1},i_{b+1},\ldots,i_n,k})

其中 (\tilde{A}) 是在位置 (a) 和 (b) 移動到最後索引位置的 (A) 的對角化陣列等價物。

比較收縮和對角運算子之間的差異:

>>> from sympy import tensordiagonal
>>> from sympy.abc import a, b, c, d
>>> m = Matrix([[a, b], [c, d]])
>>> tensorcontraction(m, [0, 1])
a + d
>>> tensordiagonal(m, [0, 1])
[a, d] 

簡而言之,tensordiagonal 不會對加和進行求和。

透過陣列導數

常規的導數操作可以擴充套件到支援對陣列進行導數,前提是該陣列中的所有元素都是符號或適合導數計算的表示式。

由陣列定義的導數如下:給定陣列 (A_{i_1, \ldots, i_N}) 和陣列 (X_{j_1, \ldots, j_M}),陣列的導數將返回由新陣列 (B) 定義的新陣列

(B_{j_1,\ldots,j_M,i_1,\ldots,i_N} := \frac{\partial A_{i_1,\ldots,i_N}}{\partial X_{j_1,\ldots,j_M}})

函式 derive_by_array 執行這樣的操作:

>>> from sympy import derive_by_array
>>> from sympy.abc import x, y, z, t
>>> from sympy import sin, exp 

對標量而言,其行為與普通導數完全相同:

>>> derive_by_array(sin(x*y), x)
y*cos(x*y) 

標量由陣列基礎推導:

>>> derive_by_array(sin(x*y), [x, y, z])
[y*cos(x*y), x*cos(x*y), 0] 

透過陣列基礎進行的導數:(B^{nm} := \frac{\partial A^m}{\partial x^n})

>>> basis = [x, y, z]
>>> ax = derive_by_array([exp(x), sin(y*z), t], basis)
>>> ax
[[exp(x), 0, 0], [0, z*cos(y*z), 0], [0, y*cos(y*z), 0]] 

收縮結果陣列:(\sum_m \frac{\partial A^m}{\partial x^m})

>>> tensorcontraction(ax, (0, 1))
z*cos(y*z) + exp(x) 

類:

class sympy.tensor.array.ImmutableDenseNDimArray(iterable, shape=None, **kwargs)
class sympy.tensor.array.ImmutableSparseNDimArray(iterable=None, shape=None, **kwargs)
class sympy.tensor.array.MutableDenseNDimArray(iterable=None, shape=None, **kwargs)
class sympy.tensor.array.MutableSparseNDimArray(iterable=None, shape=None, **kwargs)

函式:

sympy.tensor.array.derive_by_array(expr, dx)

由陣列導數。支援陣列和標量。

陣列表示式的等價運算子是 array_derive

解釋

給定陣列 (A_{i_1, \ldots, i_N}) 和陣列 (X_{j_1, \ldots, j_M}),此函式將返回由新陣列 (B) 定義的新陣列

(B_{j_1,\ldots,j_M,i_1,\ldots,i_N} := \frac{\partial A_{i_1,\ldots,i_N}}{\partial X_{j_1,\ldots,j_M}})

示例:

>>> from sympy import derive_by_array
>>> from sympy.abc import x, y, z, t
>>> from sympy import cos
>>> derive_by_array(cos(x*t), x)
-t*sin(t*x)
>>> derive_by_array(cos(x*t), [x, y, z, t])
[-t*sin(t*x), 0, 0, -x*sin(t*x)]
>>> derive_by_array([x, y**2*z], [[x, y], [z, t]])
[[[1, 0], [0, 2*y*z]], [[0, y**2], [0, 0]]] 
sympy.tensor.array.permutedims(expr, perm=None, index_order_old=None, index_order_new=None)

對陣列的索引進行排列。

引數指定索引的排列。

陣列表示式的等價運算子是 PermuteDims,可用於保持表示式不被求值。

示例:

>>> from sympy.abc import x, y, z, t
>>> from sympy import sin
>>> from sympy import Array, permutedims
>>> a = Array([[x, y, z], [t, sin(x), 0]])
>>> a
[[x, y, z], [t, sin(x), 0]]
>>> permutedims(a, (1, 0))
[[x, t], [y, sin(x)], [z, 0]] 

如果陣列是二階的,可以使用 transpose

>>> from sympy import transpose
>>> transpose(a)
[[x, t], [y, sin(x)], [z, 0]] 

高維度的示例:

>>> b = Array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
>>> permutedims(b, (2, 1, 0))
[[[1, 5], [3, 7]], [[2, 6], [4, 8]]]
>>> permutedims(b, (1, 2, 0))
[[[1, 5], [2, 6]], [[3, 7], [4, 8]]] 

指定與前幾行相同排列的另一種方法是將索引作為列表或字串傳遞:

>>> permutedims(b, index_order_old="cba", index_order_new="abc")
[[[1, 5], [3, 7]], [[2, 6], [4, 8]]]
>>> permutedims(b, index_order_old="cab", index_order_new="abc")
[[[1, 5], [2, 6]], [[3, 7], [4, 8]]] 

Permutation 物件也是允許的:

>>> from sympy.combinatorics import Permutation
>>> permutedims(b, Permutation([1, 2, 0]))
[[[1, 5], [2, 6]], [[3, 7], [4, 8]]] 

另請參閱:

sympy.tensor.array.expressions.array_expressions.PermuteDims

sympy.tensor.array.tensorcontraction(array, *contraction_axes)

在指定軸上收縮類似陣列物件。

陣列表示式的等價運算子是 ArrayContraction,可用於保持表示式不被求值。

示例:

>>> from sympy import Array, tensorcontraction
>>> from sympy import Matrix, eye
>>> tensorcontraction(eye(3), (0, 1))
3
>>> A = Array(range(18), (3, 2, 3))
>>> A
[[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]], [[12, 13, 14], [15, 16, 17]]]
>>> tensorcontraction(A, (0, 2))
[21, 30] 

可以透過適當的 tensorcontractiontensorproduct 組合來模擬矩陣乘法

>>> from sympy import tensorproduct
>>> from sympy.abc import a,b,c,d,e,f,g,h
>>> m1 = Matrix([[a, b], [c, d]])
>>> m2 = Matrix([[e, f], [g, h]])
>>> p = tensorproduct(m1, m2)
>>> p
[[[[a*e, a*f], [a*g, a*h]], [[b*e, b*f], [b*g, b*h]]], [[[c*e, c*f], [c*g, c*h]], [[d*e, d*f], [d*g, d*h]]]]
>>> tensorcontraction(p, (1, 2))
[[a*e + b*g, a*f + b*h], [c*e + d*g, c*f + d*h]]
>>> m1*m2
Matrix([
[a*e + b*g, a*f + b*h],
[c*e + d*g, c*f + d*h]]) 

另請參閱:

sympy.tensor.array.expressions.array_expressions.ArrayContraction

sympy.tensor.array.tensorproduct(*args)

標量或類陣列物件之間的張量積。

陣列表示式的等效運算子是ArrayTensorProduct,可以用來保持表示式不求值。

示例

>>> from sympy.tensor.array import tensorproduct, Array
>>> from sympy.abc import x, y, z, t
>>> A = Array([[1, 2], [3, 4]])
>>> B = Array([x, y])
>>> tensorproduct(A, B)
[[[x, y], [2*x, 2*y]], [[3*x, 3*y], [4*x, 4*y]]]
>>> tensorproduct(A, x)
[[x, 2*x], [3*x, 4*x]]
>>> tensorproduct(A, B, B)
[[[[x**2, x*y], [x*y, y**2]], [[2*x**2, 2*x*y], [2*x*y, 2*y**2]]], [[[3*x**2, 3*x*y], [3*x*y, 3*y**2]], [[4*x**2, 4*x*y], [4*x*y, 4*y**2]]]] 

在兩個矩陣上應用此函式將導致一個秩為 4 的陣列。

>>> from sympy import Matrix, eye
>>> m = Matrix([[x, y], [z, t]])
>>> p = tensorproduct(eye(3), m)
>>> p
[[[[x, y], [z, t]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[0, 0], [0, 0]], [[x, y], [z, t]], [[0, 0], [0, 0]]], [[[0, 0], [0, 0]], [[0, 0], [0, 0]], [[x, y], [z, t]]]] 

參見

sympy.tensor.array.expressions.array_expressions.ArrayTensorProduct

sympy.tensor.array.tensordiagonal(array, *diagonal_axes)

對指定軸上的類陣列物件進行對角化。

這相當於將表示式乘以克羅內克三角形單位化的軸。

對角線索引被放在軸的末尾。

陣列表示式的等效運算子是ArrayDiagonal,可以用來保持表示式不求值。

示例

tensordiagonal對二維陣列的軸 0 和 1 的作用等效於矩陣的對角線:

>>> from sympy import Array, tensordiagonal
>>> from sympy import Matrix, eye
>>> tensordiagonal(eye(3), (0, 1))
[1, 1, 1] 
>>> from sympy.abc import a,b,c,d
>>> m1 = Matrix([[a, b], [c, d]])
>>> tensordiagonal(m1, [0, 1])
[a, d] 

對於高維陣列,被對角化的維度將被追加移除,並作為最後的單一維度追加:

>>> A = Array(range(18), (3, 2, 3))
>>> A
[[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]], [[12, 13, 14], [15, 16, 17]]]
>>> tensordiagonal(A, (0, 2))
[[0, 7, 14], [3, 10, 17]]
>>> from sympy import permutedims
>>> tensordiagonal(A, (0, 2)) == permutedims(Array([A[0, :, 0], A[1, :, 1], A[2, :, 2]]), [1, 0])
True 

參見

sympy.tensor.array.expressions.array_expressions.ArrayDiagonal

N 維陣列表示式

原文連結:docs.sympy.org/latest/modules/tensor/array_expressions.html

陣列表示式是表示 N 維陣列的表示式,而不對它們進行評估。這些表示式以某種方式表示對 N 維陣列的操作的抽象語法樹。

每個 N 維陣列運算子都有對應的陣列表示式物件。

對應表:

Array operator Array expression operator
tensorproduct ArrayTensorProduct
tensorcontraction ArrayContraction
tensordiagonal ArrayDiagonal
permutedims PermuteDims

示例

ArraySymbol 物件是矩陣模組中 MatrixSymbol 物件的 N 維等效物。

>>> from sympy.tensor.array.expressions import ArraySymbol
>>> from sympy.abc import i, j, k
>>> A = ArraySymbol("A", (3, 2, 4))
>>> A.shape
(3, 2, 4)
>>> A[i, j, k]
A[i, j, k]
>>> A.as_explicit()
[[[A[0, 0, 0], A[0, 0, 1], A[0, 0, 2], A[0, 0, 3]],
 [A[0, 1, 0], A[0, 1, 1], A[0, 1, 2], A[0, 1, 3]]],
 [[A[1, 0, 0], A[1, 0, 1], A[1, 0, 2], A[1, 0, 3]],
 [A[1, 1, 0], A[1, 1, 1], A[1, 1, 2], A[1, 1, 3]]],
 [[A[2, 0, 0], A[2, 0, 1], A[2, 0, 2], A[2, 0, 3]],
 [A[2, 1, 0], A[2, 1, 1], A[2, 1, 2], A[2, 1, 3]]]] 

在陣列表示式中可以新增元件明確的陣列:

>>> from sympy import Array
>>> from sympy import tensorproduct
>>> from sympy.tensor.array.expressions import ArrayTensorProduct
>>> a = Array([1, 2, 3])
>>> b = Array([i, j, k])
>>> expr = ArrayTensorProduct(a, b, b)
>>> expr
ArrayTensorProduct([1, 2, 3], [i, j, k], [i, j, k])
>>> expr.as_explicit() == tensorproduct(a, b, b)
True 

從索引明確形式構建陣列表示式

陣列表示式是索引隱式的。這意味著它們不使用任何索引來表示陣列操作。函式 convert_indexed_to_array( ... ) 可以用來將索引明確的表示式轉換為陣列表示式。它接受兩個引數作為輸入:索引明確表示式和索引的順序:

>>> from sympy.tensor.array.expressions import convert_indexed_to_array
>>> from sympy import Sum
>>> A = ArraySymbol("A", (3, 3))
>>> B = ArraySymbol("B", (3, 3))
>>> convert_indexed_to_array(A[i, j], [i, j])
A
>>> convert_indexed_to_array(A[i, j], [j, i])
PermuteDims(A, (0 1))
>>> convert_indexed_to_array(A[i, j] + B[j, i], [i, j])
ArrayAdd(A, PermuteDims(B, (0 1)))
>>> convert_indexed_to_array(Sum(A[i, j]*B[j, k], (j, 0, 2)), [i, k])
ArrayContraction(ArrayTensorProduct(A, B), (1, 2)) 

矩陣的陣列表示式形式的對角線:

>>> convert_indexed_to_array(A[i, i], [i])
ArrayDiagonal(A, (0, 1)) 

矩陣的陣列表示式形式的跡:

>>> convert_indexed_to_array(Sum(A[i, i], (i, 0, 2)), [i])
ArrayContraction(A, (0, 1)) 

與矩陣的相容性

陣列表示式可以與矩陣模組中的物件混合使用:

>>> from sympy import MatrixSymbol
>>> from sympy.tensor.array.expressions import ArrayContraction
>>> M = MatrixSymbol("M", 3, 3)
>>> N = MatrixSymbol("N", 3, 3) 

在陣列表示式形式中表示矩陣乘積:

>>> from sympy.tensor.array.expressions import convert_matrix_to_array
>>> expr = convert_matrix_to_array(M*N)
>>> expr
ArrayContraction(ArrayTensorProduct(M, N), (1, 2)) 

可以將表示式轉換回矩陣形式:

>>> from sympy.tensor.array.expressions import convert_array_to_matrix
>>> convert_array_to_matrix(expr)
M*N 

在剩餘的軸上新增第二次收縮以獲得 (M \cdot N) 的跡:

>>> expr_tr = ArrayContraction(expr, (0, 1))
>>> expr_tr
ArrayContraction(ArrayContraction(ArrayTensorProduct(M, N), (1, 2)), (0, 1)) 

透過呼叫 .doit() 展開表示式並移除巢狀的陣列收縮操作:

>>> expr_tr.doit()
ArrayContraction(ArrayTensorProduct(M, N), (0, 3), (1, 2)) 

獲取陣列表示式的顯式形式:

>>> expr.as_explicit()
[[M[0, 0]*N[0, 0] + M[0, 1]*N[1, 0] + M[0, 2]*N[2, 0], M[0, 0]*N[0, 1] + M[0, 1]*N[1, 1] + M[0, 2]*N[2, 1], M[0, 0]*N[0, 2] + M[0, 1]*N[1, 2] + M[0, 2]*N[2, 2]],
 [M[1, 0]*N[0, 0] + M[1, 1]*N[1, 0] + M[1, 2]*N[2, 0], M[1, 0]*N[0, 1] + M[1, 1]*N[1, 1] + M[1, 2]*N[2, 1], M[1, 0]*N[0, 2] + M[1, 1]*N[1, 2] + M[1, 2]*N[2, 2]],
 [M[2, 0]*N[0, 0] + M[2, 1]*N[1, 0] + M[2, 2]*N[2, 0], M[2, 0]*N[0, 1] + M[2, 1]*N[1, 1] + M[2, 2]*N[2, 1], M[2, 0]*N[0, 2] + M[2, 1]*N[1, 2] + M[2, 2]*N[2, 2]]] 

在陣列表示式形式中表示矩陣的跡:

>>> from sympy import Trace
>>> convert_matrix_to_array(Trace(M))
ArrayContraction(M, (0, 1))
>>> convert_matrix_to_array(Trace(M*N))
ArrayContraction(ArrayTensorProduct(M, N), (0, 3), (1, 2)) 

表示矩陣的轉置(將表達為軸的排列):

>>> convert_matrix_to_array(M.T)
PermuteDims(M, (0 1)) 

計算導數陣列表示式:

>>> from sympy.tensor.array.expressions import array_derive
>>> d = array_derive(M, M)
>>> d
PermuteDims(ArrayTensorProduct(I, I), (3)(1 2)) 

驗證導數是否與使用明確矩陣計算的形式相對應:

>>> d.as_explicit()
[[[[1, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 1, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 1], [0, 0, 0], [0, 0, 0]]], [[[0, 0, 0], [1, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 1, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 1], [0, 0, 0]]], [[[0, 0, 0], [0, 0, 0], [1, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 1, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 1]]]]
>>> Me = M.as_explicit()
>>> Me.diff(Me)
[[[[1, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 1, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 1], [0, 0, 0], [0, 0, 0]]], [[[0, 0, 0], [1, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 1, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 1], [0, 0, 0]]], [[[0, 0, 0], [0, 0, 0], [1, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 1, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 1]]]] 
class sympy.tensor.array.expressions.ArrayTensorProduct(*args, **kwargs)

用於表示陣列類物件的張量積的類。

class sympy.tensor.array.expressions.ArrayContraction(expr, *contraction_indices, **kwargs)

這個類用來表示陣列在程式碼印表機易於處理的形式中的收縮。

class sympy.tensor.array.expressions.ArrayDiagonal(expr, *diagonal_indices, **kwargs)

用於表示對角線運算子的類。

解釋

在二維陣列中返回對角線,這看起來像是這樣的操作:

(A_{ij} \rightarrow A_{ii})

兩個二維陣列 (A \otimes B) 的張量積的軸 1 和 2(第二和第三)的對角線是

(\Big[ A_{ab} B_{cd} \Big]{abcd} \rightarrow \Big[ A B_{id} \Big]_{adi})

在這個最後的例子中,陣列表示式已從 4 維降至 3 維。請注意,沒有進行收縮,而是對對角線引入了新的索引 (i),收縮會將陣列降至 2 維。

注意,對角化的維度會新增為新的維度放在索引的末尾。

class sympy.tensor.array.expressions.PermuteDims(expr, permutation=None, index_order_old=None, index_order_new=None, **kwargs)

用於表示陣列軸的排列的類。

示例

>>> from sympy.tensor.array import permutedims
>>> from sympy import MatrixSymbol
>>> M = MatrixSymbol("M", 3, 3)
>>> cg = permutedims(M, [1, 0]) 

物件 cg 表示 M 的轉置,如排列 [1, 0] 將透過交換其索引作用於它:

(M_{ij} \Rightarrow M_{ji})

當轉換回矩陣形式時,這一點顯而易見:

>>> from sympy.tensor.array.expressions.from_array_to_matrix import convert_array_to_matrix
>>> convert_array_to_matrix(cg)
M.T 
>>> N = MatrixSymbol("N", 3, 2)
>>> cg = permutedims(N, [1, 0])
>>> cg.shape
(2, 3) 

有可選引數可作為排列的替代品使用:

>>> from sympy.tensor.array.expressions import ArraySymbol, PermuteDims
>>> M = ArraySymbol("M", (1, 2, 3, 4, 5))
>>> expr = PermuteDims(M, index_order_old="ijklm", index_order_new="kijml")
>>> expr
PermuteDims(M, (0 2 1)(3 4))
>>> expr.shape
(3, 1, 2, 5, 4) 

張量積的排列被簡化,以達到標準形式:

>>> from sympy.tensor.array import tensorproduct
>>> M = MatrixSymbol("M", 4, 5)
>>> tp = tensorproduct(M, N)
>>> tp.shape
(4, 5, 3, 2)
>>> perm1 = permutedims(tp, [2, 3, 1, 0]) 

引數 (M, N) 已經排序並簡化了排列,表示式等效:

>>> perm1.expr.args
(N, M)
>>> perm1.shape
(3, 2, 5, 4)
>>> perm1.permutation
(2 3) 

陣列形式的排列已從 [2, 3, 1, 0] 簡化為 [0, 1, 3, 2],因為張量積 (M) 和 (N) 的引數已經交換:

>>> perm1.permutation.array_form
[0, 1, 3, 2] 

我們可以巢狀第二個排列:

>>> perm2 = permutedims(perm1, [1, 0, 2, 3])
>>> perm2.shape
(2, 3, 5, 4)
>>> perm2.permutation.array_form
[1, 0, 3, 2] 

索引物件

原文連結:docs.sympy.org/latest/modules/tensor/indexed.html

定義索引物件的模組。

IndexedBaseIndexedIdx表示矩陣元素M[i, j]如下圖所示:

1) The Indexed class represents the entire indexed object.
           |
        ___|___
       '       '
        M[i, j]
       /   \__\______
       |             |
       |             |
       |     2) The Idx class represents indices; each Idx can
       |        optionally contain information about its range.
       |
 3) IndexedBase represents the 'stem' of an indexed object, here `M`.
    The stem used by itself is usually taken to represent the entire
    array. 

Indexed物件上可以有任意數量的索引。這些基礎物件中未實現任何轉換屬性,但支援重複索引的隱式收縮。

注意,對於複雜(即非原子)整數表示式作為索引的支援有限。(在未來版本中應進行改進。)

示例

要表示上述矩陣元素示例,您可以這樣寫:

>>> from sympy import symbols, IndexedBase, Idx
>>> M = IndexedBase('M')
>>> i, j = symbols('i j', cls=Idx)
>>> M[i, j]
M[i, j] 

乘積中的重複索引意味著求和,因此要使用Indexed物件來表示矩陣向量乘積:

>>> x = IndexedBase('x')
>>> M[i, j]*x[j]
M[i, j]*x[j] 

如果索引物件將轉換為基於元件的陣列,例如使用程式碼印表機或自動包裝框架,則還需要提供(符號或數值)維度。可以透過在構建IndexedBase時傳遞可選的形狀引數來完成:

>>> dim1, dim2 = symbols('dim1 dim2', integer=True)
>>> A = IndexedBase('A', shape=(dim1, 2*dim1, dim2))
>>> A.shape
(dim1, 2*dim1, dim2)
>>> A[i, j, 3].shape
(dim1, 2*dim1, dim2) 

如果IndexedBase物件沒有形狀資訊,則假定陣列大小與其索引的範圍一樣大:

>>> n, m = symbols('n m', integer=True)
>>> i = Idx('i', m)
>>> j = Idx('j', n)
>>> M[i, j].shape
(m, n)
>>> M[i, j].ranges
[(0, m - 1), (0, n - 1)] 

可與以下進行比較:

>>> A[i, 2, j].shape
(dim1, 2*dim1, dim2)
>>> A[i, 2, j].ranges
[(0, m - 1), None, (0, n - 1)] 

要分析索引表示式的結構,可以使用get_indices()get_contraction_structure()方法:

>>> from sympy.tensor import get_indices, get_contraction_structure
>>> get_indices(A[i, j, j])
({i}, {})
>>> get_contraction_structure(A[i, j, j])
{(j,): {A[i, j, j]}} 

檢視相應的文件字串以詳細瞭解輸出。

class sympy.tensor.indexed.Idx(label, range=None, **kw_args)

表示整數索引作為Integer或整數表示式。

有多種方法可以建立Idx物件。建構函式接受兩個引數:

label

整數或符號用於標記索引。

range

可選地可以將範圍指定為

  • Symbol或整數:被解釋為維度。下界和上界分別設定為0range - 1

  • tuple:兩個元素分別解釋為範圍的下限和上限。

注意:範圍的邊界假定為整數或無窮大(允許使用 oo 和-oo 指定無界範圍)。如果邊界給定為n,則n.is_integer不能返回 false。

為方便起見,如果標籤是字串,則自動轉換為整數符號。(注意:不會對範圍或維度引數進行此轉換。)

示例

>>> from sympy import Idx, symbols, oo
>>> n, i, L, U = symbols('n i L U', integer=True) 

如果標籤是字串,則建立一個整數Symbol,且邊界都是None

>>> idx = Idx('qwerty'); idx
qwerty
>>> idx.lower, idx.upper
(None, None) 

可以指定上界和下界:

>>> idx = Idx(i, (L, U)); idx
i
>>> idx.lower, idx.upper
(L, U) 

當只給出單個邊界時,它被解釋為維度,下界預設為 0:

>>> idx = Idx(i, n); idx.lower, idx.upper
(0, n - 1)
>>> idx = Idx(i, 4); idx.lower, idx.upper
(0, 3)
>>> idx = Idx(i, oo); idx.lower, idx.upper
(0, oo) 
property label

返回Idx物件的標籤(整數或整數表示式)。

示例

>>> from sympy import Idx, Symbol
>>> x = Symbol('x', integer=True)
>>> Idx(x).label
x
>>> j = Symbol('j', integer=True)
>>> Idx(j).label
j
>>> Idx(j + 1).label
j + 1 
property lower

返回Idx的下界。

示例

>>> from sympy import Idx
>>> Idx('j', 2).lower
0
>>> Idx('j', 5).lower
0
>>> Idx('j').lower is None
True 
property upper

返回Idx的上界。

示例

>>> from sympy import Idx
>>> Idx('j', 2).upper
1
>>> Idx('j', 5).upper
4
>>> Idx('j').upper is None
True 
class sympy.tensor.indexed.Indexed(base, *args, **kw_args)

表示具有索引的數學物件。

>>> from sympy import Indexed, IndexedBase, Idx, symbols
>>> i, j = symbols('i j', cls=Idx)
>>> Indexed('A', i, j)
A[i, j] 

建議透過索引IndexedBase建立Indexed物件:IndexedBase('A')[i, j]而不是Indexed(IndexedBase('A'), i, j)

>>> A = IndexedBase('A')
>>> a_ij = A[i, j]           # Prefer this,
>>> b_ij = Indexed(A, i, j)  # over this.
>>> a_ij == b_ij
True 
property base

返回Indexed物件的IndexedBase

示例

>>> from sympy import Indexed, IndexedBase, Idx, symbols
>>> i, j = symbols('i j', cls=Idx)
>>> Indexed('A', i, j).base
A
>>> B = IndexedBase('B')
>>> B == B[i, j].base
True 
property indices

返回 Indexed 物件的索引。

示例

>>> from sympy import Indexed, Idx, symbols
>>> i, j = symbols('i j', cls=Idx)
>>> Indexed('A', i, j).indices
(i, j) 
property ranges

返回帶有每個索引的下限和上限範圍的元組列表。

如果索引未定義資料成員的上限和下限,則列表中的相應位置包含None而不是元組。

示例

>>> from sympy import Indexed,Idx, symbols
>>> Indexed('A', Idx('i', 2), Idx('j', 4), Idx('k', 8)).ranges
[(0, 1), (0, 3), (0, 7)]
>>> Indexed('A', Idx('i', 3), Idx('j', 3), Idx('k', 3)).ranges
[(0, 2), (0, 2), (0, 2)]
>>> x, y, z = symbols('x y z', integer=True)
>>> Indexed('A', x, y, z).ranges
[None, None, None] 
property rank

返回 Indexed 物件的秩。

示例

>>> from sympy import Indexed, Idx, symbols
>>> i, j, k, l, m = symbols('i:m', cls=Idx)
>>> Indexed('A', i, j).rank
2
>>> q = Indexed('A', i, j, k, l, m)
>>> q.rank
5
>>> q.rank == len(q.indices)
True 
property shape

返回每個索引的維度列表。

維度是陣列的屬性,而不是索引的屬性。但是,如果 IndexedBase 未定義形狀屬性,則假定索引的範圍對應於陣列的形狀。

>>> from sympy import IndexedBase, Idx, symbols
>>> n, m = symbols('n m', integer=True)
>>> i = Idx('i', m)
>>> j = Idx('j', m)
>>> A = IndexedBase('A', shape=(n, n))
>>> B = IndexedBase('B')
>>> A[i, j].shape
(n, n)
>>> B[i, j].shape
(m, m) 
class sympy.tensor.indexed.IndexedBase(label, shape=None, *, offset=0, strides=None, **kw_args)

表示索引物件的基礎或干擾

IndexedBase 類表示一個包含元素的陣列。該類的主要目的是允許方便地建立 Indexed 類的物件。IndexedBase__getitem__方法返回 Indexed 的例項。單獨使用,即沒有索引,IndexedBase 類可以用作例如矩陣方程的標記,類似於使用 Symbol 類可以做的事情。但是,IndexedBase 類增加了 Symbol 例項不可用的功能:

  • IndexedBase 物件可以選擇性地儲存形狀資訊。這可用於檢查陣列的一致性和 numpy 廣播的條件。(TODO)
  • IndexedBase 物件實現了語法糖,允許使用重複索引的隱式求和來輕鬆表示陣列操作。
  • IndexedBase 物件象徵著一個數學結構,相當於陣列,因此被用於程式碼生成和自動編譯和包裝。
>>> from sympy.tensor import IndexedBase, Idx
>>> from sympy import symbols
>>> A = IndexedBase('A'); A
A
>>> type(A)
<class 'sympy.tensor.indexed.IndexedBase'> 

IndexedBase 物件接收到索引時,它返回一個帶有命名軸的陣列,由 Indexed 物件表示:

>>> i, j = symbols('i j', integer=True)
>>> A[i, j, 2]
A[i, j, 2]
>>> type(A[i, j, 2])
<class 'sympy.tensor.indexed.Indexed'> 

IndexedBase 建構函式接受一個可選的形狀引數。如果給定,則會覆蓋索引中的任何形狀資訊。(但不覆蓋索引範圍!)

>>> m, n, o, p = symbols('m n o p', integer=True)
>>> i = Idx('i', m)
>>> j = Idx('j', n)
>>> A[i, j].shape
(m, n)
>>> B = IndexedBase('B', shape=(o, p))
>>> B[i, j].shape
(o, p) 

假設可以與關鍵字引數一起指定,方式與 Symbol 相同:

>>> A_real = IndexedBase('A', real=True)
>>> A_real.is_real
True
>>> A != A_real
True 

假設也可以透過使用 Symbol 初始化 IndexedBase 來繼承:

>>> I = symbols('I', integer=True)
>>> C_inherit = IndexedBase(I)
>>> C_explicit = IndexedBase('I', integer=True)
>>> C_inherit == C_explicit
True 
property label

返回 IndexedBase 物件的標籤。

示例

>>> from sympy import IndexedBase
>>> from sympy.abc import x, y
>>> IndexedBase('A', shape=(x, y)).label
A 
property offset

返回 IndexedBase 物件的偏移量。

當將 2D Indexed 物件展開為 1D 形式時,新增到結果索引的值。用於程式碼生成。

示例

>>> from sympy.printing import ccode
>>> from sympy.tensor import IndexedBase, Idx
>>> from sympy import symbols
>>> l, m, n, o = symbols('l m n o', integer=True)
>>> A = IndexedBase('A', strides=(l, m, n), offset=o)
>>> i, j, k = map(Idx, 'ijk')
>>> ccode(A[i, j, k])
'A[l*i + m*j + n*k + o]' 
property shape

返回 IndexedBase 物件的形狀。

示例

>>> from sympy import IndexedBase, Idx
>>> from sympy.abc import x, y
>>> IndexedBase('A', shape=(x, y)).shape
(x, y) 

注意:如果指定了 IndexedBase 的形狀,它將覆蓋索引給出的任何形狀資訊。

>>> A = IndexedBase('A', shape=(x, y))
>>> B = IndexedBase('B')
>>> i = Idx('i', 2)
>>> j = Idx('j', 1)
>>> A[i, j].shape
(x, y)
>>> B[i, j].shape
(2, 1) 
property strides

返回 IndexedBase 物件的步進方案。

通常,這是一個元組,表示遍歷陣列時在相應維度上要採取的步數。為了程式碼生成的目的,也可以使用 strides='C'strides='F'

strides='C' 意味著程式碼列印器將按行主序展開,而'F'表示按列主序展開。

方法

原文連結:docs.sympy.org/latest/modules/tensor/index_methods.html

包含對 IndexedBase、Indexed 和 Idx 物件操作的模組

  • 檢查形狀符合度

  • 確定結果表示式中的索引

等等。

此模組中的方法可以透過呼叫 Expr 物件上的方法來實現。當事物穩定下來時,這可能是一個有用的重構。

sympy.tensor.index_methods.get_contraction_structure(expr)

確定expr的虛指數並描述其結構

透過dummy,我們指的是求和索引。

表示式的結構如下確定並描述:

  1. 描述了 Indexed 物件的符合求和,其中鍵是求和索引,相應的值是所有適用求和的項的集合。SymPy 表示式樹中的所有 Add 物件都是這樣描述的。

  2. 對於 SymPy 表示式樹中所有不是 Add 型別的節點,適用以下規則:

    如果節點發現其引數中有縮並,則該節點本身將作為字典中的一個鍵儲存。對於該鍵,相應的值是一個字典列表,每個字典是對 get_contraction_structure()遞迴呼叫的結果。該列表僅包含非平凡深層次縮並的字典,省略了只有一個鍵為 None 的字典。

注意

字典鍵中包含的表示式表示了多級索引縮並。巢狀字典顯示了巢狀縮並,並可能包含來自更深層級的字典。在實際計算中,必須首先計算最深層巢狀級別的求和,以便外部表示式可以訪問生成的索引物件。

示例

>>> from sympy.tensor.index_methods import get_contraction_structure
>>> from sympy import default_sort_key
>>> from sympy.tensor import IndexedBase, Idx
>>> x, y, A = map(IndexedBase, ['x', 'y', 'A'])
>>> i, j, k, l = map(Idx, ['i', 'j', 'k', 'l'])
>>> get_contraction_structure(x[i]*y[i] + A[j, j])
{(i,): {x[i]*y[i]}, (j,): {A[j, j]}}
>>> get_contraction_structure(x[i]*y[j])
{None: {x[i]*y[j]}} 

縮並因子的乘積導致表示內部縮並的巢狀字典。

>>> d = get_contraction_structure(x[i, i]*y[j, j])
>>> sorted(d.keys(), key=default_sort_key)
[None, x[i, i]*y[j, j]] 

在這種情況下,產品沒有縮並:

>>> d[None]
{x[i, i]*y[j, j]} 

因子首先進行縮並:

>>> sorted(d[x[i, i]*y[j, j]], key=default_sort_key)
[{(i,): {x[i, i]}}, {(j,): {y[j, j]}}] 

帶括號的 Add 物件也作為巢狀字典返回。括號內的項是包含引數之間縮並的 Mul,因此它將作為結果中的鍵。它儲存了對 Add 表示式進行遞迴呼叫後得到的字典。

>>> d = get_contraction_structure(x[i]*(y[i] + A[i, j]*x[j]))
>>> sorted(d.keys(), key=default_sort_key)
[(A[i, j]*x[j] + y[i])*x[i], (i,)]
>>> d[(i,)]
{(A[i, j]*x[j] + y[i])*x[i]}
>>> d[x[i]*(A[i, j]*x[j] + y[i])]
[{None: {y[i]}, (j,): {A[i, j]*x[j]}}] 

在底數或指數中具有縮並的冪也將作為字典中的鍵,對映到來自遞迴呼叫的結果列表:

>>> d = get_contraction_structure(A[j, j]**A[i, i])
>>> d[None]
{A[j, j]**A[i, i]}
>>> nested_contractions = d[A[j, j]**A[i, i]]
>>> nested_contractions[0]
{(j,): {A[j, j]}}
>>> nested_contractions[1]
{(i,): {A[i, i]}} 

上述示例中用字串表示的縮並結構描述可能看起來很複雜,但迭代處理起來很容易:

>>> from sympy import Expr
>>> for key in d:
...     if isinstance(key, Expr):
...         continue
...     for term in d[key]:
...         if term in d:
...             # treat deepest contraction first
...             pass
...     # treat outermost contactions here 
sympy.tensor.index_methods.get_indices(expr)

確定表示式expr的外部索引。

透過outer,我們指的是非求和索引。返回一個集合和一個字典。集合包含外部索引,字典包含索引對稱性的資訊。

示例

>>> from sympy.tensor.index_methods import get_indices
>>> from sympy import symbols
>>> from sympy.tensor import IndexedBase
>>> x, y, A = map(IndexedBase, ['x', 'y', 'A'])
>>> i, j, a, z = symbols('i j a z', integer=True) 

確定總表示式的索引,重複的索引意味著求和,例如矩陣 A 的跡:

>>> get_indices(A[i, i])
(set(), {}) 

在多項式情況下,要求項具有相同的外部索引。否則將引發 IndexConformanceException 異常。

>>> get_indices(x[i] + A[i, j]*y[j])
({i}, {}) 

異常:

IndexConformanceException 表示術語不相容,例如。

>>> get_indices(x[i] + y[j])                
 (...)
IndexConformanceException: Indices are not consistent: x(i) + y(j) 

警告

外部指數的概念遞回應用,從最深層開始。這意味著括號內部的虛數被假定首先求和,以便優雅地處理以下表示式:

>>> get_indices((x[i] + A[i, j]*y[j])*x[j])
({i, j}, {}) 

這是正確的,可能看起來方便,但你需要小心,因為如果要求,SymPy 會愉快地.expand()這個乘積。結果表示式將混合外部的j與括號內部的虛數,使其成為不同的表示式。為了安全起見,最好透過為所有應分開的收縮使用唯一的指數來避免這種模稜兩可的情況。

張量

原文:docs.sympy.org/latest/modules/tensor/tensor.html

class sympy.tensor.tensor.TensorIndexType(name, dummy_name=None, dim=None, eps_dim=None, metric_symmetry=1, metric_name='metric', **kwargs)

張量指標型別由其名稱和度規確定。

引數:

name:張量型別的名稱

dummy_name:虛指標的頭部名稱

dim:維度,可以是符號、整數或 None

eps_dimepsilon 張量的維度

metric_symmetry:表示度規對稱性的整數或 None 表示無度規

metric_name:度規張量的名稱字串

注意

metric_symmetry 引數的可能值為:

1:度規張量完全對稱 0:度規張量沒有指標對稱性 -1:度規張量完全反對稱 None:沒有度規張量(度規等於 None

預設情況下,度規假定為對稱的。也可以透過 .set_metric() 方法設定自定義張量。

如果有度規,則使用度規來提升和降低指標。

在非對稱度規的情況下,將採用以下提升和降低約定:

psi(a) = g(a, b)*psi(-b); chi(-a) = chi(b)*g(-b, -a)

由此可以輕鬆找到:

g(-a, b) = delta(-a, b)

其中 delta(-a, b) = delta(b, -a)Kronecker delta(參見 TensorIndex 關於指標約定)。對於反對稱度規,還有以下等式:

g(a, -b) = -delta(a, -b)

如果沒有度規,則無法提升或降低指標;例如,SU(N) 的定義表示的指標是“協變的”,共軛表示是“逆變的”;對於 N > 2,它們是線性獨立的。

如果 dim 是整數,則 eps_dim 預設等於 dim;否則可以分配(用於簡單的尺寸正規化);如果 eps_dim 不是整數,則 epsilonNone

示例

>>> from sympy.tensor.tensor import TensorIndexType
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> Lorentz.metric
metric(Lorentz,Lorentz) 

屬性

metric (度規張量)
delta (Kronecker delta)
epsilon (Levi-Civita epsilon 張量)
data ((已棄用) 用於在指定基礎上新增 ndarray 值的屬性)
class sympy.tensor.tensor.TensorIndex(name, tensor_index_type, is_up=True)

表示張量指標

引數:

name:指標的名稱,或者 True 表示自動分配

tensor_index_type:指標的 TensorIndexType

is_up:逆變指標的標誌(預設為 True

注意

張量指標遵循愛因斯坦求和約定進行縮並。

指標可以是逆變形式或協變形式;在後一種情況下,索引名稱前加 -。向協變(is_up=False)索引新增 - 使其變為逆變。

虛指標的名稱預設為 tensor_inde_type.dummy_name,後跟下劃線和數字。

類似於 symbols,可以使用 tensor_indices(s, typ) 一次建立多個逆變指標,其中 s 是名稱字串。

示例

>>> from sympy.tensor.tensor import TensorIndexType, TensorIndex, TensorHead, tensor_indices
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> mu = TensorIndex('mu', Lorentz, is_up=False)
>>> nu, rho = tensor_indices('nu, rho', Lorentz)
>>> A = TensorHead('A', [Lorentz, Lorentz])
>>> A(mu, nu)
A(-mu, nu)
>>> A(-mu, -rho)
A(mu, -rho)
>>> A(mu, -mu)
A(-L_0, L_0) 

屬性

name
tensor_index_type
is_up
class sympy.tensor.tensor.TensorHead(name, index_types, symmetry=None, comm=0)

張量的張量頭。

引數:

name:張量的名稱

index_types:TensorIndexType 的列表

symmetry:張量的 TensorSymmetry

comm:對易群號

注意事項

symbols類似,可以使用tensorhead(s, typ, sym=None, comm=0)函式建立多個TensorHead,其中s是名稱的字串,sym是單項張量對稱性(參見tensorsymmetry)。

TensorHead屬於一個對易群,由符號和數字comm定義(參見_TensorManager.set_comm);對易群中的張量具有相同的對易性質;預設情況下,comm0,表示對易張量的群。

示例

定義一個完全反對稱的二階張量:

>>> from sympy.tensor.tensor import TensorIndexType, TensorHead, TensorSymmetry
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> asym2 = TensorSymmetry.fully_symmetric(-2)
>>> A = TensorHead('A', [Lorentz, Lorentz], asym2) 

示例中使用 ndarray 值,假定分配給TensorHead物件的元件資料處於完全逆變表示。如果需要分配表示非完全協變張量值的元件資料,請參閱其他示例。

>>> from sympy.tensor.tensor import tensor_indices
>>> from sympy import diag
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> i0, i1 = tensor_indices('i0:2', Lorentz) 

指定一個替換字典以跟蹤在張量表示式中使用的陣列進行替換。TensorIndexType與用於縮並的度規相關聯(以完全協變形式):

>>> repl = {Lorentz: diag(1, -1, -1, -1)} 

讓我們看一些與電磁張量的元件一起工作的示例:

>>> from sympy import symbols
>>> Ex, Ey, Ez, Bx, By, Bz = symbols('E_x E_y E_z B_x B_y B_z')
>>> c = symbols('c', positive=True) 

讓我們定義(F),一個反對稱張量:

>>> F = TensorHead('F', [Lorentz, Lorentz], asym2) 

讓我們更新字典,包含用於替換的矩陣:

>>> repl.update({F(-i0, -i1): [
... [0, Ex/c, Ey/c, Ez/c],
... [-Ex/c, 0, -Bz, By],
... [-Ey/c, Bz, 0, -Bx],
... [-Ez/c, -By, Bx, 0]]}) 

現在可以檢索電磁張量的逆變形式:

>>> F(i0, i1).replace_with_arrays(repl, [i0, i1])
[[0, -E_x/c, -E_y/c, -E_z/c], [E_x/c, 0, -B_z, B_y], [E_y/c, B_z, 0, -B_x], [E_z/c, -B_y, B_x, 0]] 

和混合的逆變-協變形式:

>>> F(i0, -i1).replace_with_arrays(repl, [i0, -i1])
[[0, E_x/c, E_y/c, E_z/c], [E_x/c, 0, B_z, -B_y], [E_y/c, -B_z, 0, B_x], [E_z/c, B_y, -B_x, 0]] 

粒子的能量-動量可以表示為:

>>> from sympy import symbols
>>> P = TensorHead('P', [Lorentz], TensorSymmetry.no_symmetry(1))
>>> E, px, py, pz = symbols('E p_x p_y p_z', positive=True)
>>> repl.update({P(i0): [E, px, py, pz]}) 

分別是逆變和協變分量:

>>> P(i0).replace_with_arrays(repl, [i0])
[E, p_x, p_y, p_z]
>>> P(-i0).replace_with_arrays(repl, [-i0])
[E, -p_x, -p_y, -p_z] 

1-索引張量的收縮:

>>> expr = P(i0)*P(-i0)
>>> expr.replace_with_arrays(repl, [])
E**2 - p_x**2 - p_y**2 - p_z**2 

屬性

name
index_types
rank (索引的總數)
symmetry
comm (對易群)
commutes_with(other)

如果selfother對易,則返回0,如果它們反對易,則返回1

如果selfother既不對易也不反對易,則返回None

sympy.tensor.tensor.tensor_heads(s, index_types, symmetry=None, comm=0)

從字串(s)返回一系列TensorHead

class sympy.tensor.tensor.TensExpr(*args)

張量表示式的抽象基類

注意事項

張量表示式是由張量形成的表示式;目前將張量的和分佈開來。

TensExpr可以是TensAddTensMul

TensMul物件由分量張量的乘積組成,幷包括一個係數,這是一個 SymPy 表示式。

在內部表示中,收縮的指標由(ipos1, ipos2, icomp1, icomp2)表示,其中icomp1是具有逆變指標的分量張量的位置,ipos1是該分量張量中指標所佔的插槽。

因此,在內部表示中,收縮的指標是無名的。

get_matrix()

已棄用:請勿使用。

如果元件資料可用且 ndarray 維度不超過 2,則返回 ndarray 元件資料作為矩陣。

replace_with_arrays(replacement_dict, indices=None)

用陣列替換張量表示式。最終的陣列將對應於按照indices排列的 N 維陣列。

引數:

replacement_dict

包含張量替換規則的字典。

indices

與該陣列讀取相關的索引順序。如果未傳遞任何值,則將使用原始索引順序。

示例

>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices
>>> from sympy.tensor.tensor import TensorHead
>>> from sympy import symbols, diag 
>>> L = TensorIndexType("L")
>>> i, j = tensor_indices("i j", L)
>>> A = TensorHead("A", [L])
>>> A(i).replace_with_arrays({A(i): [1, 2]}, [i])
[1, 2] 

由於‘indices’是可選的,因此如果不需要特定的索引順序,我們也可以透過這種方式呼叫 replace_with_arrays:

>>> A(i).replace_with_arrays({A(i): [1, 2]})
[1, 2] 
>>> expr = A(i)*A(j)
>>> expr.replace_with_arrays({A(i): [1, 2]})
[[1, 2], [2, 4]] 

對於縮並,指定TensorIndexType的度量L的協變形式:

>>> expr = A(i)*A(-i)
>>> expr.replace_with_arrays({A(i): [1, 2], L: diag(1, -1)})
-3 

陣列的對稱化:

>>> H = TensorHead("H", [L, L])
>>> a, b, c, d = symbols("a b c d")
>>> expr = H(i, j)/2 + H(j, i)/2
>>> expr.replace_with_arrays({H(i, j): [[a, b], [c, d]]})
[[a, b/2 + c/2], [b/2 + c/2, d]] 

反對稱化的陣列:

>>> expr = H(i, j)/2 - H(j, i)/2
>>> repl = {H(i, j): [[a, b], [c, d]]}
>>> expr.replace_with_arrays(repl)
[[0, b/2 - c/2], [-b/2 + c/2, 0]] 

同一表示式也可以讀作透過反轉ij來進行轉置:

>>> expr.replace_with_arrays(repl, [j, i])
[[0, -b/2 + c/2], [b/2 - c/2, 0]] 
class sympy.tensor.tensor.TensAdd(*args, **kw_args)

張量的和。

引數:

free_args:自由指標的列表

示例

>>> from sympy.tensor.tensor import TensorIndexType, tensor_heads, tensor_indices
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> a, b = tensor_indices('a,b', Lorentz)
>>> p, q = tensor_heads('p,q', [Lorentz])
>>> t = p(a) + q(a); t
p(a) + q(a) 

示例,將元件資料新增到張量表示式中:

>>> from sympy import symbols, diag
>>> x, y, z, t = symbols("x y z t")
>>> repl = {}
>>> repl[Lorentz] = diag(1, -1, -1, -1)
>>> repl[p(a)] = [1, 2, 3, 4]
>>> repl[q(a)] = [x, y, z, t] 

以下是:22 - 32 - 22 - 72 ==> -58

>>> expr = p(a) + q(a)
>>> expr.replace_with_arrays(repl, [a])
[x + 1, y + 2, z + 3, t + 4] 

屬性

args (加法因子的元組)
rank (張量的秩)
free_args (按排序順序列出的自由指標的列表)
canon_bp()

使用 Butler-Portugal 演算法進行單項對稱性下的規範化。

contract_metric(g)

使用度量g升降指標。

引數:

g:度量

contract_all:如果為真,則消除所有已縮並的g

註釋

請參見TensorIndexType的文件字串以獲取縮並約定。

class sympy.tensor.tensor.TensMul(*args, **kw_args)

張量的乘積。

引數:

coeff:張量的 SymPy 係數

args

註釋

args[0]:組分張量的TensorHead的列表。

args[1]:(索引,位置,分量)的列表,其中ind是自由指標,iposicomp-th 分量張量中ind的插槽位置。

args[2]:表示虛指標的元組列表。(ipos1, ipos2, icomp1, icomp2)指示協變虛指標在icomp1-th 組分張量的第ipos1個插槽位置;相應的逆變指標在icomp2-th 組分張量的第ipos2個插槽位置。

屬性

components (組分張量的TensorHead的列表)
types (非重複的TensorIndexType的列表)
free (索引,位置,分量)的列表,請參見注釋。
dum (ipos1,ipos2,icomp1,icomp2)的列表,請參見注釋。
ext_rank (計算虛指標的張量秩)
rank (張量的秩)
coeff (張量的 SymPy 係數)
free_args (按排序順序列出的自由指標的列表)
is_canon_bp (如果張量處於規範形式則為True
canon_bp()

使用 Butler-Portugal 演算法進行單項對稱性下的規範化。

示例

>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TensorHead, TensorSymmetry
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz)
>>> A = TensorHead('A', [Lorentz]*2, TensorSymmetry.fully_symmetric(-2))
>>> t = A(m0,-m1)*A(m1,-m0)
>>> t.canon_bp()
-A(L_0, L_1)*A(-L_0, -L_1)
>>> t = A(m0,-m1)*A(m1,-m2)*A(m2,-m0)
>>> t.canon_bp()
0 
contract_metric(g)

使用度量g升降指標。

引數:

g:度量

註釋

請參見TensorIndexType的文件字串以獲取縮並約定。

示例

>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz)
>>> g = Lorentz.metric
>>> p, q = tensor_heads('p,q', [Lorentz])
>>> t = p(m0)*q(m1)*g(-m0, -m1)
>>> t.canon_bp()
metric(L_0, L_1)*p(-L_0)*q(-L_1)
>>> t.contract_metric(g).canon_bp()
p(L_0)*q(-L_0) 
get_free_indices() → list[TensorIndex]

返回張量的自由指標列表。

解釋

索引按組分張量中出現的順序列出。

示例

>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz)
>>> g = Lorentz.metric
>>> p, q = tensor_heads('p,q', [Lorentz])
>>> t = p(m1)*g(m0,m2)
>>> t.get_free_indices()
[m1, m0, m2]
>>> t2 = p(m1)*g(-m1, m2)
>>> t2.get_free_indices()
[m2] 
get_indices()

返回張量的索引列表。

解釋

索引按組分張量中出現的順序列出。虛指標被賦予一個不會與自由指標名稱衝突的名稱。

示例

>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz)
>>> g = Lorentz.metric
>>> p, q = tensor_heads('p,q', [Lorentz])
>>> t = p(m1)*g(m0,m2)
>>> t.get_indices()
[m1, m0, m2]
>>> t2 = p(m1)*g(-m1, m2)
>>> t2.get_indices()
[L_0, -L_0, m2] 
perm2tensor(g, is_canon_bp=False)

返回與排列g對應的張量。

更多詳細資訊,請參見 TIDS 中具有相同名稱的方法。

sorted_components()

返回一個具有排序元件的張量積。

split()

返回一個張量列表,其乘積為 self

解釋

不同張量元件之間的虛指標被用來表示相同名稱的自由指標。

示例

>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads, TensorSymmetry
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> a, b, c, d = tensor_indices('a,b,c,d', Lorentz)
>>> A, B = tensor_heads('A,B', [Lorentz]*2, TensorSymmetry.fully_symmetric(2))
>>> t = A(a,b)*B(-b,c)
>>> t
A(a, L_0)*B(-L_0, c)
>>> t.split()
[A(a, L_0), B(-L_0, c)] 
sympy.tensor.tensor.canon_bp(p)

巴特勒-葡萄牙規範化。詳見組合學模組的 tensor_can.py

sympy.tensor.tensor.riemann_cyclic_replace(t_r)

將黎曼張量替換為等效表示式。

R(m,n,p,q) -> 2/3*R(m,n,p,q) - 1/3*R(m,q,n,p) + 1/3*R(m,p,n,q)

sympy.tensor.tensor.riemann_cyclic(t2)

用滿足迴圈恆等式的等效表示式替換每個黎曼張量。

這個技巧在 Cadabra 參考指南中討論過。

示例

>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TensorHead, riemann_cyclic, TensorSymmetry
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> i, j, k, l = tensor_indices('i,j,k,l', Lorentz)
>>> R = TensorHead('R', [Lorentz]*4, TensorSymmetry.riemann())
>>> t = R(i,j,k,l)*(R(-i,-j,-k,-l) - 2*R(-i,-k,-j,-l))
>>> riemann_cyclic(t)
0 
class sympy.tensor.tensor.TensorSymmetry(*args, **kw_args)

張量的單項對稱性(即任何對稱或反對稱的索引置換)。有關相關術語,請參閱組合學模組的 tensor_can.py 部分。

引數:

bsgs:元組 (base, sgs) 張量的對稱性的 BSGS

註釋

一個張量可以透過其 BSGS 提供任意單項對稱性。多項對稱性,如黎曼張量的迴圈對稱性(即比安基恆等式),不包括在內。有關如何生成一般索引置換群的 BSGS 的資訊,請參見組合學模組。可以使用內建方法生成簡單的對稱性。

示例

定義一個二階對稱張量

>>> from sympy.tensor.tensor import TensorIndexType, TensorSymmetry, get_symmetric_group_sgs, TensorHead
>>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
>>> sym = TensorSymmetry(get_symmetric_group_sgs(2))
>>> T = TensorHead('T', [Lorentz]*2, sym) 

注意,使用內建的 TensorSymmetry 方法也可以完成相同的工作

>>> sym2 = TensorSymmetry.fully_symmetric(2)
>>> sym == sym2
True 

另請參閱

sympy.combinatorics.tensor_can.get_symmetric_group_sgs

屬性

base (BSGS 的基礎)
generators (BSGS 的生成器)
rank (張量的階)
classmethod direct_product(*args)

返回一個 TensorSymmetry 物件,它是完全(反)對稱索引排列組的直積。

註釋

一些 (*args) 的示例:(1) 向量,相當於 TensorSymmetry.fully_symmetric(1) (2) 有 2 個對稱索引的張量,相當於 .fully_symmetric(2) (-2) 有 2 個反對稱索引的張量,相當於 .fully_symmetric(-2) (2, -2) 第一個 2 個索引交換,最後 2 個反交換的張量 (1, 1, 1) 有 3 個索引且沒有任何對稱性的張量

classmethod fully_symmetric(rank)

返回一個完全對稱(如果 pyrank``<0) TensorSymmetry object for ``abs(rank) 索引則反對稱)的張量。

classmethod no_symmetry(rank)

返回一個 rank 沒有對稱性的張量對稱性物件。

classmethod riemann()

返回黎曼張量的單調對稱性。

sympy.tensor.tensor.tensorsymmetry(*args)

返回一個 TensorSymmetry 物件。此方法已棄用,請使用 TensorSymmetry.direct_product().riemann() 替代。

解釋

可以使用 BSGS 表示任何單項槽對稱性群的張量。

args 可以是 BSGS args[0] 的基礎 args[1] 的 sgs

通常張量位於(直積的)對稱群的表示中;args 可以是表示 Young 表的形狀列表的列表。

註釋

例如:[[1]] 向量 [[1]*n] 秩為 n 的對稱張量 [[n]] 秩為 n 的反對稱張量 [[2, 2]] 黎曼張量的單項對稱性 [[1],[1]] 向量向量 [[2],[1],[1](反對稱張量)向量*向量

注意,對於形狀 [2, 2],我們只與黎曼張量的單項對稱性相關聯;這是符號濫用,因為形狀 [2, 2] 通常對應於由單項對稱性和迴圈對稱性特徵化的不可約表示。

class sympy.tensor.tensor.TensorType(*args, **kwargs)

張量型別類。已棄用,請改用 tensor_heads()

引數:

index_types:張量索引的 TensorIndexType 列表

symmetry:張量的 TensorSymmetry

屬性

index_types
symmetry
types (無重複的 TensorIndexType 列表)
class sympy.tensor.tensor._TensorManager

類用於管理張量屬性。

注意

張量屬於張量交換群;每個群有一個標籤 comm;有預定義的標籤:

0 張量與任何其他張量交換

1 張量彼此反交換

2 張量不交換,與 comm=0 的張量分開

可以使用 set_comm 定義其他組;這些組中的張量與 comm=0 的張量交換;預設情況下,它們不與任何其他組交換。

clear()

清除 TensorManager。

comm_i2symbol(i)

返回與交換群編號對應的符號。

comm_symbols2i(i)

獲取與 i 對應的交換群編號。

i 可以是符號、數字或字串。

如果 i 還沒有定義其交換群編號,則設定為其交換群編號。

get_comm(i, j)

返回交換群編號 i, j 的交換引數

_TensorManager.set_comm

set_comm(i, j, c)

設定交換群 i, j 的交換引數 c

引數:

i, j:表示交換群的符號

c:群交換編號

注意

i, j 可以是符號、字串或數字,除了 0, 12 分別保留給交換、反交換張量和與任何其他組不交換的張量。對於其餘情況,請使用此方法設定交換規則;預設情況下 c=None

交換群編號 c 分配給與交換群符號對應的群;可以為

0 交換

1 反交換

None 無交換屬性

示例

GGH 與自己不交換,彼此之間交換;A 是交換的。

>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TensorHead, TensorManager, TensorSymmetry
>>> Lorentz = TensorIndexType('Lorentz')
>>> i0,i1,i2,i3,i4 = tensor_indices('i0:5', Lorentz)
>>> A = TensorHead('A', [Lorentz])
>>> G = TensorHead('G', [Lorentz], TensorSymmetry.no_symmetry(1), 'Gcomm')
>>> GH = TensorHead('GH', [Lorentz], TensorSymmetry.no_symmetry(1), 'GHcomm')
>>> TensorManager.set_comm('Gcomm', 'GHcomm', 0)
>>> (GH(i1)*G(i0)).canon_bp()
G(i0)*GH(i1)
>>> (G(i1)*G(i0)).canon_bp()
G(i1)*G(i0)
>>> (G(i1)*A(i0)).canon_bp()
A(i0)*G(i1) 
set_comms(*args)

設定符號 i, j 的交換群編號 c

引數:

args(i, j, c) 的序列

張量運算子

原文連結:docs.sympy.org/latest/modules/tensor/toperators.html

class sympy.tensor.toperators.PartialDerivative(expr, *variables)

張量表示式的偏導數。

示例

>>> from sympy.tensor.tensor import TensorIndexType, TensorHead
>>> from sympy.tensor.toperators import PartialDerivative
>>> from sympy import symbols
>>> L = TensorIndexType("L")
>>> A = TensorHead("A", [L])
>>> B = TensorHead("B", [L])
>>> i, j, k = symbols("i j k") 
>>> expr = PartialDerivative(A(i), A(j))
>>> expr
PartialDerivative(A(i), A(j)) 

PartialDerivative 物件的行為類似張量表示式:

>>> expr.get_indices()
[i, -j] 

注意求導變數的價度與列印的相反:A(j) 列印為協變,但導數的指標實際上是逆變的,即 -j

指標可以被縮並:

>>> expr = PartialDerivative(A(i), A(i))
>>> expr
PartialDerivative(A(L_0), A(L_0))
>>> expr.get_indices()
[L_0, -L_0] 

方法 .get_indices() 總是返回所有指標(即使是縮並的)。如果只需要未縮並的指標,請呼叫 .get_free_indices()

>>> expr.get_free_indices()
[] 

巢狀偏導數被展開:

>>> expr = PartialDerivative(PartialDerivative(A(i), A(j)), A(k))
>>> expr
PartialDerivative(A(i), A(j), A(k))
>>> expr.get_indices()
[i, -j, -k] 

用陣列值替換導數:

>>> from sympy.abc import x, y
>>> from sympy import sin, log
>>> compA = [sin(x), log(x)*y**3]
>>> compB = [x, y]
>>> expr = PartialDerivative(A(i), B(j))
>>> expr.replace_with_arrays({A(i): compA, B(i): compB})
[[cos(x), 0], [y**3/x, 3*y**2*log(x)]] 

返回的陣列由 ((i, -j)) 索引。

注意其他 SymPy 模組在導數結果中將求導變數的指標放在被導變數的指標之前。例如:

>>> expr.get_free_indices()
[i, -j] 
>>> from sympy import Matrix, Array
>>> Matrix(compA).diff(Matrix(compB)).reshape(2, 2)
[[cos(x), y**3/x], [0, 3*y**2*log(x)]]
>>> Array(compA).diff(Array(compB))
[[cos(x), y**3/x], [0, 3*y**2*log(x)]] 

這些是 PartialDerivative 的轉置,因為矩陣和陣列模組在導數結果中將指標 (-j) 放在 (i) 前面。用指標順序 (-j, i) 讀取的陣列確實是用指標順序 (i, -j) 讀取的同一陣列的轉置。透過指定 .replace_with_arrays 的指標順序,可以得到相容的表示式:

>>> expr.replace_with_arrays({A(i): compA, B(i): compB}, [-j, i])
[[cos(x), y**3/x], [0, 3*y**2*log(x)]] 

向量

原文:docs.sympy.org/latest/modules/vector/index.html

向量模組提供了基本的向量數學和相對於 3D 笛卡爾座標系的微分計算工具。此文件概述了提供的所有功能及相關 API。

向量指南

  • 介紹

  • 基本實現細節

  • 關於座標系的更多資訊

  • 標量和向量場功能

  • 使用的一般示例

  • 向量積分的應用

  • 向量 API

    • sympy.vector 中的基本類(文件字串)

    • 定向器類(文件字串)

    • sympy.vector 中的基本函式(文件字串)

向量的參考資料

[Dyadics]

en.wikipedia.org/wiki/Dyadics

[DyadicProducts]

en.wikipedia.org/wiki/Dyadic_product

[DelOperator]

en.wikipedia.org/wiki/Del

引言

原文連結:docs.sympy.org/latest/modules/vector/intro.html

本頁提供了對 sympy.vector 模組功能的簡要概述。

向量和標量

在向量數學中,我們處理兩種型別的量:標量和向量。

標量是僅具有大小而沒有方向的實體。標量量的例子包括質量、電荷、溫度、距離等。

另一方面,向量是由大小和方向特徵的實體。向量量的例子包括位移、速度、磁場等。

標量可以僅用一個數字表示,例如 300 K 的溫度。另一方面,加速度等向量量通常用向量表示。給定一個向量 (\mathbf{V}),相應量的大小可以計算為向量本身的大小 (\Vert \mathbf{V} \Vert),而方向則由原向量方向上的單位向量指定,(\mathbf{\hat{V}} = \frac{\mathbf{V}}{\Vert \mathbf{V} \Vert})。

例如,考慮位移為 ((3\mathbf{\hat{i}} + 4\mathbf{\hat{j}} + 5\mathbf{\hat{k}})) 米的情況,其中,按照標準慣例,(\mathbf{\hat{i}})、(\mathbf{\hat{j}}) 和 (\mathbf{\hat{k}}) 分別表示沿 (\mathbf{X})、(\mathbf{Y}) 和 (\mathbf{Z}) 軸的單位向量。因此,可以得出行程為 (\Vert 3\mathbf{\hat{i}} + 4\mathbf{\hat{j}} + 5\mathbf{\hat{k}} \Vert) 米 = (5\sqrt{2}) 米。行進方向由單位向量 (\frac{3}{5\sqrt{2}}\mathbf{\hat{i}} + \frac{4}{5\sqrt{2}}\mathbf{\hat{j}} + \frac{5}{5\sqrt{2}}\mathbf{\hat{k}}) 給出。

座標系

座標系是用來定義 n 維空間中方向和位置概念的抽象數學實體。本模組處理的是三維空間,傳統的 (X)、(Y) 和 (Z) 軸分別相對於每個座標系定義。

每個座標系還有一個稱為“原點”的特殊參考點。這一點在引用三維空間中的位置或計算相對於系統的預定義點的座標時使用。

這是一個相當知名的概念:在空間中沒有絕對的位置或方向的概念。任何給定的座標系都定義了一個獨特的“視角”,用來量化位置和方向。因此,即使我們假設所有系統都使用相同的測量單位,向量和標量量的表達也會根據某個觀察者使用的座標系而有所不同。

考慮空間中的兩點(P)和(Q)。假設單位在整個過程中是通用的,這兩點之間的距離不變,無論在哪個座標系中進行測量。然而,每個點的三維座標以及任一點相對於另一點的位置向量並不會保持不變。事實上,除非它們是在考慮某一位置和測量者的方向(本質上是座標系)的情況下進行測量,否則這兩個量根本就沒有意義。

因此,很明顯,座標系的方向和位置(原點)定義了不同量如何相對於它來表達。這兩個屬性都不能在絕對尺度上進行測量,而是相對於另一個座標系來測量。一個系統相對於另一個系統的方向是使用旋轉矩陣來測量的,而相對位置可以透過一個系統原點到另一個系統原點的位置向量來量化。

是可以作為位置的函式在空間的任何地方指定的向量或標量數量(注意,通常場也可能依賴於時間和其他自定義變數)。由於我們在本模組中只處理三維空間,因此場被定義為與座標系中位置對應的(x)、(y)和(z)座標的函式。在這裡,(x)、(y)和(z)充當定義一般點位置的標量變數。

例如,三維空間中的溫度(溫度場)可以寫成(T(x, y, z)) – 位置的標量函式。在電磁學中,標量場的一個例子是電勢。

類似地,可以將向量場定義為空間中任意點位置((x, y, z))的向量函式。

例如,地球上的每一個點都可以被認為處於地球的重力場中。我們可以透過每個空間點處的加速度大小和方向(即單位質量的力)(\vec g(x, y, z)) 來指定該場。

舉例來說,考慮一個三維空間中形式為(2{x}^{2}y)的電勢場。相應的保守電場可以計算為電勢函式的梯度,並表示為(4xy\mathbf{\hat{i}} + 2{x}{2}\mathbf{\hat{j}})。該電場的大小反過來可以表示為形如(\sqrt{4{x} + 16{x}{2}{y}{2}})的標量場。

基本實現細節

原文連結:docs.sympy.org/latest/modules/vector/basics.html

座標系和向量

目前,sympy.vector 能夠處理笛卡爾(也稱為矩形)、球面和其他曲線座標系。

可以在 sympy.vector 中初始化 3D 笛卡爾座標系。

>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N') 

建構函式的字串參數列示分配給系統的名稱,並且主要用於列印目的。

一旦定義了座標系(本質上是 CoordSys3D 例項),我們可以訪問標準單位向量(即 (\mathbf{\hat{i}})、(\mathbf{\hat{j}}) 和 (\mathbf{\hat{k}}) 向量)和座標變數/基標量(即 (\mathbf{x})、(\mathbf{y}) 和 (\mathbf{z}) 變數)。關於座標變數我們將在後面的章節中詳細討論。

可以使用 ijk 屬性分別訪問 (X)、(Y) 和 (Z) 軸的基向量。

>>> N.i
N.i
>>> type(N.i)
<class 'sympy.vector.vector.BaseVector'> 

如上所示,基向量都是名為 BaseVector 的類的例項。

BaseVector 乘以標量(實質上是任何 SymPy Expr)時,我們得到 VectorMul - 基向量與標量的乘積。

>>> 3*N.i
3*N.i
>>> type(3*N.i)
<class 'sympy.vector.vector.VectorMul'> 

VectorMulBaseVectors 的加法形成 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'> 

零向量怎麼辦?可以使用分配給 Vector 類的 zero 屬性訪問。由於零向量的概念在考慮的座標系中保持不變,我們在需要這種量時使用 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 

所有上述類 - BaseVectorVectorMulVectorAddVectorZero 都是 Vector 的子類。

您永遠不應該例項化 Vector 的任何子類的物件。使用分配給 CoordSys3D 例項的 BaseVector 例項和(如果需要)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 

除了基本的數學運算外,還可以在 Vector 上執行 dotcross 的向量運算。

>>> 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 

dotcross 方法的 &^ 運算子已過載。

>>> v1 & v2
-11
>>> v1 ^ v2
(-1)*N.i + (-3)*N.j + (-11)*N.k 

然而,這不是執行這些操作的推薦方式。使用原始方法使程式碼更清晰,更易於理解。

除了這些操作外,在 sympy.vector 中還可以計算 Vector 例項的外積。稍後將詳細介紹。

SymPy 向量的操作

SymPy 操作 simplifytrigsimpdifffactor 適用於 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類的形式實現。

要訪問系統的原點,請使用CoordSys3D類的origin屬性。

>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
>>> N.origin
N.origin
>>> type(N.origin)
<class 'sympy.vector.point.Point'> 

您可以使用Pointlocate_new方法在空間中例項化新點。引數包括新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物件。這是因為可以透過使用CoordSys3Dorigin作為參考來指向空間中的任何位置(儘管是相對位置),然後在其上使用locate_new和後續的Point例項。

可以使用position_wrt方法計算一個Point相對於另一個Point的位置向量。

>>> P.position_wrt(Q)
b*N.j
>>> Q.position_wrt(N.origin)
a*N.i + c*N.k 

此外,可以透過express_coordinates方法獲取相對於CoordSys3DPoint的(X)、(Y)和(Z)座標,以元組的形式表示。

>>> Q.express_coordinates(N)
(a, 0, c) 

二階張量

二階張量,或者說二階張量,是由向量對並列形成的。因此,向量的外積導致二階張量的形成。在sympy.vector中,已經用Dyadic類實現了二階張量。

再次強調,您永遠不需要例項化Dyadic物件。可以使用Vectorouter方法計算向量的外積。|運算子已經為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) 

類似於VectorDyadic也有像BaseDyadicDyadicMulDyadicAdd這樣的後續子類。與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) 

dotcrossDyadic例項之間以及DyadicVector之間(反之亦然)也有效,如各自的數學定義。與Vector類似,&^已經為dotcross過載。

>>> 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) 

更多關於座標系的內容

原文連結:docs.sympy.org/latest/modules/vector/coordsys.html

現在我們來看看如何在 sympy.vector 中初始化新的座標系,透過使用者定義的方式相對於已有系統進行變換。

定位新系統

我們已經知道 CoordSys3Dorigin 屬性對應於表示其原點參考點的 Point 例項。

考慮一個座標系 (N)。假設我們想定義一個新系統 (M),其原點相對於 (N) 的原點位於 (\mathbf{3\hat{i} + 4\hat{j} + 5\hat{k}}) 處。換句話說,從 (N) 的角度看,(M) 的原點座標是 ((3, 4, 5))。此外,這也意味著從 (M) 的角度看,(N) 的原點座標是 ((-3, -4, -5))。

這可以透過程式設計方式實現如下 -

>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
>>> M = N.locate_new('M', 3*N.i + 4*N.j + 5*N.k)
>>> M.position_wrt(N)
3*N.i + 4*N.j + 5*N.k
>>> N.origin.express_coordinates(M)
(-3, -4, -5) 

值得注意的是,(M) 的方向與 (N) 的方向相同。這意味著:(N) 相對於 (M) 的旋轉矩陣,以及反過來,都等於維度為 3x3 的單位矩陣。locate_new 方法初始化一個 CoordSys3D,它在空間中只是平移,而不重新定向,相對於“父”系統。

初始化新系統

與‘定位’新系統類似,sympy.vector 還允許初始化新的 CoordSys3D 例項,這些例項以使用者定義的方式相對於現有系統定向。

假設您有一個座標系 (A)。

>>> from sympy.vector import CoordSys3D
>>> A = CoordSys3D('A') 

您希望初始化一個新的座標系 (B),該座標系相對於 (A) 的 Z 軸旋轉了一個角度 (\theta)。

>>> from sympy import Symbol
>>> theta = Symbol('theta') 

方向如下圖所示:

image/svg+xml A B θ θ azbz ax bx ay by

有兩種方法可以實現這一點。

直接使用 CoordSys3D 方法

這是最簡單、最乾淨且推薦的方法。

>>> B = A.orient_new_axis('B', theta, A.k) 

這使用所需的方位資訊初始化(B),相對於(A)。

CoordSys3D在其 API 中提供了以下直接定向方法-

  1. orient_new_axis

  2. orient_new_body

  3. orient_new_space

  4. orient_new_quaternion

請檢視本模組文件中給出的CoordSys3D類 API,以詳細瞭解它們的功能和所需的引數。

使用Orienterorient_new方法

您首先需要初始化一個AxisOrienter例項來儲存旋轉資訊。

>>> from sympy.vector import AxisOrienter
>>> axis_orienter = AxisOrienter(theta, A.k) 

然後使用orient_new方法應用它,以獲得(B)。

>>> B = A.orient_new('B', axis_orienter) 

orient_new還允許您使用多個Orienter例項定向新系統,這些例項以可迭代形式提供。旋轉/定向按照Orienter例項在可迭代中出現的順序應用於新系統。

>>> from sympy.vector import BodyOrienter
>>> from sympy.abc import a, b, c
>>> body_orienter = BodyOrienter(a, b, c, 'XYZ')
>>> C = A.orient_new('C', (axis_orienter, body_orienter)) 

sympy.vector API 為定向目的提供以下四個Orienter類:

  1. AxisOrienter

  2. BodyOrienter

  3. SpaceOrienter

  4. QuaternionOrienter

請參考本模組文件中各類的 API,瞭解更多資訊。

在上述每個示例中,新座標系的原點與“父”系統的原點重合。

>>> B.position_wrt(A)
0 

要計算任何座標系相對於另一個座標系的旋轉矩陣,請使用rotation_matrix方法。

>>> B = A.orient_new_axis('B', a, A.k)
>>> B.rotation_matrix(A)
Matrix([
[ cos(a), sin(a), 0],
[-sin(a), cos(a), 0],
[      0,      0, 1]])
>>> B.rotation_matrix(B)
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]) 

定位和定向新系統

如果您想要初始化一個不僅在預定義方式下定向的新系統,還在父系統中進行了平移,該怎麼辦?

每個orient_new_<定向方法>方法以及orient_new方法都支援location關鍵字引數。

如果將Vector作為此kwarg的值提供,那麼新系統的原點將自動定義為相對於父座標系的該位置向量。

因此,定向方法也作為支援新系統定向+定位的方法。

>>> C = A.orient_new_axis('C', a, A.k, location=2*A.j)
>>> C.position_wrt(A)
2*A.j
>>> from sympy.vector import express
>>> express(A.position_wrt(C), C)
(-2*sin(a))*C.i + (-2*cos(a))*C.j 

後面詳述express函式。

轉換新系統

建立使用者定義系統的最一般方法是在CoordSys3D中使用transformation引數。在這裡,我們可以定義任何轉換方程。如果我們對某些不同於笛卡爾座標系的典型曲線座標系感興趣,我們也可以使用一些預定義的座標系。也可以透過設定適當的轉換方程來平移或旋轉系統。

>>> from sympy.vector import CoordSys3D
>>> from sympy import sin, cos
>>> A = CoordSys3D('A', transformation='spherical')
>>> B = CoordSys3D('A', transformation=lambda x,y,z: (x*sin(y), x*cos(y), z)) 

CoordSys3D中還有專用方法create_new,其工作方式類似於locate_neworient_new_axis等方法。

>>> from sympy.vector import CoordSys3D
>>> A = CoordSys3D('A')
>>> B = A.create_new('B', transformation='spherical') 

在不同座標系中的量的表示式

向量和二元向量

正如前面提到的,同一向量在不同座標系中具有不同的表示式。通常,標量表示式和二階張量也是如此。

sympy.vector 支援使用 express 函式在不同的座標系中表達向量/標量量。

在本節中,假定以下初始化:

>>> from sympy.vector import CoordSys3D, express
>>> from sympy.abc import a, b, c
>>> N = CoordSys3D('N')
>>> M = N.orient_new_axis('M', a, N.k) 

使用者可以使用 expressVector 例項表示為使用者定義的系統。

>>> v1 = N.i + N.j + N.k
>>> express(v1, M)
(sin(a) + cos(a))*M.i + (-sin(a) + cos(a))*M.j + M.k
>>> v2 = N.i + M.j
>>> express(v2, N)
(1 - sin(a))*N.i + (cos(a))*N.j 

除了 Vector 例項外,express 還支援重新表達標量(一般的 SymPy Expr)和 Dyadic 物件。

express 還接受第二個座標系,用於重新表達 Dyadic 例項。

>>> d = 2*(M.i | N.j) + 3* (M.j | N.k)
>>> express(d, M)
(2*sin(a))*(M.i|M.i) + (2*cos(a))*(M.i|M.j) + 3*(M.j|M.k)
>>> express(d, M, N)
2*(M.i|N.j) + 3*(M.j|N.k) 

座標變數

座標系的原點位置不影響 BaseVector 例項的重新表達。但它確實影響了在不同系統中表達 BaseScalar 例項的方式。

BaseScalar 例項是座標‘符號’,用於表示 sympy.vector 中向量/標量場的定義中使用的變數。

例如,考慮在系統 (N) 中定義的標量場 (\mathbf{{T}{N}(x, y, z) = x + y + z})。因此,在座標為 ((a, b, c)) 的點處,該場的值為 (a + b + c)。現在考慮系統 (R),其原點相對於 (N) 位於 ((1, 2, 3))(無方向變化)。在 (R) 中座標為 ((a, b, c)) 的點,在 (N) 中的座標為 ((a + 1, b + 2, c + 3))。因此,在系統 (R) 中,(\mathbf{{T}{N}}) 的表示式變為 (\mathbf{{T}_{R}}(x, y, z) = x + y + z + 6)。

如果向量/標量/二態表示式中存在座標變數,則可以透過將 expressvariables 關鍵字引數設定為 True 來在給定座標系中重新表達它們。

上述示例,以程式設計方式完成,看起來像這樣 -

>>> R = N.locate_new('R', N.i + 2*N.j + 3*N.k)
>>> T_N = N.x + N.y + N.z
>>> express(T_N, R, variables=True)
R.x + R.y + R.z + 6 

其他依賴表示式的方法

Vectorto_matrix 方法和 Pointexpress_coordinates 方法在提供不同座標系時返回不同結果。

>>> P = R.origin.locate_new('P', a*R.i + b*R.j + c*R.k)
>>> P.express_coordinates(N)
(a + 1, b + 2, c + 3)
>>> P.express_coordinates(R)
(a, b, c)
>>> v = N.i + N.j + N.k
>>> v.to_matrix(M)
Matrix([
[ sin(a) + cos(a)],
[-sin(a) + cos(a)],
[               1]])
>>> v.to_matrix(N)
Matrix([
[1],
[1],
[1]]) 

標量和向量場功能

原文連結:docs.sympy.org/latest/modules/vector/fields.html

在 sympy.vector 中的實現

標量和向量場

sympy.vector 中,每個 CoordSys3D 例項都分配了與 (X)、(Y) 和 (Z) 軸對應的基向量。這些可以分別透過名為 ijk 的屬性訪問。因此,要定義相對於給定框架 (\mathbf{R}) 的形式為 (3\mathbf{\hat{i}} + 4\mathbf{\hat{j}} + 5\mathbf{\hat{k}}) 的向量 (\mathbf{v}),您需要執行

>>> from sympy.vector import CoordSys3D
>>> R = CoordSys3D('R')
>>> v = 3*R.i + 4*R.j + 5*R.k 

向量數學和與向量相關的基本微積分運算已經在本模組文件的早期部分詳細說明。

另一方面,基本標量(或座標變數)實現在一個稱為 BaseScalar 的特殊類中,並且為每個座標系分配一個,從 (X)、(Y) 到 (Z) 的每個軸。這些座標變數用於在三維空間中形成向量或標量場的表示式。對於系統 R,(X)、(Y) 和 (Z) 的 BaseScalars 例項可以分別使用 R.xR.yR.z 表示式訪問。

因此,要生成前述電勢場 (2{x}^{2}y) 的表示式,您需要執行

>>> from sympy.vector import CoordSys3D
>>> R = CoordSys3D('R')
>>> electric_potential = 2*R.x**2*R.y
>>> electric_potential
2*R.x**2*R.y 

注意,BaseScalar 例項可以像任何其他 SymPy Symbol 一樣使用,只是它們儲存與其對應的座標系和軸的資訊。

標量場可以像任何其他 SymPy 表示式一樣處理,適用於任何數學/微積分功能。因此,要針對 (x)(即 R.x)不同電勢,您將使用 diff 方法。

>>> from sympy.vector import CoordSys3D
>>> R = CoordSys3D('R')
>>> electric_potential = 2*R.x**2*R.y
>>> from sympy import diff
>>> diff(electric_potential, R.x)
4*R.x*R.y 

值得注意的是,在表示式中有 BaseScalar 意味著‘場’隨位置(在三維空間中)變化。嚴格來說,一個簡單的 Expr 沒有 BaseScalar 仍然是一個場,儘管是常量。

類似於標量場,隨位置變化的向量場也可以使用測量數字表示式中的 BaseScalar 構造。

>>> from sympy.vector import CoordSys3D
>>> R = CoordSys3D('R')
>>> v = R.x**2*R.i + 2*R.x*R.z*R.k 

Del 運算元

Del 或 ‘Nabla’ 運算元 - 寫作 (\mathbf{\nabla}),通常稱為向量微分運算元。根據其在數學表示式中的用法,它可以表示標量場的梯度、向量場的散度或向量場的旋度。

本質上,(\mathbf{\nabla}) 在技術上不是一個‘運算元’,而是一個便捷的數學符號,用於表示前述任一場操作。

sympy.vector 中,(\mathbf{\nabla}) 已經實現為 Del() 類。此類的例項獨立於座標系。因此,(\mathbf{\nabla}) 運算元可以作為 Del() 訪問。

下面是使用 Del() 類的一個示例。

>>> from sympy.vector import CoordSys3D, Del
>>> C = CoordSys3D('C')
>>> delop = Del()
>>> gradient_field = delop(C.x*C.y*C.z)
>>> gradient_field
(Derivative(C.x*C.y*C.z, C.x))*C.i + (Derivative(C.x*C.y*C.z, C.y))*C.j
+ (Derivative(C.x*C.y*C.z, C.z))*C.k 

可以使用 SymPy 的doit()例程計算上述表示式。

>>> gradient_field.doit()
C.y*C.z*C.i + C.x*C.z*C.j + C.x*C.y*C.k 

sympy.vector中詳細描述了使用(\mathbf{\nabla})符號的方法。

場運算元和相關函式

這裡我們描述了實現在sympy.vector中的一些基本場相關功能。

旋度

一個旋度是描述三維空間中向量微小旋轉的數學運算元。方向由右手法則(沿著旋轉軸)確定,大小由旋轉的大小確定。

在 3D 笛卡爾座標系中,三維向量(\mathbf{F})的旋度,表示為(\nabla \times \mathbf{F}),由以下給出:

(\nabla \times \mathbf{F} = \left(\frac{\partial F_z}{\partial y} - \frac{\partial F_y}{\partial z}\right) \mathbf{\hat{i}} + \left(\frac{\partial F_x}{\partial z} - \frac{\partial F_z}{\partial x}\right) \mathbf{\hat{j}} + \left(\frac{\partial F_y}{\partial x} - \frac{\partial F_x}{\partial y}\right) \mathbf{\hat{k}})

其中(F_x)表示向量(\mathbf{F})的(X)分量。

可以透過兩種方式在sympy.vector中計算向量場的旋度。

透過使用Del()類之一

>>> from sympy.vector import CoordSys3D, Del
>>> C = CoordSys3D('C')
>>> delop = Del()
>>> delop.cross(C.x*C.y*C.z*C.i).doit()
C.x*C.y*C.j + (-C.x*C.z)*C.k
>>> (delop ^ C.x*C.y*C.z*C.i).doit()
C.x*C.y*C.j + (-C.x*C.z)*C.k 

或者透過使用專用函式

>>> from sympy.vector import curl
>>> curl(C.x*C.y*C.z*C.i)
C.x*C.y*C.j + (-C.x*C.z)*C.k 

散度

散度是一個向量運算元,用於測量向量場在給定點的源或匯的大小,用帶符號的標量表示。

散度運算元在對向量進行操作後總是返回一個標量。

在 3D 笛卡爾座標系中,三維向量(\mathbf{F})的散度,表示為(\nabla\cdot\mathbf{F}),由以下給出:

(\nabla\cdot\mathbf{F} = \frac{\partial U}{\partial x} + \frac{\partial V}{\partial y} + \frac{\partial W}{\partial z })

其中(U)、(V)和(W)分別表示(\mathbf{F})的(X)、(Y)和(Z)分量。

可以透過兩種方式在sympy.vector中計算向量場的散度。

透過使用Del()類之一

>>> from sympy.vector import CoordSys3D, Del
>>> C = CoordSys3D('C')
>>> delop = Del()
>>> delop.dot(C.x*C.y*C.z*(C.i + C.j + C.k)).doit()
C.x*C.y + C.x*C.z + C.y*C.z
>>> (delop & C.x*C.y*C.z*(C.i + C.j + C.k)).doit()
C.x*C.y + C.x*C.z + C.y*C.z 

或者透過使用專用函式

>>> from sympy.vector import divergence
>>> divergence(C.x*C.y*C.z*(C.i + C.j + C.k))
C.x*C.y + C.x*C.z + C.y*C.z 

梯度

考慮三維空間中的標量場(f(x, y, z))。該場的梯度定義為相對於(X)、(Y)和(Z)軸的(f)的 3 個偏導數的向量。

在 3D 笛卡爾座標系中,標量場(f)的散度(\nabla f)由以下給出 -

(\nabla f = \frac{\partial f}{\partial x} \mathbf{\hat{i}} + \frac{\partial f}{\partial y} \mathbf{\hat{j}} + \frac{\partial f}{\partial z} \mathbf{\hat{k}})

可以透過兩種方式在sympy.vector中計算向量場的散度。

透過使用Del()類之一

>>> from sympy.vector import CoordSys3D, Del
>>> C = CoordSys3D('C')
>>> delop = Del()
>>> delop.gradient(C.x*C.y*C.z).doit()
C.y*C.z*C.i + C.x*C.z*C.j + C.x*C.y*C.k
>>> delop(C.x*C.y*C.z).doit()
C.y*C.z*C.i + C.x*C.z*C.j + C.x*C.y*C.k 

或者透過使用專用函式

>>> from sympy.vector import gradient
>>> gradient(C.x*C.y*C.z)
C.y*C.z*C.i + C.x*C.z*C.j + C.x*C.y*C.k 

方向導數

除了上述三種常見的 (\mathbf{\nabla}) 應用外,在 sympy.vector 中還可以計算相對於 Vector 的場的方向導數。

按定義,場 (\mathbf{F}) 沿著向量 (v) 在點 (x) 處的方向導數表示 (\mathbf{F}) 在速度 (v) 下透過 (x) 移動的瞬時變化率。數學上表示為:((\vec{v} \cdot \nabla) , \mathbf{F}(x))。

可以使用 Del() 類在 sympy.vector 中計算向量和標量場的方向導數。

>>> from sympy.vector import CoordSys3D, Del
>>> C = CoordSys3D('C')
>>> delop = Del()
>>> vel = C.i + C.j + C.k
>>> scalar_field = C.x*C.y*C.z
>>> vector_field = C.x*C.y*C.z*C.i
>>> (vel.dot(delop))(scalar_field)
C.x*C.y + C.x*C.z + C.y*C.z
>>> (vel & delop)(vector_field)
(C.x*C.y + C.x*C.z + C.y*C.z)*C.i 

或者透過使用專用函式

>>> from sympy.vector import directional_derivative
>>> directional_derivative(C.x*C.y*C.z, 3*C.i + 4*C.j + C.k)
C.x*C.y + 4*C.x*C.z + 3*C.y*C.z 

正交曲線座標系中的場運算元

vector 包支援在不同型別的正交曲線座標系中進行計算。為了實現這一點,使用縮放因子(也稱為拉梅係數)來表達在所需型別的座標系中計算 curldivergencegradient

例如,如果我們想在柱座標系中計算 gradient,我們只需建立適當的座標系。

>>> from sympy.vector import CoordSys3D
>>> c = CoordSys3D('c', transformation='cylindrical', variable_names=("r", "theta", "z"))
>>> gradient(c.r*c.theta*c.z)
 c.theta*c.z*c.i + c.z*c.j + c.r*c.theta*c.k 

保守場與無旋場

在向量微積分中,保守場是某些標量場的梯度的場。保守場具有其沿任意路徑的線積分僅依賴於端點,並且與所走路徑無關的特性。保守向量場也被稱為‘無旋場’,因為保守場的旋度始終為零。

在物理學中,保守場代表在能量守恆的物理系統中的力。

要檢查在 sympy.vector 中向量場是否為保守場,可以使用 is_conservative 函式。

>>> from sympy.vector import CoordSys3D, is_conservative
>>> R = CoordSys3D('R')
>>> field = R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
>>> is_conservative(field)
True
>>> curl(field)
0 

另一方面,一個無旋場是一個向量場,在空間中所有點的散度都為零。

要檢查在 sympy.vector 中向量場是否為無旋場,可以使用 is_solenoidal 函式。

>>> from sympy.vector import CoordSys3D, is_solenoidal
>>> R = CoordSys3D('R')
>>> field = R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
>>> is_solenoidal(field)
True
>>> divergence(field)
0 

標量勢函式

我們先前提到,每個保守場可以定義為某些標量場的梯度。這個標量場也稱為與前述保守場對應的‘標量勢場’。

sympy.vector 中的 scalar_potential 函式計算給定三維空間中保守向量場對應的標量勢場 - 當然要減去額外的積分常數。

使用示例 -

>>> from sympy.vector import CoordSys3D, scalar_potential
>>> R = CoordSys3D('R')
>>> conservative_field = 4*R.x*R.y*R.z*R.i + 2*R.x**2*R.z*R.j + 2*R.x**2*R.y*R.k
>>> scalar_potential(conservative_field, R)
2*R.x**2*R.y*R.z 

將非保守向量場作為引數提供給 scalar_potential 會引發 ValueError

與保守向量場對應的標量勢差,或簡稱為“勢差”,可以定義為其標量勢函式在空間中兩點處值的差異。這在計算與保守函式相關的線積分中非常有用,因為它僅取決於路徑的端點。

sympy.vector 中,這種計算是如何執行的。

>>> from sympy.vector import CoordSys3D, Point
>>> from sympy.vector import scalar_potential_difference
>>> R = CoordSys3D('R')
>>> P = R.origin.locate_new('P', 1*R.i + 2*R.j + 3*R.k)
>>> vectfield = 4*R.x*R.y*R.i + 2*R.x**2*R.j
>>> scalar_potential_difference(vectfield, R, R.origin, P)
4 

如果提供的是標量表示式而不是向量場,則 scalar_potential_difference 返回空間中兩個給定點處標量場值的差異。

使用範例

原文連結:docs.sympy.org/latest/modules/vector/examples.html

本節詳細說明了使用 sympy.vector 包解決向量數學/微積分中的兩個基本問題。

四邊形問題

問題

OABC 是三維空間中的任意四邊形。P 是 OA 的中點,Q 是 AB 的中點,R 是 BC 的中點,S 是 OC 的中點。證明 PQ 平行於 SR

解決方案

此問題的解決方法展示了Point的使用,以及Vector的基本操作。

定義一個座標系

>>> from sympy.vector import CoordSys3D
>>> Sys = CoordSys3D('Sys') 

將點 O 定義為 Sys 的原點。我們可以毫不失誤地這樣做。

>>> O = Sys.origin 

以 O 為基礎定義點 A

>>> from sympy import symbols
>>> a1, a2, a3 = symbols('a1 a2 a3')
>>> A = O.locate_new('A', a1*Sys.i + a2*Sys.j + a3*Sys.k) 

同樣根據問題定義點 B 和 C

>>> b1, b2, b3 = symbols('b1 b2 b3')
>>> B = O.locate_new('B', b1*Sys.i + b2*Sys.j + b3*Sys.k)
>>> c1, c2, c3 = symbols('c1 c2 c3')
>>> C = O.locate_new('C', c1*Sys.i + c2*Sys.j + c3*Sys.k) 

P 是 OA 的中點。讓我們相對於 O 定位它(你也可以相對於 A 定義它)。

>>> P = O.locate_new('P', A.position_wrt(O) + (O.position_wrt(A) / 2)) 

同樣根據問題定義點 Q、R 和 S。

>>> Q = A.locate_new('Q', B.position_wrt(A) / 2)
>>> R = B.locate_new('R', C.position_wrt(B) / 2)
>>> S = O.locate_new('R', C.position_wrt(O) / 2) 

現在計算以 PQ 和 SR 指定的方向的向量。

>>> PQ = Q.position_wrt(P)
>>> SR = R.position_wrt(S) 

計算叉乘

>>> PQ.cross(SR)
0 

由於叉乘是零向量,所以這兩個向量必須是平行的,從而證明 PQ || SR。

Del 運算子的第三個乘積法則

看見

[WikiDel]

en.wikipedia.org/wiki/Del

問題

證明第三條規則 - (\nabla \cdot (f \vec v) = f (\nabla \cdot \vec v) + \vec v \cdot (\nabla f))

解決方案

從一個座標系開始

>>> from sympy.vector import CoordSys3D, Del
>>> delop = Del()
>>> C = CoordSys3D('C') 

標量場 (f) 和向量場 (\vec v) 的測量數都是一般座標系統的座標變數的函式。因此,以這種方式定義 SymPy 函式。

>>> from sympy import symbols, Function
>>> v1, v2, v3, f = symbols('v1 v2 v3 f', cls=Function) 

v1v2v3 分別是向量場的 (X)、(Y) 和 (Z) 分量。

將向量場定義為vfield,標量場定義為sfield

>>> vfield = v1(C.x, C.y, C.z)*C.i + v2(C.x, C.y, C.z)*C.j + v3(C.x, C.y, C.z)*C.k
>>> ffield = f(C.x, C.y, C.z) 

使用 Del() 構建方程左側的表示式。

>>> lhs = (delop.dot(ffield * vfield)).doit() 

同樣,RHS 也將被定義。

>>> rhs = ((vfield.dot(delop(ffield))) + (ffield * (delop.dot(vfield)))).doit() 

現在,為了證明乘積法則,我們只需要使左手邊和右手邊的展開和簡化版本相等,這樣 SymPy 表示式就匹配了。

>>> lhs.expand().simplify() == rhs.expand().doit().simplify()
True 

因此,可以使用 sympy.vector 來證明上述第三個乘積法則的一般形式。

相關文章