SymPy-1-13-中文文档-十五-
SymPy 1.13 中文文档(十五)
物理
原文:
docs.sympy.org/latest/reference/public/physics/index.html
一个帮助解决物理问题的模块。
目录
-
氢波函数
-
矩阵
-
泡利代数
-
一维量子谐振子
-
三维量子谐振子
-
二次量子化
-
Wigner 符号
-
单位系统
-
单位系统背后的哲学
-
更多例子
-
维度与维度系统
-
单位前缀
-
单位与单位系统
-
物理量
-
-
高能物理
-
物理向量模块
-
向量与参考框架
-
向量:运动学
-
物理/向量模块的潜在问题/高级主题/未来功能
-
标量和向量场功能
-
物理向量 API
-
基础课程
-
运动学(文档字符串)
-
打印(文档字符串)
-
基本函数(文档字符串)
-
基本场函数的文档字符串
-
-
-
经典力学
-
物理/力学中的质量、惯性、粒子和刚体
-
凯恩力学中的方法
-
拉格朗日力学中的方法
-
物理/力学中的关节框架
-
物理/力学中的符号系统
-
物理/力学中的线性化
- 非最小坐标摆
-
物理/力学示例
-
滚动盘
-
使用 Kane 方法的滚动盘
-
滚动盘,使用 Kane 方法和约束力
-
使用 Lagrange 方法的滚动盘
-
-
自行车
-
非最小坐标摆
-
多自由度完整系统
-
四杆连杆
-
-
物理/力学中的潜在问题/高级主题/未来特性
-
物理/力学参考
-
Autolev 解析器
-
SymPy 力学对 Autolev 用户
-
力学 API 参考
-
物体、惯性、载荷及其他函数(文档字符串)
-
Kane 方法与 Lagrange 方法(文档字符串)
-
关节框架(文档字符串)
-
系统(文档字符串)
-
线性化(文档字符串)
-
表达式操作(文档字符串)
-
打印(文档字符串)
-
路径(文档字符串)
-
致动器(文档字符串)
-
包装几何(文档字符串)
-
已弃用类(文档字符串)
-
-
-
生物力学
-
生物力学 API 参考
-
肌腱肌腱(文档字符串)
-
激活(文档字符串)
-
曲线(文档字符串)
-
-
-
量子力学
-
反对易子
-
Clebsch-Gordan 系数
-
对易子
-
常数
-
达格尔算符
-
内积
-
张量积
-
笛卡尔算符和态
-
希尔伯特空间
-
算符
-
算符/态辅助函数
-
Qapply
-
表示
-
自旋
-
状态
-
电路绘图
-
门
-
格罗弗算法
-
傅里叶变换
-
量子比特
-
肖尔算法
-
盒中的粒子
-
-
光学模块
-
高斯光学
-
介质
-
偏振
-
实用工具
-
波
-
-
控制模块
-
控制
-
控制 API
-
控制系统图
-
-
连续介质力学
-
梁(文档字符串)
-
使用奇异函数解决梁弯曲问题
-
桁架(文档字符串)
-
电缆(文档字符串)
-
氢波函数
sympy.physics.hydrogen.E_nl(n, Z=1)
返回状态 (n, l) 的能量,以 Hartree 原子单位表示。
能量不依赖于“l”。
参数:
n : 整数
主量子数,是一个整数,可能的取值为 1, 2, 3, 4,…
Z :
原子序数(氢为 1,氦为 2,…)
示例
>>> from sympy.physics.hydrogen import E_nl
>>> from sympy.abc import n, Z
>>> E_nl(n, Z)
-Z**2/(2*n**2)
>>> E_nl(1)
-1/2
>>> E_nl(2)
-1/8
>>> E_nl(3)
-1/18
>>> E_nl(3, 47)
-2209/18
sympy.physics.hydrogen.E_nl_dirac(n, l, spin_up=True, Z=1, c=137.035999037000)
返回状态(n, l, 自旋)的相对论能量,以 Hartree 原子单位表示。
能量是通过狄拉克方程计算的。未包括静止质能。
参数:
n : 整数
主量子数,是一个整数,可能的取值为 1, 2, 3, 4,…
l : 整数
l
是角动量量子数,其取值范围从 0 到n-1
。
spin_up :
如果电子自旋为向上(默认),则为真;否则为向下。
Z :
原子序数(氢为 1,氦为 2,…)
c :
光速,以原子单位表示。默认值为 137.035999037,取自
arxiv.org/abs/1012.3627
示例
>>> from sympy.physics.hydrogen import E_nl_dirac
>>> E_nl_dirac(1, 0)
-0.500006656595360
>>> E_nl_dirac(2, 0)
-0.125002080189006
>>> E_nl_dirac(2, 1)
-0.125000416028342
>>> E_nl_dirac(2, 1, False)
-0.125002080189006
>>> E_nl_dirac(3, 0)
-0.0555562951740285
>>> E_nl_dirac(3, 1)
-0.0555558020932949
>>> E_nl_dirac(3, 1, False)
-0.0555562951740285
>>> E_nl_dirac(3, 2)
-0.0555556377366884
>>> E_nl_dirac(3, 2, False)
-0.0555558020932949
sympy.physics.hydrogen.Psi_nlm(n, l, m, r, phi, theta, Z=1)
返回氢波函数 psi_{nlm}。它是径向波函数 R_{nl} 和球谐函数 Y_{l}^{m} 的乘积。
参数:
n : 整数
主量子数,是一个整数,可能的取值为 1, 2, 3, 4,…
l : 整数
l
是角动量量子数,其取值范围从 0 到n-1
。
m : 整数
m
是磁量子数,其取值范围从-l
到l
。
r :
径向坐标
phi :
方位角
theta :
极角
Z :
原子序数(氢为 1,氦为 2,…)
所有单位均为 Hartree 原子单位。
示例
>>> from sympy.physics.hydrogen import Psi_nlm
>>> from sympy import Symbol
>>> r=Symbol("r", positive=True)
>>> phi=Symbol("phi", real=True)
>>> theta=Symbol("theta", real=True)
>>> Z=Symbol("Z", positive=True, integer=True, nonzero=True)
>>> Psi_nlm(1,0,0,r,phi,theta,Z)
Z**(3/2)*exp(-Z*r)/sqrt(pi)
>>> Psi_nlm(2,1,1,r,phi,theta,Z)
-Z**(5/2)*r*exp(I*phi)*exp(-Z*r/2)*sin(theta)/(8*sqrt(pi))
对氢波函数 psi_{nlm} 的绝对平方积分得到 1。
氢波函数 Psi_nlm 的归一化为:
>>> from sympy import integrate, conjugate, pi, oo, sin
>>> wf=Psi_nlm(2,1,1,r,phi,theta,Z)
>>> abs_sqrd=wf*conjugate(wf)
>>> jacobi=r**2*sin(theta)
>>> integrate(abs_sqrd*jacobi, (r,0,oo), (phi,0,2*pi), (theta,0,pi))
1
sympy.physics.hydrogen.R_nl(n, l, r, Z=1)
返回氢原子径向波函数 R_{nl}。
参数:
n : 整数
主量子数,是一个整数,可能的取值为 1, 2, 3, 4,…
l : 整数
l
是角动量量子数,其取值范围从 0 到n-1
。
r :
径向坐标。
Z :
原子序数(氢为 1,氦为 2,…)
所有单位均为 Hartree 原子单位。
示例
>>> from sympy.physics.hydrogen import R_nl
>>> from sympy.abc import r, Z
>>> R_nl(1, 0, r, Z)
2*sqrt(Z**3)*exp(-Z*r)
>>> R_nl(2, 0, r, Z)
sqrt(2)*(-Z*r + 2)*sqrt(Z**3)*exp(-Z*r/2)/4
>>> R_nl(2, 1, r, Z)
sqrt(6)*Z*r*sqrt(Z**3)*exp(-Z*r/2)/12
对于氢原子,你可以使用 Z=1 的默认值:
>>> R_nl(1, 0, r)
2*exp(-r)
>>> R_nl(2, 0, r)
sqrt(2)*(2 - r)*exp(-r/2)/4
>>> R_nl(3, 0, r)
2*sqrt(3)*(2*r**2/9 - 2*r + 3)*exp(-r/3)/27
对于银原子,你可以使用 Z=47:
>>> R_nl(1, 0, r, Z=47)
94*sqrt(47)*exp(-47*r)
>>> R_nl(2, 0, r, Z=47)
47*sqrt(94)*(2 - 47*r)*exp(-47*r/2)/4
>>> R_nl(3, 0, r, Z=47)
94*sqrt(141)*(4418*r**2/9 - 94*r + 3)*exp(-47*r/3)/27
径向波函数的归一化为:
>>> from sympy import integrate, oo
>>> integrate(R_nl(1, 0, r)**2 * r**2, (r, 0, oo))
1
>>> integrate(R_nl(2, 0, r)**2 * r**2, (r, 0, oo))
1
>>> integrate(R_nl(2, 1, r)**2 * r**2, (r, 0, oo))
1
对于任意原子序数成立:
>>> integrate(R_nl(1, 0, r, Z=2)**2 * r**2, (r, 0, oo))
1
>>> integrate(R_nl(2, 0, r, Z=3)**2 * r**2, (r, 0, oo))
1
>>> integrate(R_nl(2, 1, r, Z=4)**2 * r**2, (r, 0, oo))
1
矩阵
与物理相关的已知矩阵
sympy.physics.matrices.mdft(n)
自版本 1.9 起弃用:请改用 sympy.matrices.expressions.fourier 中的 DFT。
要获得与 mdft(n)
相同的行为,请使用 DFT(n).as_explicit()
。
sympy.physics.matrices.mgamma(mu, lower=False)
返回标准(Dirac)表示中的 Dirac 伽马矩阵 (\gamma^\mu)。
解释
如果你想要 (\gamma_\mu),使用 gamma(mu, True)
。
我们使用一个约定:
(\gamma⁵ = i \cdot \gamma⁰ \cdot \gamma¹ \cdot \gamma² \cdot \gamma³)
(\gamma_5 = i \cdot \gamma_0 \cdot \gamma_1 \cdot \gamma_2 \cdot \gamma_3 = - \gamma⁵)
示例
>>> from sympy.physics.matrices import mgamma
>>> mgamma(1)
Matrix([
[ 0, 0, 0, 1],
[ 0, 0, 1, 0],
[ 0, -1, 0, 0],
[-1, 0, 0, 0]])
参考文献
[R737]
en.wikipedia.org/wiki/Gamma_matrices
sympy.physics.matrices.msigma(i)
返回具有 (i=1,2,3) 的 Pauli 矩阵 (\sigma_i)。
示例
>>> from sympy.physics.matrices import msigma
>>> msigma(1)
Matrix([
[0, 1],
[1, 0]])
参考文献
[R738]
en.wikipedia.org/wiki/Pauli_matrices
sympy.physics.matrices.pat_matrix(m, dx, dy, dz)
返回平行轴定理矩阵,以便将惯性矩阵沿 ((dx, dy, dz)) 距离转换为质量为 m 的物体。
示例
要将质量为 2 单位的物体沿 (x)-轴移动 1 单位的距离进行翻译,我们得到:
>>> from sympy.physics.matrices import pat_matrix
>>> pat_matrix(2, 1, 0, 0)
Matrix([
[0, 0, 0],
[0, 2, 0],
[0, 0, 2]])
Pauli 代数
该模块通过子类化符号实现了Pauli 代数。仅使用了 Pauli 矩阵的代数性质(我们不使用 Matrix 类)。
请参阅 Pauli 类的文档获取示例。
参考资料
[R748]
en.wikipedia.org/wiki/Pauli_matrices
sympy.physics.paulialgebra.evaluate_pauli_product(arg)
帮助函数,用于评估与符号对象的 Pauli 矩阵乘积。
参数:
arg: 包含 Pauli 矩阵的符号表达式
示例
>>> from sympy.physics.paulialgebra import Pauli, evaluate_pauli_product
>>> from sympy import I
>>> evaluate_pauli_product(I*Pauli(1)*Pauli(2))
-sigma3
>>> from sympy.abc import x
>>> evaluate_pauli_product(x**2*Pauli(2)*Pauli(1))
-I*x**2*sigma3
一维量子谐振子
sympy.physics.qho_1d.E_n(n, omega)
返回一维谐振子的能量。
参数:
n:
“节点”量子数。
omega:
谐振子的角频率。
注意
返回值的单位与 hw 的单位匹配,因为能量的计算为:
E_n = hbar * omega*(n + 1/2)
示例
>>> from sympy.physics.qho_1d import E_n
>>> from sympy.abc import x, omega
>>> E_n(x, omega)
hbar*omega*(x + 1/2)
sympy.physics.qho_1d.coherent_state(n, alpha)
返回 1D 谐振子相干态的 <n|alpha>。参见 en.wikipedia.org/wiki/Coherent_states
参数:
n:
“节点”量子数。
alpha:
湮灭算符的本征值。
sympy.physics.qho_1d.psi_n(n, x, m, omega)
返回一维谐振子的波函数 psi_{n}。
参数:
n:
“节点”量子数。对应于波函数中的节点数。
n >= 0
x:
x 坐标。
m:
粒子的质量。
omega:
振子的角频率。
示例
>>> from sympy.physics.qho_1d import psi_n
>>> from sympy.abc import m, x, omega
>>> psi_n(0, x, m, omega)
(m*omega)**(1/4)*exp(-m*omega*x**2/(2*hbar))/(hbar**(1/4)*pi**(1/4))
三维量子谐振子
sympy.physics.sho.E_nl(n, l, hw)
返回各向同性谐振子的能量。
参数:
n:
"节点"量子数。
l:
轨道角动量。
hw:
谐振子参数。
注意事项
返回值的单位与hw
的单位相匹配,因为能量计算公式为:
( E_{nl} = (2n + l + \frac{3}{2}) \cdot hw )
示例
>>> from sympy.physics.sho import E_nl
>>> from sympy import symbols
>>> x, y, z = symbols('x, y, z')
>>> E_nl(x, y, z)
z*(2*x + y + 3/2)
sympy.physics.sho.R_nl(n, l, nu, r)
返回三维各向同性谐振子的径向波函数 ( R_{nl} ) 。
参数:
n:
"节点"量子数。对应于波函数中的节点数。
n >= 0
l:
轨道角动量的量子数。
nu:
质量标度频率:( \nu = \frac{m \cdot \omega}{2 \cdot \hbar} ),其中 ( m ) 是质量, ( \omega ) 是振荡器的频率。(在原子单位中, ( \nu == \frac{\omega}{2} ) )
r:
径向坐标。
示例
>>> from sympy.physics.sho import R_nl
>>> from sympy.abc import r, nu, l
>>> R_nl(0, 0, 1, r)
2*2**(3/4)*exp(-r**2)/pi**(1/4)
>>> R_nl(1, 0, 1, r)
4*2**(1/4)*sqrt(3)*(3/2 - 2*r**2)*exp(-r**2)/(3*pi**(1/4))
l
、nu
和 r
可能是符号变量:
>>> R_nl(0, 0, nu, r)
2*2**(3/4)*sqrt(nu**(3/2))*exp(-nu*r**2)/pi**(1/4)
>>> R_nl(0, l, 1, r)
r**l*sqrt(2**(l + 3/2)*2**(l + 2)/factorial2(2*l + 1))*exp(-r**2)/pi**(1/4)
径向波函数的归一化为:
>>> from sympy import Integral, oo
>>> Integral(R_nl(0, 0, 1, r)**2*r**2, (r, 0, oo)).n()
1.00000000000000
>>> Integral(R_nl(1, 0, 1, r)**2*r**2, (r, 0, oo)).n()
1.00000000000000
>>> Integral(R_nl(1, 1, 1, r)**2*r**2, (r, 0, oo)).n()
1.00000000000000
二次量子化
玻色子的二次量子化算符和状态。
这遵循费特和韦勒克的《多粒子系统的量子理论》的表述。
class sympy.physics.secondquant.AnnihilateBoson(k)
玻色子湮灭算符。
Examples
>>> from sympy.physics.secondquant import B
>>> from sympy.abc import x
>>> B(x)
AnnihilateBoson(x)
apply_operator(state)
如果 self 不是符号化的且 state 是 FockStateKet,则将 state 应用于 self,否则将 self 乘以 state。
Examples
>>> from sympy.physics.secondquant import B, BKet
>>> from sympy.abc import x, y, n
>>> B(x).apply_operator(y)
y*AnnihilateBoson(x)
>>> B(0).apply_operator(BKet((n,)))
sqrt(n)*FockStateBosonKet((n - 1,))
class sympy.physics.secondquant.AnnihilateFermion(k)
费米子湮灭算符。
apply_operator(state)
如果 self 不是符号化的且 state 是 FockStateKet,则将 state 应用于 self,否则将 self 乘以 state。
Examples
>>> from sympy.physics.secondquant import B, Dagger, BKet
>>> from sympy.abc import x, y, n
>>> Dagger(B(x)).apply_operator(y)
y*CreateBoson(x)
>>> B(0).apply_operator(BKet((n,)))
sqrt(n)*FockStateBosonKet((n - 1,))
property is_only_q_annihilator
总是销毁一个准粒子吗?(湮灭空穴或湮灭粒子)
Examples
>>> from sympy import Symbol
>>> from sympy.physics.secondquant import F
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> F(a).is_only_q_annihilator
True
>>> F(i).is_only_q_annihilator
False
>>> F(p).is_only_q_annihilator
False
property is_only_q_creator
总是创建一个准粒子吗?(创建空穴或创建粒子)
Examples
>>> from sympy import Symbol
>>> from sympy.physics.secondquant import F
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> F(a).is_only_q_creator
False
>>> F(i).is_only_q_creator
True
>>> F(p).is_only_q_creator
False
property is_q_annihilator
我们能够销毁一个准粒子吗?(湮灭空穴或湮灭粒子)如果可以,那么这会在费米面之上还是之下?
Examples
>>> from sympy import Symbol
>>> from sympy.physics.secondquant import F
>>> a = Symbol('a', above_fermi=1)
>>> i = Symbol('i', below_fermi=1)
>>> p = Symbol('p')
>>> F(a).is_q_annihilator
1
>>> F(i).is_q_annihilator
0
>>> F(p).is_q_annihilator
1
property is_q_creator
我们能够创建一个准粒子吗?(创建空穴或创建粒子)如果可以,那么这会在费米面之上还是之下?
Examples
>>> from sympy import Symbol
>>> from sympy.physics.secondquant import F
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> F(a).is_q_creator
0
>>> F(i).is_q_creator
-1
>>> F(p).is_q_creator
-1
class sympy.physics.secondquant.AntiSymmetricTensor(symbol, upper, lower)
将上下标存储在单独的 Tuple 中。
每组指标假定为反对称。
Examples
>>> from sympy import symbols
>>> from sympy.physics.secondquant import AntiSymmetricTensor
>>> i, j = symbols('i j', below_fermi=True)
>>> a, b = symbols('a b', above_fermi=True)
>>> AntiSymmetricTensor('v', (a, i), (b, j))
AntiSymmetricTensor(v, (a, i), (b, j))
>>> AntiSymmetricTensor('v', (i, a), (b, j))
-AntiSymmetricTensor(v, (a, i), (b, j))
如您所见,指标会自动排序为规范形式。
property lower
返回较低的指标。
Examples
>>> from sympy import symbols
>>> from sympy.physics.secondquant import AntiSymmetricTensor
>>> i, j = symbols('i,j', below_fermi=True)
>>> a, b = symbols('a,b', above_fermi=True)
>>> AntiSymmetricTensor('v', (a, i), (b, j))
AntiSymmetricTensor(v, (a, i), (b, j))
>>> AntiSymmetricTensor('v', (a, i), (b, j)).lower
(b, j)
property symbol
返回张量的符号。
Examples
>>> from sympy import symbols
>>> from sympy.physics.secondquant import AntiSymmetricTensor
>>> i, j = symbols('i,j', below_fermi=True)
>>> a, b = symbols('a,b', above_fermi=True)
>>> AntiSymmetricTensor('v', (a, i), (b, j))
AntiSymmetricTensor(v, (a, i), (b, j))
>>> AntiSymmetricTensor('v', (a, i), (b, j)).symbol
v
property upper
返回较高的指标。
Examples
>>> from sympy import symbols
>>> from sympy.physics.secondquant import AntiSymmetricTensor
>>> i, j = symbols('i,j', below_fermi=True)
>>> a, b = symbols('a,b', above_fermi=True)
>>> AntiSymmetricTensor('v', (a, i), (b, j))
AntiSymmetricTensor(v, (a, i), (b, j))
>>> AntiSymmetricTensor('v', (a, i), (b, j)).upper
(a, i)
sympy.physics.secondquant.B
别名为AnnihilateBoson
sympy.physics.secondquant.BBra
别名为FockStateBosonBra
sympy.physics.secondquant.BKet
别名为FockStateBosonKet
sympy.physics.secondquant.Bd
别名为CreateBoson
class sympy.physics.secondquant.BosonicBasis
玻色子 Fock 态基础集合的基类。
class sympy.physics.secondquant.Commutator(a, b)
交换子:[A, B] = AB - BA
根据.cmp()对参数进行排序。
Examples
>>> from sympy import symbols
>>> from sympy.physics.secondquant import Commutator
>>> A, B = symbols('A,B', commutative=False)
>>> Commutator(B, A)
-Commutator(A, B)
使用.doit()评估交换子。
>>> comm = Commutator(A,B); comm
Commutator(A, B)
>>> comm.doit()
A*B - B*A
对于两个二次量子化算符,交换子立即计算:
>>> from sympy.physics.secondquant import Fd, F
>>> a = symbols('a', above_fermi=True)
>>> i = symbols('i', below_fermi=True)
>>> p,q = symbols('p,q')
>>> Commutator(Fd(a),Fd(i))
2*NO(CreateFermion(a)*CreateFermion(i))
但对于更复杂的表达式,通过调用.doit()来触发评估。
>>> comm = Commutator(Fd(p)*Fd(q),F(i)); comm
Commutator(CreateFermion(p)*CreateFermion(q), AnnihilateFermion(i))
>>> comm.doit(wicks=True)
-KroneckerDelta(i, p)*CreateFermion(q) +
KroneckerDelta(i, q)*CreateFermion(p)
doit(**hints)
启用计算复杂表达式。
Examples
>>> from sympy.physics.secondquant import Commutator, F, Fd
>>> from sympy import symbols
>>> i, j = symbols('i,j', below_fermi=True)
>>> a, b = symbols('a,b', above_fermi=True)
>>> c = Commutator(Fd(a)*F(i),Fd(b)*F(j))
>>> c.doit(wicks=True)
0
classmethod eval(a, b)
交换子[A, B]在 A < B 时处于规范形式。
Examples
>>> from sympy.physics.secondquant import Commutator, F, Fd
>>> from sympy.abc import x
>>> c1 = Commutator(F(x), Fd(x))
>>> c2 = Commutator(Fd(x), F(x))
>>> Commutator.eval(c1, c2)
0
class sympy.physics.secondquant.CreateBoson(k)
玻色子产生算符。
apply_operator(state)
如果 self 不是符号化的且 state 是 FockStateKet,则将 state 应用于 self,否则将 self 乘以 state。
Examples
>>> from sympy.physics.secondquant import B, Dagger, BKet
>>> from sympy.abc import x, y, n
>>> Dagger(B(x)).apply_operator(y)
y*CreateBoson(x)
>>> B(0).apply_operator(BKet((n,)))
sqrt(n)*FockStateBosonKet((n - 1,))
class sympy.physics.secondquant.CreateFermion(k)
费米子产生算符。
apply_operator(state)
如果 self 不是符号化的且 state 是 FockStateKet,则将 state 应用于 self,否则将 self 乘以 state。
Examples
>>> from sympy.physics.secondquant import B, Dagger, BKet
>>> from sympy.abc import x, y, n
>>> Dagger(B(x)).apply_operator(y)
y*CreateBoson(x)
>>> B(0).apply_operator(BKet((n,)))
sqrt(n)*FockStateBosonKet((n - 1,))
property is_only_q_annihilator
总是销毁一个准粒子吗?(湮灭空穴或湮灭粒子)
Examples
>>> from sympy import Symbol
>>> from sympy.physics.secondquant import Fd
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> Fd(a).is_only_q_annihilator
False
>>> Fd(i).is_only_q_annihilator
True
>>> Fd(p).is_only_q_annihilator
False
property is_only_q_creator
总是创建一个准粒子吗?(创建空穴或创建粒子)
Examples
>>> from sympy import Symbol
>>> from sympy.physics.secondquant import Fd
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> Fd(a).is_only_q_creator
True
>>> Fd(i).is_only_q_creator
False
>>> Fd(p).is_only_q_creator
False
property is_q_annihilator
我们能够销毁一个准粒子吗?(湮灭空穴或湮灭粒子)如果可以,那么这会在费米面之上还是之下?
Examples
>>> from sympy import Symbol
>>> from sympy.physics.secondquant import Fd
>>> a = Symbol('a', above_fermi=1)
>>> i = Symbol('i', below_fermi=1)
>>> p = Symbol('p')
>>> Fd(a).is_q_annihilator
0
>>> Fd(i).is_q_annihilator
-1
>>> Fd(p).is_q_annihilator
-1
property is_q_creator
我们能够创建一个准粒子吗?(创建空穴或创建粒子)如果可以,那么这会在费米面之上还是之下?
Examples
>>> from sympy import Symbol
>>> from sympy.physics.secondquant import Fd
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> Fd(a).is_q_creator
1
>>> Fd(i).is_q_creator
0
>>> Fd(p).is_q_creator
1
class sympy.physics.secondquant.Dagger(arg)
创建/湮灭算符的厄米共轭。
示例。
>>> from sympy import I
>>> from sympy.physics.secondquant import Dagger, B, Bd
>>> Dagger(2*I)
-2*I
>>> Dagger(B(0))
CreateBoson(0)
>>> Dagger(Bd(0))
AnnihilateBoson(0)
classmethod eval(arg)
评估 Dagger 实例。
示例。
>>> from sympy import I
>>> from sympy.physics.secondquant import Dagger, B, Bd
>>> Dagger(2*I)
-2*I
>>> Dagger(B(0))
CreateBoson(0)
>>> Dagger(Bd(0))
AnnihilateBoson(0)
自动调用 eval() 方法。
sympy.physics.secondquant.F
AnnihilateFermion
的别名。
sympy.physics.secondquant.FBra
FockStateFermionBra
的别名。
sympy.physics.secondquant.FKet
FockStateFermionKet
的别名。
sympy.physics.secondquant.Fd
CreateFermion
的别名。
class sympy.physics.secondquant.FixedBosonicBasis(n_particles, n_levels)
固定粒子数的基组。
示例。
>>> from sympy.physics.secondquant import FixedBosonicBasis
>>> b = FixedBosonicBasis(2, 2)
>>> state = b.state(1)
>>> b
[FockState((2, 0)), FockState((1, 1)), FockState((0, 2))]
>>> state
FockStateBosonKet((1, 1))
>>> b.index(state)
1
index(state)
返回基础中状态的索引。
示例。
>>> from sympy.physics.secondquant import FixedBosonicBasis
>>> b = FixedBosonicBasis(2, 3)
>>> b.index(b.state(3))
3
state(i)
返回在基础中索引为 i 的态。
示例。
>>> from sympy.physics.secondquant import FixedBosonicBasis
>>> b = FixedBosonicBasis(2, 3)
>>> b.state(3)
FockStateBosonKet((1, 0, 1))
class sympy.physics.secondquant.FockState(occupations)
具有一系列占据数的多粒子 Fock 态。
在任何可以有 FockState 的地方,也可以有 S.Zero。所有代码必须检查这一点!
代表 FockStates 的基类。
class sympy.physics.secondquant.FockStateBosonBra(occupations)
描述了一组 BosonBra 粒子。
示例。
>>> from sympy.physics.secondquant import BBra
>>> BBra([1, 2])
FockStateBosonBra((1, 2))
class sympy.physics.secondquant.FockStateBosonKet(occupations)
具有一系列占据数的多粒子 Fock 态。
占据数可以是任何大于等于 0 的整数。
示例。
>>> from sympy.physics.secondquant import BKet
>>> BKet([1, 2])
FockStateBosonKet((1, 2))
class sympy.physics.secondquant.FockStateBra(occupations)
左矢的表示。
class sympy.physics.secondquant.FockStateFermionBra(occupations, fermi_level=0)
示例。
>>> from sympy.physics.secondquant import FBra
>>> FBra([1, 2])
FockStateFermionBra((1, 2))
另请参见。
FockStateFermionKet
class sympy.physics.secondquant.FockStateFermionKet(occupations, fermi_level=0)
具有一系列占据轨道的多粒子 Fock 态。
解释。
每个状态只能有一个粒子,因此我们选择存储一组占据轨道而不是具有占据数(零和一)的元组。
费米面以下的态被称为空穴,并且在占据列表中用负标签表示。
对于符号态标签,费米面限制了允许的空穴态数。
示例。
>>> from sympy.physics.secondquant import FKet
>>> FKet([1, 2])
FockStateFermionKet((1, 2))
class sympy.physics.secondquant.FockStateKet(occupations)
右矢的表示。
class sympy.physics.secondquant.InnerProduct(bra, ket)
一个未评估的左矢和右矢之间的内积。
解释。
目前该类只将事物简化为 Kronecker Delta 的乘积。将来,我们可以引入像 |a>
和 |b>
这样的抽象态,并将内积保持为未评估状态 <a|b>
。
property bra
返回态的左矢部分。
property ket
返回态的右矢部分。
class sympy.physics.secondquant.KroneckerDelta(i, j, delta_range=None)
离散或 Kronecker Delta 函数。
参数:
i:数字,符号
Delta 函数的第一个索引。
j:数字,符号
Delta 函数的第二个索引。
解释。
一个函数,接受两个整数 (i) 和 (j)。如果 (i) 和 (j) 不相等,则返回 (0),如果相等,则返回 (1)。
示例。
具有整数索引的示例:
>>> from sympy import KroneckerDelta
>>> KroneckerDelta(1, 2)
0
>>> KroneckerDelta(3, 3)
1
符号索引:
>>> from sympy.abc import i, j, k
>>> KroneckerDelta(i, j)
KroneckerDelta(i, j)
>>> KroneckerDelta(i, i)
1
>>> KroneckerDelta(i, i + 1)
0
>>> KroneckerDelta(i, i + 1 + k)
KroneckerDelta(i, i + k + 1)
另请参见。
eval
,DiracDelta
参考文献。
[R771]
en.wikipedia.org/wiki/Kronecker_delta
classmethod eval(i, j, delta_range=None)
评估离散 Delta 函数。
示例。
>>> from sympy import KroneckerDelta
>>> from sympy.abc import i, j, k
>>> KroneckerDelta(i, j)
KroneckerDelta(i, j)
>>> KroneckerDelta(i, i)
1
>>> KroneckerDelta(i, i + 1)
0
>>> KroneckerDelta(i, i + 1 + k)
KroneckerDelta(i, i + k + 1)
间接的 doctest。
property indices_contain_equal_information
返回 True,如果指标要么都在费米能级上,要么都在费米能级下。
示例
>>> from sympy import KroneckerDelta, Symbol
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> q = Symbol('q')
>>> KroneckerDelta(p, q).indices_contain_equal_information
True
>>> KroneckerDelta(p, q+1).indices_contain_equal_information
True
>>> KroneckerDelta(i, p).indices_contain_equal_information
False
property is_above_fermi
如果 Delta 在费米能级上方可以非零,则为真。
示例
>>> from sympy import KroneckerDelta, Symbol
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> q = Symbol('q')
>>> KroneckerDelta(p, a).is_above_fermi
True
>>> KroneckerDelta(p, i).is_above_fermi
False
>>> KroneckerDelta(p, q).is_above_fermi
True
另请参阅
is_below_fermi
, is_only_below_fermi
, is_only_above_fermi
property is_below_fermi
如果 Delta 在费米能级下方可以非零,则为真。
示例
>>> from sympy import KroneckerDelta, Symbol
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> q = Symbol('q')
>>> KroneckerDelta(p, a).is_below_fermi
False
>>> KroneckerDelta(p, i).is_below_fermi
True
>>> KroneckerDelta(p, q).is_below_fermi
True
另请参阅
is_above_fermi
, is_only_above_fermi
, is_only_below_fermi
property is_only_above_fermi
如果 Delta 受限于费米能级上方,则为真。
示例
>>> from sympy import KroneckerDelta, Symbol
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> q = Symbol('q')
>>> KroneckerDelta(p, a).is_only_above_fermi
True
>>> KroneckerDelta(p, q).is_only_above_fermi
False
>>> KroneckerDelta(p, i).is_only_above_fermi
False
另请参阅
is_above_fermi
, is_below_fermi
, is_only_below_fermi
property is_only_below_fermi
如果 Delta 受限于费米能级下方,则为真。
示例
>>> from sympy import KroneckerDelta, Symbol
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> p = Symbol('p')
>>> q = Symbol('q')
>>> KroneckerDelta(p, i).is_only_below_fermi
True
>>> KroneckerDelta(p, q).is_only_below_fermi
False
>>> KroneckerDelta(p, a).is_only_below_fermi
False
另请参阅
is_above_fermi
, is_below_fermi
, is_only_above_fermi
property killable_index
返回在最终表达式中要替换的首选指标。
解释
要替换的指标是在费米能级方面具有较少信息的指标。如果指标包含相同信息,则‘a’优于‘b’。
示例
>>> from sympy import KroneckerDelta, Symbol
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> j = Symbol('j', below_fermi=True)
>>> p = Symbol('p')
>>> KroneckerDelta(p, i).killable_index
p
>>> KroneckerDelta(p, a).killable_index
p
>>> KroneckerDelta(i, j).killable_index
j
另请参阅
preferred_index
property preferred_index
返回在最终表达式中要保留的首选指标。
解释
首选指标是在费米能级方面具有更多信息的指标。如果指标包含相同信息,则‘a’优于‘b’。
示例
>>> from sympy import KroneckerDelta, Symbol
>>> a = Symbol('a', above_fermi=True)
>>> i = Symbol('i', below_fermi=True)
>>> j = Symbol('j', below_fermi=True)
>>> p = Symbol('p')
>>> KroneckerDelta(p, i).preferred_index
i
>>> KroneckerDelta(p, a).preferred_index
a
>>> KroneckerDelta(i, j).preferred_index
i
另请参阅
killable_index
class sympy.physics.secondquant.NO(arg)
该对象用于表示正规顺序括号。
即 {abcd} 有时写作 🔡
解释
对一个参数应用 NO(arg)函数意味着假设参数中的所有算符均反对易,并且具有消失的收缩。这允许在对象创建时立即重新排序为规范形式。
例子
>>> from sympy import symbols
>>> from sympy.physics.secondquant import NO, F, Fd
>>> p,q = symbols('p,q')
>>> NO(Fd(p)*F(q))
NO(CreateFermion(p)*AnnihilateFermion(q))
>>> NO(F(q)*Fd(p))
-NO(CreateFermion(p)*AnnihilateFermion(q))
注意
如果您想生成一个表达式的正规顺序等价物,则应使用 wicks()函数。此类仅指示括号内的所有算符均反对易,并具有消失的收缩。不多不少。
doit(**hints)
要么去掉括号或在其参数中启用复杂计算。
例子
>>> from sympy.physics.secondquant import NO, Fd, F
>>> from textwrap import fill
>>> from sympy import symbols, Dummy
>>> p,q = symbols('p,q', cls=Dummy)
>>> print(fill(str(NO(Fd(p)*F(q)).doit())))
KroneckerDelta(_a, _p)*KroneckerDelta(_a,
_q)*CreateFermion(_a)*AnnihilateFermion(_a) + KroneckerDelta(_a,
_p)*KroneckerDelta(_i, _q)*CreateFermion(_a)*AnnihilateFermion(_i) -
KroneckerDelta(_a, _q)*KroneckerDelta(_i,
_p)*AnnihilateFermion(_a)*CreateFermion(_i) - KroneckerDelta(_i,
_p)*KroneckerDelta(_i, _q)*AnnihilateFermion(_i)*CreateFermion(_i)
get_subNO(i)
返回在索引 i 处没有 FermionicOperator 的 NO()。
例子
>>> from sympy import symbols
>>> from sympy.physics.secondquant import F, NO
>>> p, q, r = symbols('p,q,r')
>>> NO(F(p)*F(q)*F(r)).get_subNO(1)
NO(AnnihilateFermion(p)*AnnihilateFermion(r))
property has_q_annihilators
如果第一个参数的最右边参数不是 q 湮灭算符,则返回 0,否则如果其在费米面上方则返回 1,如果在费米面下方则返回-1。
例子
>>> from sympy import symbols
>>> from sympy.physics.secondquant import NO, F, Fd
>>> a = symbols('a', above_fermi=True)
>>> i = symbols('i', below_fermi=True)
>>> NO(Fd(a)*Fd(i)).has_q_annihilators
-1
>>> NO(F(i)*F(a)).has_q_annihilators
1
>>> NO(Fd(a)*F(i)).has_q_annihilators
0
property has_q_creators
如果第一个参数的最左边参数不是 q 创造算符,则返回 0,否则如果其在费米面上方则返回 1,如果在费米面下方则返回-1。
例子
>>> from sympy import symbols
>>> from sympy.physics.secondquant import NO, F, Fd
>>> a = symbols('a', above_fermi=True)
>>> i = symbols('i', below_fermi=True)
>>> NO(Fd(a)*Fd(i)).has_q_creators
1
>>> NO(F(i)*F(a)).has_q_creators
-1
>>> NO(Fd(i)*F(a)).has_q_creators
0
iter_q_annihilators()
迭代湮灭算符。
例子
>>> from sympy import symbols
>>> i, j = symbols('i j', below_fermi=True)
>>> a, b = symbols('a b', above_fermi=True)
>>> from sympy.physics.secondquant import NO, F, Fd
>>> no = NO(Fd(a)*F(i)*F(b)*Fd(j))
>>> no.iter_q_creators()
<generator object... at 0x...>
>>> list(no.iter_q_creators())
[0, 1]
>>> list(no.iter_q_annihilators())
[3, 2]
iter_q_creators()
迭代创建算符。
例子
>>> from sympy import symbols
>>> i, j = symbols('i j', below_fermi=True)
>>> a, b = symbols('a b', above_fermi=True)
>>> from sympy.physics.secondquant import NO, F, Fd
>>> no = NO(Fd(a)*F(i)*F(b)*Fd(j))
>>> no.iter_q_creators()
<generator object... at 0x...>
>>> list(no.iter_q_creators())
[0, 1]
>>> list(no.iter_q_annihilators())
[3, 2]
class sympy.physics.secondquant.PermutationOperator(i, j)
表示指数置换算符 P(ij)。
P(ij)f(i)g(j) = f(i)g(j) - f(j)g(i)
get_permuted(expr)
返回具有置换指数的-expr。
解释
>>> from sympy import symbols, Function
>>> from sympy.physics.secondquant import PermutationOperator
>>> p,q = symbols('p,q')
>>> f = Function('f')
>>> PermutationOperator(p,q).get_permuted(f(p,q))
-f(q, p)
class sympy.physics.secondquant.VarBosonicBasis(n_max)
一个单态、变粒子数的基组。
例子
>>> from sympy.physics.secondquant import VarBosonicBasis
>>> b = VarBosonicBasis(5)
>>> b
[FockState((0,)), FockState((1,)), FockState((2,)),
FockState((3,)), FockState((4,))]
index(state)
返回基础中状态的索引。
例子
>>> from sympy.physics.secondquant import VarBosonicBasis
>>> b = VarBosonicBasis(3)
>>> state = b.state(1)
>>> b
[FockState((0,)), FockState((1,)), FockState((2,))]
>>> state
FockStateBosonKet((1,))
>>> b.index(state)
1
state(i)
单一基组的状态。
例子
>>> from sympy.physics.secondquant import VarBosonicBasis
>>> b = VarBosonicBasis(5)
>>> b.state(3)
FockStateBosonKet((3,))
sympy.physics.secondquant.apply_operators(e)
以 SymPy 表达式和算符为参数,应用这些算符。
例子
>>> from sympy.physics.secondquant import apply_operators
>>> from sympy import sympify
>>> apply_operators(sympify(3)+4)
7
sympy.physics.secondquant.contraction(a, b)
计算 Fermionic 算符 a 和 b 的收缩。
例子
>>> from sympy import symbols
>>> from sympy.physics.secondquant import F, Fd, contraction
>>> p, q = symbols('p,q')
>>> a, b = symbols('a,b', above_fermi=True)
>>> i, j = symbols('i,j', below_fermi=True)
收缩仅在准创造算符位于准湮灭算符右侧时才非零:
>>> contraction(F(a),Fd(b))
KroneckerDelta(a, b)
>>> contraction(Fd(i),F(j))
KroneckerDelta(i, j)
对于一般指标,非零结果将限制指标位于费米面以下/以上:
>>> contraction(Fd(p),F(q))
KroneckerDelta(_i, q)*KroneckerDelta(p, q)
>>> contraction(F(p),Fd(q))
KroneckerDelta(_a, q)*KroneckerDelta(p, q)
两个创建算符或两个湮灭算符总是消失的:
>>> contraction(F(p),F(q))
0
>>> contraction(Fd(p),Fd(q))
0
sympy.physics.secondquant.evaluate_deltas(e)
我们在表达式中假设按照爱因斯坦求和约定评估 KroneckerDelta 符号。
解释
如果一个指标重复,则对其求和,并实际上用另一个指标代替它。如果两个指标都重复,则根据首选指标进行替换。这由 KroneckerDelta.preferred_index 和 KroneckerDelta.killable_index 决定。
如果没有可能的替换或者替换会导致信息丢失,则不进行任何操作。
如果一个指标出现在多个 KroneckerDelta 中,则结果的替换取决于因子的顺序。由于排序依赖于平台,因此从此函数得到的文字表达可能难以预测。
例子
我们假设以下情况:
>>> from sympy import symbols, Function, Dummy, KroneckerDelta
>>> from sympy.physics.secondquant import evaluate_deltas
>>> i,j = symbols('i j', below_fermi=True, cls=Dummy)
>>> a,b = symbols('a b', above_fermi=True, cls=Dummy)
>>> p,q = symbols('p q', cls=Dummy)
>>> f = Function('f')
>>> t = Function('t')
根据 KroneckerDelta,这些指标的优先顺序是(a, b, i, j, p, q)。
简单的情况:
>>> evaluate_deltas(KroneckerDelta(i,j)*f(i)) # d_ij f(i) -> f(j)
f(_j)
>>> evaluate_deltas(KroneckerDelta(i,j)*f(j)) # d_ij f(j) -> f(i)
f(_i)
>>> evaluate_deltas(KroneckerDelta(i,p)*f(p)) # d_ip f(p) -> f(i)
f(_i)
>>> evaluate_deltas(KroneckerDelta(q,p)*f(p)) # d_qp f(p) -> f(q)
f(_q)
>>> evaluate_deltas(KroneckerDelta(q,p)*f(q)) # d_qp f(q) -> f(p)
f(_p)
更有趣的情况:
>>> evaluate_deltas(KroneckerDelta(i,p)*t(a,i)*f(p,q))
f(_i, _q)*t(_a, _i)
>>> evaluate_deltas(KroneckerDelta(a,p)*t(a,i)*f(p,q))
f(_a, _q)*t(_a, _i)
>>> evaluate_deltas(KroneckerDelta(p,q)*f(p,q))
f(_p, _p)
最后,这里有一些不做任何操作的情况,因为那将意味着信息的丢失:
>>> evaluate_deltas(KroneckerDelta(i,p)*f(q))
f(_q)*KroneckerDelta(_i, _p)
>>> evaluate_deltas(KroneckerDelta(i,p)*f(i))
f(_i)*KroneckerDelta(_i, _p)
sympy.physics.secondquant.matrix_rep(op, basis)
查找算符在基组中的表示。
例子
>>> from sympy.physics.secondquant import VarBosonicBasis, B, matrix_rep
>>> b = VarBosonicBasis(5)
>>> o = B(0)
>>> matrix_rep(o, b)
Matrix([
[0, 1, 0, 0, 0],
[0, 0, sqrt(2), 0, 0],
[0, 0, 0, sqrt(3), 0],
[0, 0, 0, 0, 2],
[0, 0, 0, 0, 0]])
sympy.physics.secondquant.simplify_index_permutations(expr, permutation_operators)
通过引入适当的置换算符来执行简化。
解释
示意性地:
[abij] - [abji] - [baij] + [baji] -> P(ab)P(ij)[abij]
permutation_operators 是要考虑的置换算符列表。
如果 permutation_operators=[P(ab),P(ij)],我们将尝试在表达式中引入排列算子 P(ij)和 P(ab)。如果还有其他可能的简化,我们将忽略它们。
>>> from sympy import symbols, Function
>>> from sympy.physics.secondquant import simplify_index_permutations
>>> from sympy.physics.secondquant import PermutationOperator
>>> p,q,r,s = symbols('p,q,r,s')
>>> f = Function('f')
>>> g = Function('g')
>>> expr = f(p)*g(q) - f(q)*g(p); expr
f(p)*g(q) - f(q)*g(p)
>>> simplify_index_permutations(expr,[PermutationOperator(p,q)])
f(p)*g(q)*PermutationOperator(p, q)
>>> PermutList = [PermutationOperator(p,q),PermutationOperator(r,s)]
>>> expr = f(p,r)*g(q,s) - f(q,r)*g(p,s) + f(q,s)*g(p,r) - f(p,s)*g(q,r)
>>> simplify_index_permutations(expr,PermutList)
f(p, r)*g(q, s)*PermutationOperator(p, q)*PermutationOperator(r, s)
sympy.physics.secondquant.substitute_dummies(expr, new_indices=False, pretty_indices={})
通过替换虚拟变量来收集项。
解释
此例程允许简化包含仅因虚拟变量而不同的项的 Add 表达式。
这个想法是根据项的结构一致地替换所有虚拟变量。对于每个项,我们获得一个所有虚拟变量的序列,其中顺序由索引范围、索引所属的因子以及其在每个因子中的位置决定。有关虚拟变量排序的更多信息,请参阅 _get_ordered_dummies()。然后在每个项中一致地进行替换。
示例
>>> from sympy import symbols, Function, Dummy
>>> from sympy.physics.secondquant import substitute_dummies
>>> a,b,c,d = symbols('a b c d', above_fermi=True, cls=Dummy)
>>> i,j = symbols('i j', below_fermi=True, cls=Dummy)
>>> f = Function('f')
>>> expr = f(a,b) + f(c,d); expr
f(_a, _b) + f(_c, _d)
由于 a、b、c 和 d 是等效的求和索引,因此表达式可以简化为单一项(其中虚拟指数仍然被求和)
>>> substitute_dummies(expr)
2*f(_a, _b)
控制输出:
默认情况下,将在表达式中已经存在的虚拟符号重新用于不同的排列。然而,如果 new_indices=True,则会生成并插入新的虚拟符号。“pretty_indices”关键字可用于控制此新符号的生成。
默认情况下,新的虚拟符号将以 i_1、i_2、a_1 等形式生成。如果您提供一个键值对字典,形式为:
这些字母将用作新虚拟符号的标签。index_groups 必须是“above”、“below”或“general”之一。
>>> expr = f(a,b,i,j)
>>> my_dummies = { 'above':'st', 'below':'uv' }
>>> substitute_dummies(expr, new_indices=True, pretty_indices=my_dummies)
f(_s, _t, _u, _v)
如果我们用完了字母,或者某些 index_group 没有关键字,则默认的虚拟生成器将作为后备:
>>> p,q = symbols('p q', cls=Dummy) # general indices
>>> expr = f(p,q)
>>> substitute_dummies(expr, new_indices=True, pretty_indices=my_dummies)
f(_p_0, _p_1)
sympy.physics.secondquant.wicks(e, **kw_args)
使用 Wick 定理返回表达式的正常排序等效物。
示例
>>> from sympy import symbols, Dummy
>>> from sympy.physics.secondquant import wicks, F, Fd
>>> p, q, r = symbols('p,q,r')
>>> wicks(Fd(p)*F(q))
KroneckerDelta(_i, q)*KroneckerDelta(p, q) + NO(CreateFermion(p)*AnnihilateFermion(q))
默认情况下,表达式被展开:
>>> wicks(F(p)*(F(q)+F(r)))
NO(AnnihilateFermion(p)*AnnihilateFermion(q)) + NO(AnnihilateFermion(p)*AnnihilateFermion(r))
使用关键字“keep_only_fully_contracted=True”,仅返回完全收缩的项。
根据请求,结果可以按以下顺序简化:
– KroneckerDelta 函数被评估 – 虚拟变量在各项中一致地替换
>>> p, q, r = symbols('p q r', cls=Dummy)
>>> wicks(Fd(p)*(F(q)+F(r)), keep_only_fully_contracted=True)
KroneckerDelta(_i, _q)*KroneckerDelta(_p, _q) + KroneckerDelta(_i, _r)*KroneckerDelta(_p, _r)
Wigner 符号
Wigner、Clebsch-Gordan、Racah 和 Gaunt 系数
集合函数用于精确计算 Wigner 3j、6j、9j、Clebsch-Gordan、Racah 以及 Gaunt 系数,所有的计算结果都是有理数乘以有理数的平方根[Rasch03]。
请参阅个别函数的描述以获取更多详细信息和示例。
参考文献
[Regge58] (1,2)
‘Clebsch-Gordan 系数的对称性质’, T. Regge, Nuovo Cimento, 卷 10, pp. 544 (1958)
[Regge59]
‘Racah 系数的对称性质’, T. Regge, Nuovo Cimento, 卷 11, pp. 116 (1959)
[Edmonds74] (1,2,3,4,5,6,7,8,9,10)
A. R. Edmonds. Angular momentum in quantum mechanics. Investigations in physics, 4.; Investigations in physics, no. 4. Princeton, N.J., Princeton University Press, 1957.
[Rasch03] (1,2,3,4,5,6,7,8,9)
J. Rasch 和 A. C. H. Yu, ‘为预先计算的 Wigner 3j、6j 和 Gaunt 系数提供高效存储方案’, SIAM J. Sci. Comput. 卷 25, 期 4, pp. 1416-1428 (2003)
[Liberatodebrito82]
‘FORTRAN 程序计算三个球面谐波的积分’, A. Liberato de Brito, Comput. Phys. Commun., 卷 25, pp. 81-85 (1982)
[Homeier96] (1,2)
‘一些真实球面谐波耦合系数的性质及其与 Gaunt 系数的关系’, H. H. H. Homeier 和 E. O. Steinborn J. Mol. Struct., 卷 368, pp. 31-37 (1996)
Credits and Copyright
这段代码取自 Sage,经过了所有作者的允许:
groups.google.com/forum/#!topic/sage-devel/M4NZdu-7O38
作者
-
Jens Rasch (2009-03-24): Sage 的初始版本
-
Jens Rasch (2009-05-31): updated to sage-4.0
-
Oscar Gerardo Lazo Arjona (2017-06-18): added Wigner D matrices
-
Phil Adam LeMaitre (2022-09-19): 添加了真实的 Gaunt 系数
版权所有 (C) 2008 Jens Rasch jyr2000@gmail.com
sympy.physics.wigner.clebsch_gordan(j_1, j_2, j_3, m_1, m_2, m_3)
计算 Clebsch-Gordan 系数。 (\left\langle j_1 m_1 ; j_2 m_2 | j_3 m_3 \right\rangle)。
这个函数的参考资料是[Edmonds74]。
Parameters:
j_1, j_2, j_3, m_1, m_2, m_3 :
整数或半整数。
返回:
有理数乘以有理数的平方根。
示例
>>> from sympy import S
>>> from sympy.physics.wigner import clebsch_gordan
>>> clebsch_gordan(S(3)/2, S(1)/2, 2, S(3)/2, S(1)/2, 2)
1
>>> clebsch_gordan(S(3)/2, S(1)/2, 1, S(3)/2, -S(1)/2, 1)
sqrt(3)/2
>>> clebsch_gordan(S(3)/2, S(1)/2, 1, -S(1)/2, S(1)/2, 0)
-sqrt(2)/2
注记
Clebsch-Gordan 系数将通过其与 Wigner 3j 符号的关系进行评估:
[\left\langle j_1 m_1 ; j_2 m_2 | j_3 m_3 \right\rangle =(-1)^{j_1-j_2+m_3} \sqrt{2j_3+1} \operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,-m_3)]
查看 Wigner 3j 符号的文档,它展示了比 Clebsch-Gordan 系数更高的对称关系。
Authors
- Jens Rasch(2009-03-24):初始版本
sympy.physics.wigner.dot_rot_grad_Ynm(j, p, l, m, theta, phi)
返回球面谐波的旋转梯度的点积。
解释
此函数返回以下表达式的右侧:
[\vec{R}Y{j^{p}} \cdot \vec{R}Y{l^{m}} = (-1)^{m+p} \sum\limits{l+j}Y{_k{m+p}} * \alpha * \frac{1}{2} (k²-j²-l²+k-j-l)]
参数
j, p, l, m …. 球面谐波的指数(表达式或整数)theta, phi …. 球面谐波的角度参数
示例
>>> from sympy import symbols
>>> from sympy.physics.wigner import dot_rot_grad_Ynm
>>> theta, phi = symbols("theta phi")
>>> dot_rot_grad_Ynm(3, 2, 2, 0, theta, phi).doit()
3*sqrt(55)*Ynm(5, 2, theta, phi)/(11*sqrt(pi))
sympy.physics.wigner.gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None)
计算高斯系数。
参数:
l_1, l_2, l_3, m_1, m_2, m_3 :
整数。
prec - 精度,默认为 None
。
提供精度可以大大加快计算速度。
返回:
有理数乘以有理数的平方根
(如果 prec=None
),或者如果指定了精度,则为实数。
解释
高斯系数定义为三个球面谐波的积分:
[\begin{split}\begin{aligned} \operatorname{Gaunt}(l_1,l_2,l_3,m_1,m_2,m_3) &=\int Y_{l_1,m_1}(\Omega) Y_{l_2,m_2}(\Omega) Y_{l_3,m_3}(\Omega) ,d\Omega \ &=\sqrt{\frac{(2l_1+1)(2l_2+1)(2l_3+1)}{4\pi}} \operatorname{Wigner3j}(l_1,l_2,l_3,0,0,0) \operatorname{Wigner3j}(l_1,l_2,l_3,m_1,m_2,m_3) \end{aligned}\end{split}]
示例
>>> from sympy.physics.wigner import gaunt
>>> gaunt(1,0,1,1,0,-1)
-1/(2*sqrt(pi))
>>> gaunt(1000,1000,1200,9,3,-12).n(64)
0.006895004219221134484332976156744208248842039317638217822322799675
在 (l) 和 (m) 的非整数值上使用是错误的:
sage: gaunt(1.2,0,1.2,0,0,0)
Traceback (most recent call last):
...
ValueError: l values must be integer
sage: gaunt(1,0,1,1.1,0,-1.1)
Traceback (most recent call last):
...
ValueError: m values must be integer
注记
高斯系数遵循以下对称规则:
-
在列的任何排列下不变
[\begin{split}\begin{aligned} Y(l_1,l_2,l_3,m_1,m_2,m_3) &=Y(l_3,l_1,l_2,m_3,m_1,m_2) \ &=Y(l_2,l_3,l_1,m_2,m_3,m_1) \ &=Y(l_3,l_2,l_1,m_3,m_2,m_1) \ &=Y(l_1,l_3,l_2,m_1,m_3,m_2) \ &=Y(l_2,l_1,l_3,m_2,m_1,m_3) \end{aligned}\end{split}]
-
在空间反射下不变,即
[Y(l_1,l_2,l_3,m_1,m_2,m_3) =Y(l_1,l_2,l_3,-m_1,-m_2,-m_3)]
-
对于 (3j) 符号的 72 个 Regge 对称性,关于对称:
-
对于不满足三角关系的 (l_1), (l_2), (l_3) 为零
-
违反条件之一为零:(l_1 \ge |m_1|), (l_2 \ge |m_2|), (l_3 \ge |m_3|)
-
仅对 (l_i) 的偶数和 (L = l_1 + l_2 + l_3 = 2n) 的 (n \in \mathbb{N}) 非零
算法
此函数使用[Liberatodebrito82]的算法精确计算 Gaunt 系数的值。注意,该公式包含大阶乘的交替求和,因此不适合有限精度算术,只适用于计算代数系统[Rasch03]。
作者
Jens Rasch(2009-03-24):Sage 的初始版本。
sympy.physics.wigner.racah(aa, bb, cc, dd, ee, ff, prec=None)
计算 Racah 符号 (W(a,b,c,d;e,f))。
参数:
a, …, f :
整数或半整数。
prec :
精度,默认为
None
。提供精度可以大大加快计算速度。
返回:
有理数乘以有理数的平方根
(如果 prec=None
),或者如果指定了精度,则为实数。
示例
>>> from sympy.physics.wigner import racah
>>> racah(3,3,3,3,3,3)
-1/14
注记
Racah 符号与 Wigner 6j 符号相关:
[\operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6) =(-1)^{j_1+j_2+j_4+j_5} W(j_1,j_2,j_5,j_4,j_3,j_6)]
请参阅 6j 符号,了解其更丰富的对称性和其他属性。
算法
此函数使用[Edmonds74]的算法来精确计算 6j 符号的值。请注意,该公式包含大因子的交错和,因此不适合有限精度算术,只适用于计算代数系统[Rasch03]。
作者
- Jens Rasch(2009-03-24):初始版本
sympy.physics.wigner.real_gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None)
计算实高斯系数。
参数:
l_1, l_2, l_3, m_1, m_2, m_3:
整数。
prec - 精度,默认:None
。
提供精度可以显著加快计算速度。
返回:
有理数乘以有理数的平方根。
解释
实高斯系数被定义为对三个实球谐函数的积分:
[\begin{split}\begin{aligned} \operatorname{RealGaunt}(l_1,l_2,l_3,m_1,m_2,m_3) &=\int Z^{m_1}{l_1}(\Omega) Z^{m_2}(\Omega) Z^{m_3}_{l_3}(\Omega) ,d\Omega \ \end{aligned}\end{split}]
或者,可以通过将实球谐函数与标准球谐函数通过酉变换 (U) 关联来定义,即 (Z{m}_{l}(\Omega)=\sum_{m'}U{m'}Y^{m'}(\Omega)) [Homeier96]。则实高斯系数被定义为
[\begin{split}\begin{aligned} \operatorname{RealGaunt}(l_1,l_2,l_3,m_1,m_2,m_3) &=\int Z^{m_1}{l_1}(\Omega) Z^{m_2}(\Omega) Z^{m_3}{l_3}(\Omega) ,d\Omega \ &=\sum{m'_1 m'_2 m'3} U{m_1}_{m'_1}U{m'2}U^{m_3} \operatorname{Gaunt}(l_1,l_2,l_3,m'_1,m'_2,m'_3) \end{aligned}\end{split}]
酉矩阵 (U) 的分量为
[\begin{aligned} U^m_{m'} = \delta_{|m||m'|}(\delta_{m'0}\delta_{m0} + \frac{1}{\sqrt{2}}\big[\Theta(m) \big(\delta_{m'm}+(-1){m'}\delta_{m'-m}\big)+i\Theta(-m)\big((-1) \delta_{m'-m}-\delta_{m'm}(-1)^{m'-m}\big)\big]) \end{aligned}]
其中 (\delta_{ij}) 是克罗内克 δ 符号,(\Theta) 是定义为的阶跃函数
[\begin{split}\begin{aligned} \Theta(x) = \begin{cases} 1 ,\text{for}, x > 0 \ 0 ,\text{for}, x \leq 0 \end{cases} \end{aligned}\end{split}]
例子
>>> from sympy.physics.wigner import real_gaunt
>>> real_gaunt(2,2,4,-1,-1,0)
-2/(7*sqrt(pi))
>>> real_gaunt(10,10,20,-9,-9,0).n(64)
-0.00002480019791932209313156167176797577821140084216297395518482071448
对于 (l) 和 (m) 的非整数值使用是错误的::
real_gaunt(2.8,0.5,1.3,0,0,0) 追溯到(最近的调用)... ValueError: l values must be integer real_gaunt(2,2,4,0.7,1,-3.4) 追溯到(最近的调用)... ValueError: m values must be integer
注意
实高斯系数继承自标准高斯系数,在对 ((l_i, m_i)) 对的任意置换下不变,并要求 (l_i) 的和为偶数以产生非零值。它还遵循以下对称规则:
-
若 (l_1), (l_2), (l_3) 未满足条件 (l_1 \in {l_{\text{max}}, l_{\text{max}}-2, \ldots, l_{\text{min}}}), 其中 (l_{\text{max}} = l_2+l_3), 则为零
[\begin{split}\begin{aligned} l_{\text{min}} = \begin{cases} \kappa(l_2, l_3, m_2, m_3) & \text{if}, \kappa(l_2, l_3, m_2, m_3) + l_{\text{max}}, \text{is even} \ \kappa(l_2, l_3, m_2, m_3)+1 & \text{if}, \kappa(l_2, l_3, m_2, m_3) + l_{\text{max}}, \text{is odd}\end{cases} \end{aligned}\end{split}]
并且 (\kappa(l_2, l_3, m_2, m_3) = \max{\big(|l_2-l_3|, \min{\big(|m_2+m_3|, |m_2-m_3|\big)}\big)})
-
负 (m_i) 的个数为奇数时为零
算法
该函数精确计算实数 Gaunt 系数的值,使用了 [Homeier96] 和 [Rasch03] 的算法。注意,[Rasch03] 中使用的公式包含大阶乘的交替和,因此不适合有限精度算术,仅适用于计算机代数系统 [Rasch03]。然而,该函数原则上可以使用计算 Gaunt 系数的任何算法,因此在计算 Gaunt 系数的算法适用于有限精度算术的情况下也是合适的。
sympy.physics.wigner.wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3)
计算 Wigner 3j 符号 (\operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,m_3))。
参数:
j_1, j_2, j_3, m_1, m_2, m_3 :
整数或半整数。
返回:
有理数乘以有理数的平方根。
例子
>>> from sympy.physics.wigner import wigner_3j
>>> wigner_3j(2, 6, 4, 0, 0, 0)
sqrt(715)/143
>>> wigner_3j(2, 6, 4, 0, 0, 1)
0
如果参数不是整数或半整数值,则出错:
sage: wigner_3j(2.1, 6, 4, 0, 0, 0)
Traceback (most recent call last):
...
ValueError: j values must be integer or half integer
sage: wigner_3j(2, 6, 4, 1, 0, -1.1)
Traceback (most recent call last):
...
ValueError: m values must be integer or half integer
注释
Wigner 3j 符号遵循以下对称性规则:
-
在列的任何置换下不变(除了在 (J:=j_1+j_2+j_3) 处的符号变化)
[\begin{split}\begin{aligned} \operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,m_3) &=\operatorname{Wigner3j}(j_3,j_1,j_2,m_3,m_1,m_2) \ &=\operatorname{Wigner3j}(j_2,j_3,j_1,m_2,m_3,m_1) \ &=(-1)^J \operatorname{Wigner3j}(j_3,j_2,j_1,m_3,m_2,m_1) \ &=(-1)^J \operatorname{Wigner3j}(j_1,j_3,j_2,m_1,m_3,m_2) \ &=(-1)^J \operatorname{Wigner3j}(j_2,j_1,j_3,m_2,m_1,m_3) \end{aligned}\end{split}]
-
对于空间反射是不变的,即
[\operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,m_3) =(-1)^J \operatorname{Wigner3j}(j_1,j_2,j_3,-m_1,-m_2,-m_3)]
-
对称于基于 [Regge58] 的其他 72 种对称性
-
若 (j_1), (j_2), (j_3) 不满足三角关系,则为零
-
若 (m_1 + m_2 + m_3 \neq 0), 则为零
-
违反任何一个条件均为零
(m_1 \in {-|j_1|, \ldots, |j_1|}), (m_2 \in {-|j_2|, \ldots, |j_2|}), (m_3 \in {-|j_3|, \ldots, |j_3|})
算法
该函数使用 [Edmonds74] 的算法精确计算 3j 符号的值。注意,该公式包含大阶乘的交替和,因此不适合有限精度算术,仅适用于计算机代数系统 [Rasch03]。
作者
- Jens Rasch (2009-03-24): 初始版本
sympy.physics.wigner.wigner_6j(j_1, j_2, j_3, j_4, j_5, j_6, prec=None)
计算 Wigner 6j 符号 (\operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6))。
参数:
j_1, …, j_6 :
整数或半整数。
prec :
精度,默认为
None
。提供精度可以大大加快计算速度。
返回:
有理数乘以有理数的平方根
(如果prec=None
),或者如果给出精度,则为实数。
例子
>>> from sympy.physics.wigner import wigner_6j
>>> wigner_6j(3,3,3,3,3,3)
-1/14
>>> wigner_6j(5,5,5,5,5,5)
1/52
参数必须是整数或半整数值,并满足三角关系,否则将出错:
sage: wigner_6j(2.5,2.5,2.5,2.5,2.5,2.5)
Traceback (most recent call last):
...
ValueError: j values must be integer or half integer and fulfill the triangle relation
sage: wigner_6j(0.5,0.5,1.1,0.5,0.5,1.1)
Traceback (most recent call last):
...
ValueError: j values must be integer or half integer and fulfill the triangle relation
注意事项
Wigner 6j 符号与 Racah 符号有关,但展示了更多的对称性,如下所述。
[\operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6) =(-1)^{j_1+j_2+j_4+j_5} W(j_1,j_2,j_5,j_4,j_3,j_6)]
Wigner 6j 符号遵循以下对称规则:
-
Wigner 6j 符号在列的任何排列下都是左不变的:
[\begin{split}\begin{aligned} \operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6) &=\operatorname{Wigner6j}(j_3,j_1,j_2,j_6,j_4,j_5) \ &=\operatorname{Wigner6j}(j_2,j_3,j_1,j_5,j_6,j_4) \ &=\operatorname{Wigner6j}(j_3,j_2,j_1,j_6,j_5,j_4) \ &=\operatorname{Wigner6j}(j_1,j_3,j_2,j_4,j_6,j_5) \ &=\operatorname{Wigner6j}(j_2,j_1,j_3,j_5,j_4,j_6) \end{aligned}\end{split}]
-
它们在每两列中交换上下参数的情况下是不变的,即
[\operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6) =\operatorname{Wigner6j}(j_1,j_5,j_6,j_4,j_2,j_3) =\operatorname{Wigner6j}(j_4,j_2,j_6,j_1,j_5,j_3) =\operatorname{Wigner6j}(j_4,j_5,j_3,j_1,j_2,j_6)]
-
附加 6 种对称性[Regge59]总共产生 144 种对称性
-
仅在任意三个(j)的三元组满足三角关系时非零
算法
该函数使用[Edmonds74]的算法精确计算 6j 符号的值。请注意,公式包含大量阶乘的交错和,因此不适合有限精度算术,仅适用于计算代数系统[Rasch03]。
sympy.physics.wigner.wigner_9j(j_1, j_2, j_3, j_4, j_5, j_6, j_7, j_8, j_9, prec=None)
计算 Wigner 9j 符号 (\operatorname{Wigner9j}(j_1,j_2,j_3,j_4,j_5,j_6,j_7,j_8,j_9))。
参数:
j_1, …, j_9 :
整数或半整数。
prec : 精度,默认
None
. 提供精度可以大大加快计算速度。
返回:
有理数乘以有理数的平方根
(如果prec=None
),或者如果给出精度,则为实数。
例子
>>> from sympy.physics.wigner import wigner_9j
>>> wigner_9j(1,1,1, 1,1,1, 1,1,0, prec=64)
0.05555555555555555555555555555555555555555555555555555555555555555
>>> wigner_9j(1/2,1/2,0, 1/2,3/2,1, 0,1,1, prec=64)
0.1666666666666666666666666666666666666666666666666666666666666667
参数必须是整数或半整数值,并满足三角关系,否则将出错:
sage: wigner_9j(0.5,0.5,0.5, 0.5,0.5,0.5, 0.5,0.5,0.5,prec=64)
Traceback (most recent call last):
...
ValueError: j values must be integer or half integer and fulfill the triangle relation
sage: wigner_9j(1,1,1, 0.5,1,1.5, 0.5,1,2.5,prec=64)
Traceback (most recent call last):
...
ValueError: j values must be integer or half integer and fulfill the triangle relation
算法
该函数使用[Edmonds74]的算法精确计算 3j 符号的值。请注意,公式包含大量阶乘的交错和,因此不适合有限精度算术,仅适用于计算代数系统[Rasch03]。
sympy.physics.wigner.wigner_d(J, alpha, beta, gamma)
返回角动量 J 的 Wigner D 矩阵。
返回:
代表相应的欧拉角旋转矩阵(在基础上
(J_z)的特征向量)。
[\mathcal{D}_{\alpha \beta \gamma} = \exp\big( \frac{i\alpha}{\hbar} J_z\big) \exp\big( \frac{i\beta}{\hbar} J_y\big) \exp\big( \frac{i\gamma}{\hbar} J_z\big)]
这些分量是用通用形式计算的[Edmonds74],
方程 4.1.12。
解释
J:
表示被旋转角动量空间的总角动量的整数、半整数或 SymPy 符号。
alpha, beta, gamma - 表示欧拉旋转角的实数。
环绕所谓的垂直线、节点线和图形轴的旋转角。参见[Edmonds74]。
例子
最简单的例子:
>>> from sympy.physics.wigner import wigner_d
>>> from sympy import Integer, symbols, pprint
>>> half = 1/Integer(2)
>>> alpha, beta, gamma = symbols("alpha, beta, gamma", real=True)
>>> pprint(wigner_d(half, alpha, beta, gamma), use_unicode=True)
⎡ ⅈ⋅α ⅈ⋅γ ⅈ⋅α -ⅈ⋅γ ⎤
⎢ ─── ─── ─── ───── ⎥
⎢ 2 2 ⎛β⎞ 2 2 ⎛β⎞ ⎥
⎢ ℯ ⋅ℯ ⋅cos⎜─⎟ ℯ ⋅ℯ ⋅sin⎜─⎟ ⎥
⎢ ⎝2⎠ ⎝2⎠ ⎥
⎢ ⎥
⎢ -ⅈ⋅α ⅈ⋅γ -ⅈ⋅α -ⅈ⋅γ ⎥
⎢ ───── ─── ───── ───── ⎥
⎢ 2 2 ⎛β⎞ 2 2 ⎛β⎞⎥
⎢-ℯ ⋅ℯ ⋅sin⎜─⎟ ℯ ⋅ℯ ⋅cos⎜─⎟⎥
⎣ ⎝2⎠ ⎝2⎠⎦
sympy.physics.wigner.wigner_d_small(J, beta)
返回角动量 J 的小 Wigner d 矩阵。
返回:
表示对应欧拉角旋转的矩阵
的特征向量的整数(J_z))。
[\mathcal{d}_{\beta} = \exp\big( \frac{i\beta}{\hbar} J_y\big)]
这些分量是用通用形式计算的[Edmonds74],
方程 4.1.15。
解释
J 表示被旋转角动量空间的总角动量的整数、半整数或 SymPy 符号。
被旋转角动量空间的角动量。
beta 表示欧拉角的实数。
所谓的节点线。参见[Edmonds74]。
例子
>>> from sympy import Integer, symbols, pi, pprint
>>> from sympy.physics.wigner import wigner_d_small
>>> half = 1/Integer(2)
>>> beta = symbols("beta", real=True)
>>> pprint(wigner_d_small(half, beta), use_unicode=True)
⎡ ⎛β⎞ ⎛β⎞⎤
⎢cos⎜─⎟ sin⎜─⎟⎥
⎢ ⎝2⎠ ⎝2⎠⎥
⎢ ⎥
⎢ ⎛β⎞ ⎛β⎞⎥
⎢-sin⎜─⎟ cos⎜─⎟⎥
⎣ ⎝2⎠ ⎝2⎠⎦
>>> pprint(wigner_d_small(2*half, beta), use_unicode=True)
⎡ 2⎛β⎞ ⎛β⎞ ⎛β⎞ 2⎛β⎞ ⎤
⎢ cos ⎜─⎟ √2⋅sin⎜─⎟⋅cos⎜─⎟ sin ⎜─⎟ ⎥
⎢ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎥
⎢ ⎥
⎢ ⎛β⎞ ⎛β⎞ 2⎛β⎞ 2⎛β⎞ ⎛β⎞ ⎛β⎞⎥
⎢-√2⋅sin⎜─⎟⋅cos⎜─⎟ - sin ⎜─⎟ + cos ⎜─⎟ √2⋅sin⎜─⎟⋅cos⎜─⎟⎥
⎢ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠⎥
⎢ ⎥
⎢ 2⎛β⎞ ⎛β⎞ ⎛β⎞ 2⎛β⎞ ⎥
⎢ sin ⎜─⎟ -√2⋅sin⎜─⎟⋅cos⎜─⎟ cos ⎜─⎟ ⎥
⎣ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎦
从表 4 中[Edmonds74]
>>> pprint(wigner_d_small(half, beta).subs({beta:pi/2}), use_unicode=True)
⎡ √2 √2⎤
⎢ ── ──⎥
⎢ 2 2 ⎥
⎢ ⎥
⎢-√2 √2⎥
⎢──── ──⎥
⎣ 2 2 ⎦
>>> pprint(wigner_d_small(2*half, beta).subs({beta:pi/2}),
... use_unicode=True)
⎡ √2 ⎤
⎢1/2 ── 1/2⎥
⎢ 2 ⎥
⎢ ⎥
⎢-√2 √2 ⎥
⎢──── 0 ── ⎥
⎢ 2 2 ⎥
⎢ ⎥
⎢ -√2 ⎥
⎢1/2 ──── 1/2⎥
⎣ 2 ⎦
>>> pprint(wigner_d_small(3*half, beta).subs({beta:pi/2}),
... use_unicode=True)
⎡ √2 √6 √6 √2⎤
⎢ ── ── ── ──⎥
⎢ 4 4 4 4 ⎥
⎢ ⎥
⎢-√6 -√2 √2 √6⎥
⎢──── ──── ── ──⎥
⎢ 4 4 4 4 ⎥
⎢ ⎥
⎢ √6 -√2 -√2 √6⎥
⎢ ── ──── ──── ──⎥
⎢ 4 4 4 4 ⎥
⎢ ⎥
⎢-√2 √6 -√6 √2⎥
⎢──── ── ──── ──⎥
⎣ 4 4 4 4 ⎦
>>> pprint(wigner_d_small(4*half, beta).subs({beta:pi/2}),
... use_unicode=True)
⎡ √6 ⎤
⎢1/4 1/2 ── 1/2 1/4⎥
⎢ 4 ⎥
⎢ ⎥
⎢-1/2 -1/2 0 1/2 1/2⎥
⎢ ⎥
⎢ √6 √6 ⎥
⎢ ── 0 -1/2 0 ── ⎥
⎢ 4 4 ⎥
⎢ ⎥
⎢-1/2 1/2 0 -1/2 1/2⎥
⎢ ⎥
⎢ √6 ⎥
⎢1/4 -1/2 ── -1/2 1/4⎥
⎣ 4 ⎦
单位制度
此模块将单位制度集成到 SymPy 中,允许用户在计算时选择使用的系统,并提供显示和转换单位的实用工具。
单位(如米、磅、秒)和常数(如光年、玻尔兹曼常数)都被视为量。Quantity
对象定义了单位和物理常数(尽管它的子类PhysicalConstant
可能更适合物理常数)。
数量之间的关系由它们的维度和至少另一个相同维度的量的比例因子定义。这两种类型的关系通常在UnitSystem
对象内定义,除了在每个单位制度中都有效的属性。例如,1 千米在所有单位制度中都等于 1000 米,其维度在所有维度系统中都是长度
。另一方面,在 SI 单位制度中,光速等于 299792458 米每秒,而在自然单位中,光速等于 1(无单位)。在 SI 和自然单位中,光速的维度为速度
,但在自然单位的维度系统中,速度
是无维度的,因为长度
和时间
是等效的。类似地,在 SI 单位制度和 CGS 及高斯单位制度之间,在电磁量的维度和比例因子中存在差异,因为后两种单位制度不认为电流
是一个基本维度。
与其他库中的实现相比,此实现的优势在于,它以不同的方式处理单位制度之间的关系,而不受 SI 单位制度对单位和物理常数关系的假设限制。
示例
单位模块中最重要的函数是convert_to
,它允许将给定的量重新表示为某些目标量的幂的乘积。例如,要用米和秒表示光速:
>>> from sympy.physics.units import speed_of_light, meter, second
>>> from sympy.physics.units import convert_to
>>> convert_to(speed_of_light, [meter, second])
299792458*meter/second
如果无法用目标单位表示给定的量,将原样返回给定的量:
>>> convert_to(speed_of_light, [meter])
speed_of_light
数量之间的关系取决于单位制度。因此,convert_to
接受一个可选的第三个参数,表示单位制度,默认为SI
。根据所选的单位制度,转换可能返回不同的结果,例如,在cgs_gauss
单位制度中,电流不是一个基本维度,而是可以表示为长度、时间和质量的组合:
>>> from sympy.physics.units.systems.si import SI
>>> from sympy.physics.units.systems.cgs import cgs_gauss
>>> from sympy.physics.units import ampere, gram, second
>>> convert_to(ampere, [meter, gram, second], SI)
ampere
>>> convert_to(ampere, [meter, gram, second], cgs_gauss)
149896229*sqrt(gram)*meter**(3/2)/(50*second**2)
相同维度的量不会自动简化,例如如果你将米除以千米,你会得到一个表示两个单位之间除法的对象。为了简化这类表达式,你可以调用.simplify()
方法或导入quantity_simplify()
函数,后者还可以接受一个单位系统作为可选参数。
>>> from sympy.physics.units.util import quantity_simplify
>>> from sympy.physics.units import kilometer
>>> meter/kilometer
meter/kilometer
>>> (meter/kilometer).simplify()
1/1000
>>> quantity_simplify(meter/kilometer)
1/1000
更多
有关未来发展的想法可以在Github wiki中找到。
-
单位制背后的哲学
-
更多例子
-
维度和维度系统
-
单位前缀
-
单位和单位制度
-
物理量
单位制背后的哲学
原文链接:
docs.sympy.org/latest/modules/physics/units/philosophy.html
维度
介绍
单位制背后的根源是维度系统,其结构主要决定了单位系统的结构。我们的定义可能看起来粗略,但对于我们的目的来说已经足够了。
维度被定义为可测量的并分配给特定现象的属性。在这个意义上,维度与纯数不同,因为它们具有一些额外的意义,因此不能将两个不同的维度相加。例如,时间或长度是维度,但对于我们有意义的任何其他事物,如角度、粒子数(摩尔...)或信息(比特...)也是如此。
从这个角度来看,唯一真正无量纲的量是纯数。无量纲的概念非常依赖于系统,正如在((c, \hbar, G))中所见的那样,所有单位在通常的常识中似乎都是无量纲的。这在通用单位系统的可计算性上是不可避免的(但最终我们可以告诉程序什么是无量纲的)。
通过取其乘积或其比率(在下文中定义)可以将维度组合在一起。例如,速度定义为长度除以时间,或者我们可以将长度看作速度乘以时间,取决于我们认为哪个更基本:一般来说,我们可以选择一组基础维度,从中我们可以描述所有其他维度。
群结构
在这个简短的介绍之后,旨在从直观的角度介绍维度之后,我们描述了数学结构。具有(n)个独立维度({d_i}_{i=1,\ldots,n})的维度系统由乘法群(G)描述:
-
存在一个纯数对应的单位元素(1);
-
两个元素(D_1, D_2 \in G)的乘积(D_3 = D_1 D_2)也在(G)中;
-
任何元素(D \in G)都有逆元(D^{-1} \in G)。
我们表示
[D^n = \underbrace{D \times \cdots \times D}_{\text{\(n\) times}},]
并且按定义(D⁰ = 1)。称为群生成元的({d_i}_{i=1,\ldots,n}),因为群中的任何元素(D \in G)都可以表示为生成元的幂的乘积:
[D = \prod_{i=1}^n d_i^{a_i}, \qquad a_i \in \mathbf{Z}.]
对于(a_i = 0, \forall i)给出了单位元,而对于(a_i = 1, a_j = 0, \forall j \neq i)我们恢复了生成元(d_i)。该群具有以下特性:
-
阿贝尔的,因为生成元交换,([d_i, d_j] = 0);
-
可数(无限但离散),因为元素按生成元的幂进行索引[1]。
可以通过取旧生成元的某些组合来改变维度基({d'i}):
[d'i = \prod^n d_j^{P_{ij}}.]
线性空间表示
可以使用线性空间 (\mathbf{Z}^n) 作为群的表示,因为幂次系数 (a_i) 包含了所需的所有信息(我们不区分群的元素和其表示):
[\begin{split}(d_i)j = \delta, \qquad D = \begin{pmatrix} a_1 \ \vdots \ a_n \end{pmatrix}.\end{split}]
到 (d'i) 的基变换遵循线性空间的通常基变换规则,矩阵由新向量的系数 (P) 给出,这些系数简单地是旧基础下新向量的系数:
[d'i = P d_j.]
我们将在算法中使用这个最后的解决方案。
一个例子
为了说明所有这些形式主义,我们用一个具体例子来结束本节,即 MKSA 系统(m, kg, s),其维度为 (L: length, M: mass, T: time)。它们表示为(我们将始终按字母顺序排列向量)
[\begin{split}L = \begin{pmatrix} 1 \ 0 \ 0 \end{pmatrix}, \qquad M = \begin{pmatrix} 0 \ 1 \ 0 \end{pmatrix}, \qquad T = \begin{pmatrix} 0 \ 0 \ 1 \end{pmatrix}.\end{split}]
其他维度可以导出,例如速度 (V) 或作用量 (A)
[\begin{split}V = L T^{-1}, \qquad A = M L² T^{-2},\ V = \begin{pmatrix} 1 \ 0 \ -1 \end{pmatrix}, \qquad A = \begin{pmatrix} 2 \ 1 \ -2 \end{pmatrix}.\end{split}]
我们可以转换基础以转向自然系统 ((m, c, \hbar)),其维度为 (L: length, V: velocity, A: action) [2]。在此基础上,生成器为
[\begin{split}A = \begin{pmatrix} 1 \ 0 \ 0 \end{pmatrix}, \qquad L = \begin{pmatrix} 0 \ 1 \ 0 \end{pmatrix}, \qquad V = \begin{pmatrix} 0 \ 0 \ 1 \end{pmatrix},\end{split}]
而质量和时间分别由
[\begin{split}T = L V^{-1}, \qquad M = A V^{-2},\ T = \begin{pmatrix} 0 \ 1 \ -1 \end{pmatrix}, \qquad M = \begin{pmatrix} 1 \ 0 \ -2 \end{pmatrix}.\end{split}]
最终逆变换基矩阵 (P^{-1}) 通过将在旧基础下表达的向量粘合在一起而得到:
[\begin{split}P^{-1} = \begin{pmatrix} 2 & 1 & 1 \ 1 & 0 & 0 \ -2 & 0 & -1 \end{pmatrix}.\end{split}]
要找到基矩阵的变换,我们只需取其逆
[\begin{split}P = \begin{pmatrix} 0 & 1 & 0 \ 1 & 0 & 1 \ 0 & -2 & -1 \end{pmatrix}.\end{split}]
数量
一个量由其名称、维度和到相同维度的规范量的因子定义。规范量是单位模块的内部参考,不应影响最终用户。单位和物理常数都是数量。
单位
单位,如米、秒和千克,通常是人们选择的参考量,用于引用其他数量。
定义了几种不同维度的单位后,我们可以形成一个单位制度,这基本上是一个带有比例概念的维度系统。
常数
物理常数只是数量。它们表明我们以前并不理解两个维度实际上是相同的。例如,我们看到光速不是 1,因为我们没有意识到时间和空间是相同的(这是因为我们的感官;但在基本层面上它们是不同的)。例如,曾经有一个“热常数”,它允许在焦耳和卡路里之间进行转换,因为人们不知道热是能量。一旦他们理解了这一点,他们把这个常数固定为 1(这是一个非常简略的故事)。
现在我们固定国际单位制中基本常数的值,这表明它们是单位(我们用它们来定义其他常用单位)。
参考需求
不可能从头定义单位和单位系统:我们需要定义一些参考点,然后在它们上面建立其他内容。换句话说,我们需要一个刻度起源来定义我们单位的尺度(即一个因子为 1 的单位),并确保所有给定维度的单位都以一致的方式定义,这可以发生在我们希望在另一个系统中使用一个派生单位作为基本单位时:我们不应将其定义为具有比例 1,因为即使在系统内部是不一致的,我们也无法将其转换为第一个系统,因为从我们的角度来看,我们有两个不同单位的相同比例(这意味着它们在计算机中是相等的)。
我们将说,在系统外定义的维度和刻度是规范的,因为我们用它们进行所有计算。另一方面,相对于系统得到的维度和刻度称为物理的,因为它们最终带有一种意义。
让我们举一个具体(而且重要)的例子:质量单位的情况。我们希望将克定义为起点。我们希望将克定义为质量的规范起点,因此我们赋予它一个比例 1。然后我们可以定义一个系统(例如化学系统),将其作为基本单位。MKS 系统更喜欢使用千克;一个简单的选择是给它一个比例为 1 的标度,因为它是一个基本单位,但我们看到我们无法将其转换为化学系统,因为克和千克都被赋予了相同的因子。因此,我们需要把千克定义为 1000 克,然后才能在 MKS 系统中使用它作为基础。但是一旦我们问“千克在 MKS 中的因子是多少?”,我们得到的答案是 1,因为它是一个基本单位。
因此,我们将定义所有的计算而不涉及任何系统,在最后一步我们才将结果插入到系统中,以给出我们感兴趣的上下文。
文献
[Page52]
C. H. Page,SI 单位的类别,物理学美国杂志,20 卷,1 期(1952 年):1。
[Page78]
C. H. Page,物理学中的单位与维度,物理学美国杂志,46 卷,1 期(1978 年):78。
[deBoer79]
J. de Boer, 量和单位的群属性, Am. J. of Phys. 47, 9 (1979): 818.
[LevyLeblond77]
J.-M. Lévy-Leblond, 关于物理常数的概念性质, La Rivista Del Nuovo Cimento 7, no. 2 (1977): 187-214.
[NIST]
脚注
更多例子
原文链接:
docs.sympy.org/latest/modules/physics/units/examples.html
在接下来的几节中,我们将提供一些可以使用此模块完成的示例。
尺寸分析
我们将从牛顿第二定律开始
[m a = F]
其中 (m, a) 和 (F) 分别是质量、加速度和力。知道 (m) ((M)) 和 (a) ((L T^{-2})) 的维度后,我们将确定 (F) 的维度;显然,我们将发现它是一个力:(M L T^{-2})。
从那里我们将使用质量为 (m) 的粒子和质量为 (M) 的物体之间的引力表达式,距离为 (r)。
[F = \frac{G m M}{r²}]
以确定牛顿引力常数 (G) 的维度。结果应为 (L³ M^{-1} T^{-2})。
>>> from sympy import symbols >>> from sympy.physics.units.systems import SI >>> from sympy.physics.units import length, mass, acceleration, force >>> from sympy.physics.units import gravitational_constant as G >>> from sympy.physics.units.systems.si import dimsys_SI >>> F = mass*acceleration >>> F Dimension(acceleration*mass) >>> dimsys_SI.get_dimensional_dependencies(F) {Dimension(length): 1, Dimension(mass, M): 1, Dimension(time): -2} >>> dimsys_SI.get_dimensional_dependencies(force) {Dimension(length): 1, Dimension(mass): 1, Dimension(time): -2}
尽管在国际单位制中它们相同,但尺寸不能直接比较:
>>> F == force False
尺寸系统对象提供了测试尺寸等效性的方法:
>>> dimsys_SI.equivalent_dims(F, force) True
>>> m1, m2, r = symbols("m1 m2 r") >>> grav_eq = G * m1 * m2 / r**2 >>> F2 = grav_eq.subs({m1: mass, m2: mass, r: length, G: G.dimension}) >>> F2 Dimension(mass*length*time**-2) >>> F2.get_dimensional_dependencies() {'length': 1, 'mass': 1, 'time': -2}
注意应先解方程,然后用尺寸进行替换。
具有数量的方程
使用开普勒第三定律
[\frac{T²}{a³} = \frac{4 \pi²}{GM}]
我们可以使用从维基百科获取的其他变量的已知值来找到金星的轨道周期。结果应为 224.701 天。
>>> from sympy import solve, symbols, pi, Eq >>> from sympy.physics.units import Quantity, length, mass >>> from sympy.physics.units import day, gravitational_constant as G >>> from sympy.physics.units import meter, kilogram >>> T = symbols("T") >>> a = Quantity("venus_a")
在国际单位制中指定维度和比例:
>>> SI.set_quantity_dimension(a, length) >>> SI.set_quantity_scale_factor(a, 108208000e3*meter)
添加太阳质量作为量:
>>> M = Quantity("solar_mass") >>> SI.set_quantity_dimension(M, mass) >>> SI.set_quantity_scale_factor(M, 1.9891e30*kilogram)
现在是开普勒定律:
>>> eq = Eq(T**2 / a**3, 4*pi**2 / G / M) >>> eq Eq(T**2/venus_a**3, 4*pi**2/(gravitational_constant*solar_mass)) >>> q = solve(eq, T)[1] >>> q 2*pi*venus_a**(3/2)/(sqrt(gravitational_constant)*sqrt(solar_mass))
要转换为天数,使用 convert_to
函数(可能需要近似结果):
>>> from sympy.physics.units import convert_to
>>> convert_to(q, day)
71.5112118495813*pi*day
>>> convert_to(q, day).n()
224.659097795948*day
我们也可以使用来自天体物理系统的太阳质量和日子作为单位,但我们想展示如何创建一个所需的单位。
我们可以看到在这个例子中,中间维度可能不明确,比如 sqrt(G),但应检查最终结果 - 当所有维度组合在一起时 - 是否明确定义。
维度和维度系统
原文:
docs.sympy.org/latest/modules/physics/units/dimensions.html
物理维度的定义。
单位制将建立在这些维度之上。
文档中的大多数示例使用 MKS 系统,并且从计算机的角度来看:从人类的角度来看,在 MKS 中将长度添加到时间是不合法的,但在自然系统中是合法的;对于计算机在自然系统中不存在时间维度(而是速度维度代替)- 在基础中 - 因此将时间添加到长度的问题毫无意义。
class sympy.physics.units.dimensions.Dimension(name, symbol=None)
此类表示物理量的维度。
Dimension
构造函数以名称和可选符号作为参数。
例如,在经典力学中,我们知道时间与温度不同,并且维度使得这种差异明显(但它们不提供这些量的任何测量。
>>> from sympy.physics.units import Dimension
>>> length = Dimension('length')
>>> length
Dimension(length)
>>> time = Dimension('time')
>>> time
Dimension(time)
可以使用乘法、除法和指数运算(乘以数)来组合维度,以生成新的维度。仅当两个对象为相同维度时才定义加法和减法。
>>> velocity = length / time
>>> velocity
Dimension(length/time)
可以使用维度系统对象获取维度的维度依赖性,例如,可以使用 SI 单位约定中使用的维度系统:
>>> from sympy.physics.units.systems.si import dimsys_SI
>>> dimsys_SI.get_dimensional_dependencies(velocity)
{Dimension(length, L): 1, Dimension(time, T): -1}
>>> length + length
Dimension(length)
>>> l2 = length**2
>>> l2
Dimension(length**2)
>>> dimsys_SI.get_dimensional_dependencies(l2)
{Dimension(length, L): 2}
has_integer_powers(dim_sys)
检查维度对象是否仅具有整数幂。
所有维度幂应为整数,但在中间步骤中可能出现有理数幂。此方法可用于检查最终结果是否定义良好。
class sympy.physics.units.dimensions.DimensionSystem(base_dims, derived_dims=(), dimensional_dependencies={})
DimensionSystem
表示一组一致的维度。
构造函数接受三个参数:
-
基础维度;
-
派生维度:这些是以基础维度定义的(例如,速度是通过长度除以时间定义的);
-
维度依赖性:派生维度如何依赖于基础维度。
可选地,derived_dims
或 dimensional_dependencies
可能会被省略。
property can_transf_matrix
无用的方法,保持与先前版本的兼容性。
请勿使用。
返回从规范到基础维度基础的规范变换矩阵。
它是使用 inv_can_transf_matrix()
计算的矩阵的逆。
property dim
无用的方法,保持与先前版本的兼容性。
请勿使用。
给出系统的维度。
这是返回形成基础的维度数量。
dim_can_vector(dim)
无用的方法,保持与先前版本的兼容性。
请勿使用。
以规范基础维度表示的维度。
dim_vector(dim)
无用的方法,保持与先前版本的兼容性。
请勿使用。
以基础维度表示的向量。
property inv_can_transf_matrix
无用的方法,保持与先前版本的兼容性。
请勿使用。
计算从基础到规范维度基础的逆变换矩阵。
它对应于矩阵,其中列是规范基础维度的向量。
这个矩阵几乎不会被使用,因为维度总是相对于规范基定义的,因此不需要额外工作来在此基础上获取它们。尽管如此,如果此矩阵不是方阵(或不可逆),这意味着我们选择了一个不好的基。
property is_consistent
这个方法无用,仅为了与之前版本兼容而保留。
请勿使用。
检查系统是否定义良好。
is_dimensionless(dimension)
检查维度对象是否确实具有维度。
维度应该至少有一个具有非零幂的分量。
property list_can_dims
这个方法无用,仅为了与之前版本兼容而保留。
请勿使用。
列出所有规范维度名称。
print_dim_base(dim)
给出维度的字符串表达式,用基本符号表示。
单位前缀
原文:
docs.sympy.org/latest/modules/physics/units/prefixes.html
定义单位前缀类和一些常数的模块。
SI 和二进制前缀的常数字典被定义为 PREFIXES 和 BIN_PREFIXES。
class sympy.physics.units.prefixes.Prefix(name, abbrev, exponent, base=10, latex_repr=None)
这个类表示前缀,带有它们的名称、符号和因子。
前缀用于从给定单位创建导出单位。它们应始终封装到单位中。
该因子是从一个基数(默认为 10)构造到某个幂,并给出总倍数或分数。例如,千米 km 是从米(因子 1)和千(10 的 3 次方,即 1000)构造而成。基数可以更改以允许例如二进制前缀。
一个前缀乘以另一个对象总是返回另一个对象乘以这个因子的乘积,除非另一个对象:
-
是一个前缀,它们可以组合成一个新的前缀;
-
定义与前缀的乘法(这是单位类的情况)。
单位和单位制度
原文链接:
docs.sympy.org/latest/modules/physics/units/unitsystem.html
物理量的单位制;包括常数的定义。
class sympy.physics.units.unitsystem.UnitSystem(base_units, units=(), name='', descr='', dimension_system=None, derived_units: Dict[Dimension, Quantity] = {})
UnitSystem 表示一个连贯的单位集合。
单位系统基本上是一个具有比例概念的维度系统。许多方法都以相同的方式定义。
如果所有基本单位都有符号,那就更好了。
property dim
给出系统的维度。
这是返回形成基础的单位数量。
extend(base, units=(), name='', description='', dimension_system=None, derived_units: Dict[Dimension, Quantity] = {})
将当前系统扩展到一个新系统。
取当前系统的基本和标准单位,将它们与参数中给出的基本和标准单位合并。如果未提供,则名称和描述被覆盖为空字符串。
get_units_non_prefixed() → Set[Quantity]
返回该系统中没有前缀的单位。
property is_consistent
检查底层维度系统是否一致。
物理量
原文:
docs.sympy.org/latest/modules/physics/units/quantities.html
物理量。
class sympy.physics.units.quantities.Quantity(name, abbrev=None, latex_repr=None, pretty_unicode_repr=None, pretty_ascii_repr=None, mathml_presentation_repr=None, is_prefixed=False, **assumptions)
物理数量:可以是测量单位、常量或通用数量。
property abbrev
表示单位名称的符号。
如果定义了缩写词,则在前缀符号之前加上缩写词。
convert_to(other, unit_system='SI')
将数量转换为具有相同维度的另一个数量。
示例
>>> from sympy.physics.units import speed_of_light, meter, second
>>> speed_of_light
speed_of_light
>>> speed_of_light.convert_to(meter/second)
299792458*meter/second
>>> from sympy.physics.units import liter
>>> liter.convert_to(meter**3)
meter**3/1000
property free_symbols
返回数量的无返回符号。
property is_prefixed
数量是否带有前缀。例如,(kilogram) 带有前缀,但 (gram) 没有。
property scale_factor
相对于规范单位的整体数量。
set_global_relative_scale_factor(scale_factor, reference_quantity)
设置在所有单位系统中都有效的比例因子。
量之间的转换
几种简化涉及单位对象的表达式的方法。
sympy.physics.units.util.convert_to(expr, target_units, unit_system='SI')
将 expr
转换为其所有单位和数量表示为 target_units
的因子的相同表达式,只要维度兼容。
target_units
可以是单个单位/数量,也可以是单位/数量的集合。
示例
>>> from sympy.physics.units import speed_of_light, meter, gram, second, day
>>> from sympy.physics.units import mile, newton, kilogram, atomic_mass_constant
>>> from sympy.physics.units import kilometer, centimeter
>>> from sympy.physics.units import gravitational_constant, hbar
>>> from sympy.physics.units import convert_to
>>> convert_to(mile, kilometer)
25146*kilometer/15625
>>> convert_to(mile, kilometer).n()
1.609344*kilometer
>>> convert_to(speed_of_light, meter/second)
299792458*meter/second
>>> convert_to(day, second)
86400*second
>>> 3*newton
3*newton
>>> convert_to(3*newton, kilogram*meter/second**2)
3*kilogram*meter/second**2
>>> convert_to(atomic_mass_constant, gram)
1.660539060e-24*gram
转换为多个单位:
>>> convert_to(speed_of_light, [meter, second])
299792458*meter/second
>>> convert_to(3*newton, [centimeter, gram, second])
300000*centimeter*gram/second**2
转换为普朗克单位:
>>> convert_to(atomic_mass_constant, [gravitational_constant, speed_of_light, hbar]).n()
7.62963087839509e-20*hbar**0.5*speed_of_light**0.5/gravitational_constant**0.5
高能物理
伽玛矩阵
处理表示为张量对象的伽玛矩阵的模块。
示例
>>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G, LorentzIndex
>>> from sympy.tensor.tensor import tensor_indices
>>> i = tensor_indices('i', LorentzIndex)
>>> G(i)
GammaMatrix(i)
请注意,四维空间中已经存在一个 GammaMatrixHead 实例:GammaMatrix,它只需声明为
>>> from sympy.physics.hep.gamma_matrices import GammaMatrix
>>> from sympy.tensor.tensor import tensor_indices
>>> i = tensor_indices('i', LorentzIndex)
>>> GammaMatrix(i)
GammaMatrix(i)
访问度规张量
>>> LorentzIndex.metric
metric(LorentzIndex,LorentzIndex)
sympy.physics.hep.gamma_matrices.extract_type_tens(expression, component)
从 TensExpr
中提取所有具有 (component) 的张量。
返回两个张量表达式:
-
第一个包含所有
Tensor
具有 (component)。 -
第二个包含所有其余。
sympy.physics.hep.gamma_matrices.gamma_trace(t)
一行伽玛矩阵的痕迹
示例
>>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G, gamma_trace, LorentzIndex
>>> from sympy.tensor.tensor import tensor_indices, tensor_heads
>>> p, q = tensor_heads('p, q', [LorentzIndex])
>>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', LorentzIndex)
>>> ps = p(i0)*G(-i0)
>>> qs = q(i0)*G(-i0)
>>> gamma_trace(G(i0)*G(i1))
4*metric(i0, i1)
>>> gamma_trace(ps*ps) - 4*p(i0)*p(-i0)
0
>>> gamma_trace(ps*qs + ps*ps) - 4*p(i0)*p(-i0) - 4*p(i0)*q(-i0)
0
sympy.physics.hep.gamma_matrices.kahane_simplify(expression)
此函数取消四维伽玛矩阵乘积中的收缩元素,导致一个等于给定表达式的表达式,没有收缩的伽玛矩阵。
参数:
expression
包含要简化的伽玛矩阵的张量表达式。
注意事项
如果给出旋量指标,则矩阵必须按照乘积中给定的顺序给出。
算法
该算法背后的思想是使用一些众所周知的身份,即用于包围偶数个 (\gamma) 矩阵的收缩
(\gamma^\mu \gamma_{a_1} \cdots \gamma_{a_{2N}} \gamma_\mu = 2 (\gamma_{a_{2N}} \gamma_{a_1} \cdots \gamma_{a_{2N-1}} + \gamma_{a_{2N-1}} \cdots \gamma_{a_1} \gamma_{a_{2N}} ))
对于奇数个 (\gamma) 矩阵
(\gamma^\mu \gamma_{a_1} \cdots \gamma_{a_{2N+1}} \gamma_\mu = -2 \gamma_{a_{2N+1}} \gamma_{a_{2N}} \cdots \gamma_{a_{1}})
而不是重复应用这些身份来取消所有收缩的指数,可以识别这种操作将导致的链接,因此问题简化为自由伽玛矩阵的简单重新排列。
示例
使用时,请记住原始表达式的系数必须单独处理
>>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G, LorentzIndex
>>> from sympy.physics.hep.gamma_matrices import kahane_simplify
>>> from sympy.tensor.tensor import tensor_indices
>>> i0, i1, i2 = tensor_indices('i0:3', LorentzIndex)
>>> ta = G(i0)*G(-i0)
>>> kahane_simplify(ta)
Matrix([
[4, 0, 0, 0],
[0, 4, 0, 0],
[0, 0, 4, 0],
[0, 0, 0, 4]])
>>> tb = G(i0)*G(i1)*G(-i0)
>>> kahane_simplify(tb)
-2*GammaMatrix(i1)
>>> t = G(i0)*G(-i0)
>>> kahane_simplify(t)
Matrix([
[4, 0, 0, 0],
[0, 4, 0, 0],
[0, 0, 4, 0],
[0, 0, 0, 4]])
>>> t = G(i0)*G(-i0)
>>> kahane_simplify(t)
Matrix([
[4, 0, 0, 0],
[0, 4, 0, 0],
[0, 0, 4, 0],
[0, 0, 0, 4]])
如果没有收缩,将返回相同的表达式
>>> tc = G(i0)*G(i1)
>>> kahane_simplify(tc)
GammaMatrix(i0)*GammaMatrix(i1)
参考文献
[1] 降低伽玛矩阵收缩乘积的算法,Joseph Kahane,数学物理学杂志,第 9 卷,第 10 期,1968 年 10 月。
sympy.physics.hep.gamma_matrices.simplify_gpgp(ex, sort=True)
简化乘积 G(i)*p(-i)*G(j)*p(-j) -> p(i)*p(-i)
示例
>>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G, LorentzIndex, simplify_gpgp
>>> from sympy.tensor.tensor import tensor_indices, tensor_heads
>>> p, q = tensor_heads('p, q', [LorentzIndex])
>>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', LorentzIndex)
>>> ps = p(i0)*G(-i0)
>>> qs = q(i0)*G(-i0)
>>> simplify_gpgp(ps*qs*qs)
GammaMatrix(-L_0)*p(L_0)*q(L_1)*q(-L_1)
物理向量模块
物理/向量参考资料
[WikiDyadics]
“Dyadics.” Wikipedia, the Free Encyclopedia. Web. 05 Aug. 2011. <en.wikipedia.org/wiki/Dyadics
>.
[WikiDyadicProducts]
“Dyadic Product.” Wikipedia, the Free Encyclopedia. Web. 05 Aug. 2011. <en.wikipedia.org/wiki/Dyadic_product
>.
[Likins1973]
Likins, Peter W. Elements of Engineering Mechanics. McGraw-Hill, Inc. 1973. Print.
向量指南
-
向量与参考系
-
向量:运动学
-
物理/向量模块的潜在问题/高级主题/未来功能
-
标量和向量场功能
-
物理向量 API
-
基本类
-
运动学(文档字符串)
-
打印(文档字符串)
-
基本函数(文档字符串)
-
基本场函数文档字符串
-
向量与参考框架
原文链接:
docs.sympy.org/latest/modules/physics/vector/vectors.html
在sympy.physics.vector
中,向量和参考框架是动态系统的“基础”。本文档将从数学角度描述它们,并说明如何在此模块的代码中使用它们。
Vector
向量是具有大小(或长度)和方向的几何对象。在纸上,三维空间中的向量通常表示为:
向量代数
向量代数是首要讨论的主题。
如果两个向量具有相同的大小和方向,则它们被称为相等。
Vector Operations
可以对向量进行多种代数操作:向量之间的加法,标量乘法和向量乘法。
向量加法是基于平行四边形法则。
向量加法也是可交换的:
[\begin{split}\mathbf{a} + \mathbf{b} &= \mathbf{b} + \mathbf{a} \ (\mathbf{a} + \mathbf{b}) + \mathbf{c} &= \mathbf{a} + (\mathbf{b} + \mathbf{c})\end{split}]
标量乘法是向量与标量的乘积;结果是一个方向相同但大小按标量缩放的向量。注意,乘以-1 相当于围绕垂直于向量平面的任意轴旋转向量 180 度。
单位向量简单地说是其大小等于 1 的向量。对于任意向量(\mathbf{v}),我们可以定义一个单位向量:
[\mathbf{\hat{n}_v} = \frac{\mathbf{v}}{\Vert \mathbf{v} \Vert}]
注意,每个向量都可以写成标量和单位向量的乘积。
在sympy.physics.vector
中实现了三种向量积:点积、叉积和外积。
点积运算将两个向量映射到一个标量。它的定义如下:
[\begin{split}\mathbf{a} \cdot \mathbf{b} = \Vert \mathbf{a} \Vert \Vert \mathbf{b} \Vert \cos(\theta)\\end{split}]
其中(\theta)为(\mathbf{a})和(\mathbf{b})之间的角度。
两个单位向量的点积代表了共同方向的大小;对于其他向量,它是共同方向的大小和两个向量大小的乘积。两个垂直向量的点积为零。下图显示了一些示例:
点乘是交换的:
[\mathbf{a} \cdot \mathbf{b} = \mathbf{b} \cdot \mathbf{a}]
两个向量的叉乘向量乘法操作返回一个向量:
[\mathbf{a} \times \mathbf{b} = \mathbf{c}]
向量 (\mathbf{c}) 具有以下特性:它的方向与 (\mathbf{a}) 和 (\mathbf{b}) 垂直,其大小定义为 (\Vert \mathbf{c} \Vert = \Vert \mathbf{a} \Vert \Vert \mathbf{b} \Vert \sin(\theta))(其中 (\theta) 是 (\mathbf{a}) 和 (\mathbf{b}) 之间的角度),并且其方向由右手法则定义在 (\Vert \mathbf{a} \Vert \Vert \mathbf{b} \Vert) 之间。下图显示如下:
叉乘具有以下属性:
它不是交换的:
[\begin{split}\mathbf{a} \times \mathbf{b} &\neq \mathbf{b} \times \mathbf{a} \ \mathbf{a} \times \mathbf{b} &= - \mathbf{b} \times \mathbf{a}\end{split}]
并非可结合的:
[(\mathbf{a} \times \mathbf{b} ) \times \mathbf{c} \neq \mathbf{a} \times (\mathbf{b} \times \mathbf{c})]
两个平行向量的叉积为零。
两个向量的外积不在此讨论,而是在惯性部分(使用的地方)。其他有用的向量性质和关系包括:
[\begin{split}\alpha (\mathbf{a} + \mathbf{b}) &= \alpha \mathbf{a} + \alpha \mathbf{b}\ \mathbf{a} \cdot (\mathbf{b} + \mathbf{c}) &= \mathbf{a} \cdot \mathbf{b} + \mathbf{a} \cdot \mathbf{c}\ \mathbf{a} \times (\mathbf{b} + \mathbf{c}) &= \mathbf{a} \times \mathbf{b} + \mathbf{a} \times \mathbf{b}\ (\mathbf{a} \times \mathbf{b}) \cdot \mathbf{c} & \textrm{ 给出标量三重积。}\ \mathbf{a} \times (\mathbf{b} \cdot \mathbf{c}) & \textrm{ 不起作用,因为不能对向量和标量进行叉乘。}\ (\mathbf{a} \times \mathbf{b}) \cdot \mathbf{c} &= \mathbf{a} \cdot (\mathbf{b} \times \mathbf{c})\ (\mathbf{a} \times \mathbf{b}) \cdot \mathbf{c} &= (\mathbf{b} \times \mathbf{c}) \cdot \mathbf{a} = (\mathbf{c} \times \mathbf{a}) \cdot \mathbf{b}\ (\mathbf{a} \times \mathbf{b}) \times \mathbf{c} &= \mathbf{b}(\mathbf{a} \cdot \mathbf{c}) - \mathbf{a}(\mathbf{b} \cdot \mathbf{c})\ \mathbf{a} \times (\mathbf{b} \times \mathbf{c}) &= \mathbf{b}(\mathbf{a} \cdot \mathbf{c}) - \mathbf{c}(\mathbf{a} \cdot \mathbf{b})\\end{split}]
替代表示
如果我们有三个非共面的单位向量 (\mathbf{\hat{n}_x},\mathbf{\hat{n}_y},\mathbf{\hat{n}_z}),我们可以将任意向量 (\mathbf{a}) 表示为 (\mathbf{a} = a_x \mathbf{\hat{n}_x} + a_y \mathbf{\hat{n}_y} + a_z \mathbf{\hat{n}_z})。在这种情况下,(\mathbf{\hat{n}_x},\mathbf{\hat{n}_y},\mathbf{\hat{n}_z}) 被称为基底。(a_x, a_y, a_z) 被称为测量数。通常单位向量是相互垂直的,这时我们可以称它们为正交基,通常是右手的。
现在我们可以通过以下方式测试两个向量的相等性。对于向量:
[\begin{split}\mathbf{a} &= a_x \mathbf{\hat{n}_x} + a_y \mathbf{\hat{n}_y} + a_z \mathbf{\hat{n}_z}\ \mathbf{b} &= b_x \mathbf{\hat{n}_x} + b_y \mathbf{\hat{n}_y} + b_z \mathbf{\hat{n}_z}\\end{split}]
我们可以在以下情况下宣称相等:(a_x = b_x, a_y = b_y, a_z = b_z)。
同样的两个向量的向量加法表示为:
[\mathbf{a} + \mathbf{b} = (a_x + b_x)\mathbf{\hat{n}_x} + (a_y + b_y) \mathbf{\hat{n}_y} + (a_z + b_z) \mathbf{\hat{n}_z}]
现在定义乘法运算如下:
[\begin{split}\alpha \mathbf{b} &= \alpha b_x \mathbf{\hat{n}_x} + \alpha b_y \mathbf{\hat{n}_y} + \alpha b_z \mathbf{\hat{n}_z}\ \mathbf{a} \cdot \mathbf{b} &= a_x b_x + a_y b_y + a_z b_z\ \mathbf{a} \times \mathbf{b} &= \textrm{det }\begin{bmatrix} \mathbf{\hat{n}_x} & \mathbf{\hat{n}_y} & \mathbf{\hat{n}_z} \ a_x & a_y & a_z \ b_x & b_y & b_z \end{bmatrix}\ (\mathbf{a} \times \mathbf{b}) \cdot \mathbf{c} &= \textrm{det }\begin{bmatrix} a_x & a_y & a_z \ b_x & b_y & b_z \ c_x & c_y & c_z \end{bmatrix}\\end{split}]
要在给定的基础上写出一个向量,我们可以这样做:
[\begin{split}\mathbf{a} = (\mathbf{a}\cdot\mathbf{\hat{n}_x})\mathbf{\hat{n}_x} + (\mathbf{a}\cdot\mathbf{\hat{n}_y})\mathbf{\hat{n}_y} + (\mathbf{a}\cdot\mathbf{\hat{n}_z})\mathbf{\hat{n}_z}\\end{split}]
Examples
Some numeric examples of these operations follow:
[\begin{split}\mathbf{a} &= \mathbf{\hat{n}_x} + 5 \mathbf{\hat{n}_y}\ \mathbf{b} &= \mathbf{\hat{n}_y} + \alpha \mathbf{\hat{n}_z}\ \mathbf{a} + \mathbf{b} &= \mathbf{\hat{n}_x} + 6 \mathbf{\hat{n}_y} + \alpha \mathbf{\hat{n}_z}\ \mathbf{a} \cdot \mathbf{b} &= 5\ \mathbf{a} \cdot \mathbf{\hat{n}_y} &= 5\ \mathbf{a} \cdot \mathbf{\hat{n}_z} &= 0\ \mathbf{a} \times \mathbf{b} &= 5 \alpha \mathbf{\hat{n}_x} - \alpha \mathbf{\hat{n}_y} + \mathbf{\hat{n}_z}\ \mathbf{b} \times \mathbf{a} &= -5 \alpha \mathbf{\hat{n}_x} + \alpha \mathbf{\hat{n}_y} - \mathbf{\hat{n}_z}\\end{split}]
Vector Calculus
处理带有移动物体的向量微积分,我们必须引入参考框架的概念。一个经典的例子是火车沿着轨道运行,你和朋友都在里面。如果你和朋友都坐着,那么你们之间的相对速度为零。从火车外部的观察者来看,你们两个都会有速度。
我们现在将更严格地应用这一定义。一个参考框架是我们选择从中观察向量量的虚拟“平台”。如果我们有一个参考框架(\mathbf{N}),向量(\mathbf{a})在框架(\mathbf{N})中被认为是固定的,如果从(\mathbf{N})观察时它的任何特性都不会改变。我们通常会为每个参考框架分配一个固定的正交基向量集;(\mathbf{N})将具有(\mathbf{\hat{n}_x}, \mathbf{\hat{n}_y},\mathbf{\hat{n}_z})作为其基向量。
Derivatives of Vectors
一个在参考框架中不固定的向量,因此在从该框架观察时具有不同的特性。微积分是研究变化的学科,为了处理不同参考框架中固定和不固定向量的特殊性,我们需要在定义上更加明确。
在上图中,我们有向量 (\mathbf{c,d,e,f})。如果我们对 (\mathbf{e}) 求关于 (\theta) 的导数:
[\frac{d \mathbf{e}}{d \theta}]
目前尚不清楚导数是什么。如果你是从框架 (\mathbf{A}) 观察的话,导数显然不为零。如果你是从框架 (\mathbf{B}) 观察的话,导数为零。因此,我们将引入框架作为导数符号的一部分:
[\begin{split}\frac{^{\mathbf{A}} d \mathbf{e}}{d \theta} &\neq 0 \textrm{,在参考框架 } \mathbf{A} \textrm{ 中,} \mathbf{e} \textrm{ 对 } \theta \textrm{ 的导数不为零。}\ \frac{^{\mathbf{B}} d \mathbf{e}}{d \theta} &= 0 \textrm{,在参考框架 } \mathbf{B} \textrm{ 中,} \mathbf{e} \textrm{ 对 } \theta \textrm{ 的导数为零。}\ \frac{^{\mathbf{A}} d \mathbf{c}}{d \theta} &= 0 \textrm{,在参考框架 } \mathbf{A} \textrm{ 中,} \mathbf{c} \textrm{ 对 } \theta \textrm{ 的导数为零。}\ \frac{^{\mathbf{B}} d \mathbf{c}}{d \theta} &\neq 0 \textrm{,在参考框架 } \mathbf{B} \textrm{ 中,} \mathbf{c} \textrm{ 对 } \theta \textrm{ 的导数不为零。}\\end{split}]
下面是特定参考框架中向量导数的一些额外性质:
[\begin{split}\frac{^{\mathbf{A}} d}{dt}(\mathbf{a} + \mathbf{b}) &= \frac{^{\mathbf{A}} d\mathbf{a}}{dt} + \frac{^{\mathbf{A}} d\mathbf{b}}{dt}\ \frac{^{\mathbf{A}} d}{dt}\gamma \mathbf{a} &= \frac{ d \gamma}{dt}\mathbf{a} + \gamma\frac{^{\mathbf{A}} d\mathbf{a}}{dt}\ \frac{^{\mathbf{A}} d}{dt}(\mathbf{a} \times \mathbf{b}) &= \frac{^{\mathbf{A}} d\mathbf{a}}{dt} \times \mathbf{b} + \mathbf{a} \times \frac{^{\mathbf{A}} d\mathbf{b}}{dt}\\end{split}]
关联基向量集合
现在我们需要定义两个不同参考框架之间的关系;或者如何将一个框架的基向量与另一个框架的基向量相关联。我们可以使用方向余弦矩阵(DCM)来实现这一点。方向余弦矩阵将一个框架的基向量与另一个框架的基向量相关联,如下所示:
[\begin{split}\begin{bmatrix} \mathbf{\hat{a}_x} \ \mathbf{\hat{a}_y} \ \mathbf{\hat{a}_z} \ \end{bmatrix} = \begin{bmatrix} ^{\mathbf{A}} \mathbf{C}^{\mathbf{B}} \end{bmatrix} \begin{bmatrix} \mathbf{\hat{b}_x} \ \mathbf{\hat{b}_y} \ \mathbf{\hat{b}_z} \ \end{bmatrix}\end{split}]
当两个框架(比如 (\mathbf{A}) 和 (\mathbf{B}))最初对齐时,其中一个框架的所有基向量围绕与一个基向量对齐的轴旋转,我们称这些框架通过简单旋转相关联。下图展示了这一点:
上述旋转是绕 Z 轴简单旋转,角度为 (\theta)。请注意,在旋转后,基向量 (\mathbf{\hat{a}_z}) 和 (\mathbf{\hat{b}_z}) 仍然对齐。
这个旋转可以由以下方向余弦矩阵来表征:
[\begin{split}{\mathbf{A}}\mathbf{C}{\mathbf{B}} = \begin{bmatrix} \cos(\theta) & - \sin(\theta) & 0\ \sin(\theta) & \cos(\theta) & 0\ 0 & 0 & 1\ \end{bmatrix}\end{split}]
简单的绕 X 和 Y 轴的旋转由以下方式定义:
[ \begin{align}\begin{aligned}\begin{split}\textrm{绕 x 轴旋转的 DCM: } \begin{bmatrix} 1 & 0 & 0\ 0 & \cos(\theta) & -\sin(\theta)\ 0 & \sin(\theta) & \cos(\theta) \end{bmatrix}\end{split}\\begin{split}\textrm{绕 y 轴旋转的 DCM: } \begin{bmatrix} \cos(\theta) & 0 & \sin(\theta)\ 0 & 1 & 0\ -\sin(\theta) & 0 & \cos(\theta)\ \end{bmatrix}\end{split}\end{aligned}\end{align} ]
正方向的旋转通过右手规则定义。
方向余弦矩阵还涉及到基向量组之间点积的定义。如果我们有两个带有关联基向量的参考坐标系,它们的方向余弦矩阵可以定义为:
[\begin{split}\begin{bmatrix} C_{xx} & C_{xy} & C_{xz}\ C_{yx} & C_{yy} & C_{yz}\ C_{zx} & C_{zy} & C_{zz}\ \end{bmatrix} = \begin{bmatrix} \mathbf{\hat{a}_x}\cdot\mathbf{\hat{b}_x} & \mathbf{\hat{a}_x}\cdot\mathbf{\hat{b}_y} & \mathbf{\hat{a}_x}\cdot\mathbf{\hat{b}_z}\ \mathbf{\hat{a}_y}\cdot\mathbf{\hat{b}_x} & \mathbf{\hat{a}_y}\cdot\mathbf{\hat{b}_y} & \mathbf{\hat{a}_y}\cdot\mathbf{\hat{b}_z}\ \mathbf{\hat{a}_z}\cdot\mathbf{\hat{b}_x} & \mathbf{\hat{a}_z}\cdot\mathbf{\hat{b}_y} & \mathbf{\hat{a}_z}\cdot\mathbf{\hat{b}_z}\ \end{bmatrix}\end{split}]
此外,方向余弦矩阵是正交的,即:
[\begin{split}{\mathbf{A}}\mathbf{C}{\mathbf{B}} = ({\mathbf{B}}\mathbf{C}{\mathbf{A}})^{-1}\ = ({\mathbf{B}}\mathbf{C}{\mathbf{A}})^T\\end{split}]
如果我们有参考坐标系 (\mathbf{A}) 和 (\mathbf{B}),在这个例子中经历了简单的绕 Z 轴旋转,旋转角度为 (\theta),我们将会有两组基向量。然后我们可以定义两个向量:(\mathbf{a} = \mathbf{\hat{a}_x} + \mathbf{\hat{a}_y} + \mathbf{\hat{a}_z}) 和 (\mathbf{b} = \mathbf{\hat{b}_x} + \mathbf{\hat{b}_y} + \mathbf{\hat{b}_z})。如果我们希望在 (\mathbf{A}) 坐标系中表达 (\mathbf{b}),我们执行以下操作:
[\begin{split}\mathbf{b} &= \mathbf{\hat{b}_x} + \mathbf{\hat{b}_y} + \mathbf{\hat{b}_z}\ \mathbf{b} &= \begin{bmatrix}\mathbf{\hat{a}_x}\cdot (\mathbf{\hat{b}_x} + \mathbf{\hat{b}_y} + \mathbf{\hat{b}_z})\end{bmatrix} \mathbf{\hat{a}_x} + \begin{bmatrix}\mathbf{\hat{a}_y}\cdot (\mathbf{\hat{b}_x} + \mathbf{\hat{b}_y} + \mathbf{\hat{b}_z})\end{bmatrix} \mathbf{\hat{a}_y} + \begin{bmatrix}\mathbf{\hat{a}_z}\cdot (\mathbf{\hat{b}_x} + \mathbf{\hat{b}_y} + \mathbf{\hat{b}_z})\end{bmatrix} \mathbf{\hat{a}_z}\ \mathbf{b} &= (\cos(\theta) - \sin(\theta))\mathbf{\hat{a}_x} + (\sin(\theta) + \cos(\theta))\mathbf{\hat{a}_y} + \mathbf{\hat{a}_z}\end{split}]
如果我们希望在B中表示(\mathbf{a}),我们可以这样做:
[\begin{split}\mathbf{a} &= \mathbf{\hat{a}_x} + \mathbf{\hat{a}_y} + \mathbf{\hat{a}_z}\ \mathbf{a} &= \begin{bmatrix}\mathbf{\hat{b}_x}\cdot (\mathbf{\hat{a}_x} + \mathbf{\hat{a}_y} + \mathbf{\hat{a}_z})\end{bmatrix} \mathbf{\hat{b}_x} + \begin{bmatrix}\mathbf{\hat{b}_y}\cdot (\mathbf{\hat{a}_x} + \mathbf{\hat{a}_y} + \mathbf{\hat{a}_z})\end{bmatrix} \mathbf{\hat{b}_y} + \begin{bmatrix}\mathbf{\hat{b}_z}\cdot (\mathbf{\hat{a}_x} + \mathbf{\hat{a}_y} + \mathbf{\hat{a}_z})\end{bmatrix} \mathbf{\hat{b}_z}\ \mathbf{a} &= (\cos(\theta) + \sin(\theta))\mathbf{\hat{b}_x} + (-\sin(\theta)+\cos(\theta))\mathbf{\hat{b}_y} + \mathbf{\hat{b}_z}\end{split}]
多个参考系下的导数
如果我们有参考系A和B,我们将会有两组基向量。然后我们可以定义两个向量:(\mathbf{a} = a_x\mathbf{\hat{a}_x} + a_y\mathbf{\hat{a}_y} + a_z\mathbf{\hat{a}_z}) 和 (\mathbf{b} = b_x\mathbf{\hat{b}_x} + b_y\mathbf{\hat{b}_y} + b_z\mathbf{\hat{b}_z})。如果我们想要在参考系A中对(\mathbf{b})进行导数运算,我们必须首先在A中表示它,然后对测量数字进行导数运算:
[\frac{^{\mathbf{A}} d\mathbf{b}}{dx} = \frac{d (\mathbf{b}\cdot \mathbf{\hat{a}_x} )}{dx} \mathbf{\hat{a}_x} + \frac{d (\mathbf{b}\cdot \mathbf{\hat{a}_y} )}{dx} \mathbf{\hat{a}_y} + \frac{d (\mathbf{b}\cdot \mathbf{\hat{a}_z} )}{dx} \mathbf{\hat{a}_z} +]
向量微积分的示例
一个矢量微积分的例子:
在本例中,我们有两个物体,每个物体都有一个附加的参考框架。我们将(\theta)和(x)视为时间的函数。我们希望知道向量(\mathbf{c})在(\mathbf{A})和(\mathbf{B})框架中的时间导数。
首先,我们需要定义(\mathbf{c});(\mathbf{c}=x\mathbf{\hat{b}_x}+l\mathbf{\hat{b}_y})。这在(\mathbf{B})框架中提供了一个定义。现在我们可以执行以下操作:
[\begin{split}\frac{^{\mathbf{B}} d \mathbf{c}}{dt} &= \frac{dx}{dt} \mathbf{\hat{b}_x} + \frac{dl}{dt} \mathbf{\hat{b}_y}\ &= \dot{x} \mathbf{\hat{b}_x}\end{split}]
要在(\mathbf{A})框架中进行导数运算,我们必须首先将这两个框架联系起来:
[\begin{split}^{\mathbf{A}} \mathbf{C} ^{\mathbf{B}} = \begin{bmatrix} \cos(\theta) & 0 & \sin(\theta)\ 0 & 1 & 0\ -\sin(\theta) & 0 & \cos(\theta)\ \end{bmatrix}\end{split}]
现在我们可以执行以下操作:
[\begin{split}\frac{^{\mathbf{A}} d \mathbf{c}}{dt} &= \frac{d (\mathbf{c} \cdot \mathbf{\hat{a}_x})}{dt} \mathbf{\hat{a}_x} + \frac{d (\mathbf{c} \cdot \mathbf{\hat{a}_y})}{dt} \mathbf{\hat{a}_y} + \frac{d (\mathbf{c} \cdot \mathbf{\hat{a}_z})}{dt} \mathbf{\hat{a}_z}\ &= \frac{d (\cos(\theta) x)}{dt} \mathbf{\hat{a}_x} + \frac{d (l)}{dt} \mathbf{\hat{a}_y} + \frac{d (-\sin(\theta) x)}{dt} \mathbf{\hat{a}_z}\ &= (-\dot{\theta}\sin(\theta)x + \cos(\theta)\dot{x}) \mathbf{\hat{a}_x} + (\dot{\theta}\cos(\theta)x + \sin(\theta)\dot{x}) \mathbf{\hat{a}_z}\end{split}]
注意,这是(\mathbf{A})框架中(\mathbf{c})的时间导数,并以(\mathbf{A})框架表达。然而,我们也可以在(\mathbf{B})框架中表达它,并且表达式仍然有效:
[\begin{split}\frac{^{\mathbf{A}} d \mathbf{c}}{dt} &= (-\dot{\theta}\sin(\theta)x + \cos(\theta)\dot{x}) \mathbf{\hat{a}_x} + (\dot{\theta}\cos(\theta)x + \sin(\theta)\dot{x}) \mathbf{\hat{a}_z}\ &= \dot{x}\mathbf{\hat{b}_x} - \theta x \mathbf{\hat{b}_z}\\end{split}]
注意两种表达形式在复杂度上的差异。它们是等价的,但其中一种要简单得多。这是一个非常重要的概念,因为在更复杂的形式中定义向量可能会大大减慢动力学方程的制定并增加其长度,有时甚至无法在屏幕上显示。
使用向量和参考框架
在所有相关数学关系被定义之后,我们才引入代码。这是由于向量的形成方式。在开始任何问题之前,必须定义一个参考框架(记得首先导入sympy.physics.vector
):
>>> from sympy.physics.vector import *
>>> N = ReferenceFrame('N')
现在我们已经创建了一个参考框架(\mathbf{N})。要访问任何基向量,首先需要创建一个参考框架。现在我们已经创建了表示(\mathbf{N})的对象,我们可以访问它的基向量:
>>> N.x
N.x
>>> N.y
N.y
>>> N.z
N.z
物理向量中的向量代数
现在我们可以对这些向量进行基本的代数运算。
>>> N.x == N.x
True
>>> N.x == N.y
False
>>> N.x + N.y
N.x + N.y
>>> 2 * N.x + N.y
2*N.x + N.y
记住,不要将标量数量添加到向量中(N.x + 5
);这将引发错误。在此时,我们将在我们的向量中使用 SymPy 的符号。在处理符号时,请记住参考 SymPy 的陷阱和问题。
>>> from sympy import Symbol, symbols
>>> x = Symbol('x')
>>> x * N.x
x*N.x
>>> x*(N.x + N.y)
x*N.x + x*N.y
在sympy.physics.vector
中,已经实现了多个接口来进行矢量乘法,包括操作符级别、方法级别和函数级别。矢量点乘可以如下工作:
>>> N.x.dot(N.x)
1
>>> N.x.dot(N.y)
0
>>> dot(N.x, N.x)
1
>>> dot(N.x, N.y)
0
“官方”接口是函数接口;这是所有示例中将使用的内容。这是为了避免混淆,使属性和方法彼此紧邻,并且在操作符操作优先级的情况下。在sympy.physics.vector
中用于矢量乘法的操作符没有正确的操作顺序;这可能导致错误。在使用操作符表示矢量乘法时,需要注意括号。
叉乘是另一种将讨论的矢量乘法。它提供了与点乘类似的接口,并伴随着相同的警告。
>>> N.x.cross(N.x)
0
>>> N.x.cross(N.z)
- N.y
>>> cross(N.x, N.y)
N.z
>>> cross(N.x, (N.y + N.z))
- N.y + N.z
向量还可以进行两种额外的操作:将向量归一化为长度 1,以及获取其大小。操作如下进行:
>>> (N.x + N.y).normalize()
sqrt(2)/2*N.x + sqrt(2)/2*N.y
>>> (N.x + N.y).magnitude()
sqrt(2)
向量通常以矩阵形式表达,特别是在数值计算中。由于矩阵形式不包含向量所定义的参考框架的任何信息,因此必须提供参考框架以从向量中提取测量数。有一个方便的函数可以实现这一点:
>>> (x * N.x + 2 * x * N.y + 3 * x * N.z).to_matrix(N)
Matrix([
[ x],
[2*x],
[3*x]])
物理向量中的矢量微积分
我们已经介绍了我们的第一个参考框架。如果我们愿意,我们可以在该框架中立即进行微分:
>>> (x * N.x + N.y).diff(x, N)
N.x
SymPy 有一个diff
函数,但它目前无法与sympy.physics.vector
中的向量一起使用,请使用Vector
的diff
方法。原因在于,在对Vector
进行微分时,除了对什么进行微分外,还必须指定参考坐标系;SymPy 的diff
函数不适合这种情况。
更有趣的情况出现在多个参考框架中。如果我们引入第二个参考框架(\mathbf{A}),我们现在有了两个框架。请注意,此时我们可以添加(\mathbf{N})和(\mathbf{A})的分量,但不能执行矢量乘法,因为尚未定义两个框架之间的关系。
>>> A = ReferenceFrame('A')
>>> A.x + N.x
N.x + A.x
如果我们想进行矢量乘法,首先必须定义一个方向。ReferenceFrame
的orient
方法提供了这个功能。
>>> A.orient(N, 'Axis', [x, N.y])
通过简单的绕 Y 轴旋转的方式,将(\mathbf{A})框架相对于(\mathbf{N})框架进行定位,旋转量为 x。这两个框架之间的方向余弦矩阵可以随时通过dcm
方法查看:A.dcm(N)
给出了方向余弦矩阵 (^{\mathbf{A}} \mathbf{C} ^{\mathbf{N}})。
其他更复杂的旋转类型包括体旋转、空间旋转、四元数和任意轴旋转。体和空间旋转等效于连续进行三个简单旋转,每个旋转围绕新框架中的基向量。以下是一个例子:
>>> N = ReferenceFrame('N')
>>> Bp = ReferenceFrame('Bp')
>>> Bpp = ReferenceFrame('Bpp')
>>> B = ReferenceFrame('B')
>>> q1,q2,q3 = symbols('q1 q2 q3')
>>> Bpp.orient(N,'Axis', [q1, N.x])
>>> Bp.orient(Bpp,'Axis', [q2, Bpp.y])
>>> B.orient(Bp,'Axis', [q3, Bp.z])
>>> N.dcm(B)
Matrix([
[ cos(q2)*cos(q3), -sin(q3)*cos(q2), sin(q2)],
[sin(q1)*sin(q2)*cos(q3) + sin(q3)*cos(q1), -sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), -sin(q1)*cos(q2)],
[sin(q1)*sin(q3) - sin(q2)*cos(q1)*cos(q3), sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2)]])
>>> B.orient(N,'Body',[q1,q2,q3],'XYZ')
>>> N.dcm(B)
Matrix([
[ cos(q2)*cos(q3), -sin(q3)*cos(q2), sin(q2)],
[sin(q1)*sin(q2)*cos(q3) + sin(q3)*cos(q1), -sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), -sin(q1)*cos(q2)],
[sin(q1)*sin(q3) - sin(q2)*cos(q1)*cos(q3), sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2)]])
空间方向与体方向类似,但是应用于从框架到体。体和空间旋转可以涉及两个或三个轴:‘XYZ’适用,‘YZX’、‘ZXZ’、‘YXY’等也适用。关键在于每个简单旋转是围绕不同轴进行的,与前一个不同;‘ZZX’不能完全定向一个三维空间的基向量集。
有时,创建一个新的参考框架并在一步中相对于现有框架进行定向会更方便。orientnew
方法允许此功能,并且本质上包装了orient
方法。在orient
中可以做的所有事情,在orientnew
中也可以做到。
>>> C = N.orientnew('C', 'Axis', [q1, N.x])
四元数(或欧拉参数)使用 4 个值来描述框架的方向。这些内容以及任意轴旋转可以在orient
和orientnew
方法的帮助下找到,或者在参考文献[Kane1983]中了解。
最后,在开始多框架计算操作之前,我们将介绍另一个sympy.physics.vector
工具:dynamicsymbols
。dynamicsymbols
是在 SymPy 中创建时间未定义函数的快捷方式。这样一个‘dynamicsymbol’的导数如下所示。
>>> from sympy import diff
>>> q1, q2, q3 = dynamicsymbols('q1 q2 q3')
>>> diff(q1, Symbol('t'))
Derivative(q1(t), t)
上面的‘dynamicsymbol’打印结果不太清晰;我们还将在这里介绍其他一些工具。在非交互式会话中,我们可以使用vprint
代替 print。
>>> q1
q1(t)
>>> q1d = diff(q1, Symbol('t'))
>>> vprint(q1)
q1
>>> vprint(q1d)
q1'
对于交互式会话,请使用init_vprinting
。SymPy 的vprint
、vpprint
、latex
和vlatex
也存在类似的模拟。
>>> from sympy.physics.vector import init_vprinting
>>> init_vprinting(pretty_print=False)
>>> q1
q1
>>> q1d
q1'
在sympy.physics.vector
中,任何时间变化的量都应使用‘dynamicsymbol’来表示,无论是坐标、变化的位置还是力量。‘dynamicsymbol’的主要用途是用于速度和坐标(在文档的运动学部分将有更多讨论)。
现在我们将用一个‘dynamicsymbol’定义我们新框架的方向,并且可以轻松地进行导数和时间导数。以下是一些例子。
>>> N = ReferenceFrame('N')
>>> B = N.orientnew('B', 'Axis', [q1, N.x])
>>> (B.y*q2 + B.z).diff(q2, N)
B.y
>>> (B.y*q2 + B.z).dt(N)
(-q1' + q2')*B.y + q2*q1'*B.z
注意,输出向量保持了它们提供时所在的框架不变。对于由多个框架的基向量组成分量的向量,这一点仍然成立:
>>> (B.y*q2 + B.z + q2*N.x).diff(q2, N)
N.x + B.y
向量的编码方式
接下来是如何在sympy.physics.vector
中的代码中定义向量的简要说明。这是为了那些想要了解此部分如何工作的人提供的,不需要阅读它就可以使用此模块;除非您想了解如何实现此模块,否则不要阅读它。
每个Vector
的主要信息存储在args
属性中,该属性为每个相关帧中的每个基向量存储三个测量数。在创建ReferenceFrame
之前,代码中不存在向量。此时,参考框架的x
、y
和z
属性是不可变的Vector
,其测量数分别为[1,0,0]、[0,1,0]和[0,0,1]。一旦可以访问这些向量,可以通过使用基向量进行代数运算来创建新向量。向量可以具有多个帧的分量。这就是为什么args
是一个列表的原因;它的列表长度等于其组件中唯一ReferenceFrames
的数量,即如果我们的新向量中有A
和B
帧基向量,则args
的长度为 2;如果它有A
、B
和C
帧基向量,则args
的长度为 3。
args
列表中的每个元素都是一个 2 元组;第一个元素是 SymPy Matrix
(存储每组基向量的测量数),第二个元素是ReferenceFrame
,用于将这些测量数与之关联。
ReferenceFrame
存储了几个东西。首先,它存储您在创建时提供的名称(name
属性)。它还存储方向余弦矩阵,使用orientnew
方法在创建时定义,或在创建后调用orient
方法。方向余弦矩阵由 SymPy 的Matrix
表示,并且是一个字典的一部分,其中键是ReferenceFrame
,值是Matrix
;这些设置是双向的;当您将A
定向到N
时,您设置了A
的方向字典,以包括N
及其Matrix
,但您也设置了N
的方向字典,以包括A
及其Matrix
(该 DCM 是另一个的转置)。
向量:运动学
原文链接:
docs.sympy.org/latest/modules/physics/vector/kinematics.html
本文将为描述系统运动学背景及如何在sympy.physics.vector
中表示运动学提供一些数学背景。
运动学介绍
第一个主题是刚体运动学。刚体是具有质量和转动惯量的物理对象的理想化表示。显然,刚体不是柔软的。我们可以将刚体运动分解为平移运动和旋转运动(在处理粒子时,我们只有平移运动)。旋转运动可以进一步分解为简单旋转和一般旋转。
刚体的平移是指在运动过程中,物体的方向不会改变;或者在运动过程中,任何线段在运动开始时都将保持平行于自身。
简单旋转是指物体的方向可能会改变,但总有一条线段在运动开始时保持平行于自身。
一般旋转是指在运动开始时并不总有一条线段平行于自身。
角速度
刚体的角速度是指其方向变化率。刚体的角速度写为:({\mathbf{N}}\mathbf{\omega}{\mathbf{B}}),或者是(\mathbf{B})在(\mathbf{N})中的角速度,它是一个向量。请注意,这里使用了刚体这个术语,但参考系也可以有角速度。在描述代码表示时,稍后将进一步讨论刚体和参考系之间的区别。
角速度被定义为引起方向角增加的方向上为正(对于简单旋转或一系列简单旋转)。
角速度矢量表示方向的时间导数。作为时间导数矢量量,就像矢量和参考框架文档中所涵盖的那些一样,这个量(角速度)需要在一个参考框架中定义。这就是上述角速度定义中的 (\mathbf{N});角速度在其中定义的框架。
(\mathbf{N}) 中的 (\mathbf{B}) 的角速度也可以定义为:
[{\mathbf{N}}\mathbf{\omega}{\mathbf{B}} = (\frac{^{\mathbf{N}}d \mathbf{\hat{b}_y}}{dt}\cdot\mathbf{\hat{b}_z} )\mathbf{\hat{b}_x} + (\frac{^{\mathbf{N}}d \mathbf{\hat{b}_z}}{dt}\cdot \mathbf{\hat{b}_x})\mathbf{\hat{b}_y} + (\frac{^{\mathbf{N}}d \mathbf{\hat{b}_x}}{dt}\cdot\mathbf{\hat{b}_y})\mathbf{\hat{b}_z}]
一个物体的角速度通常也可以写成:
[{\mathbf{N}}\mathbf{\omega}{\mathbf{B}} = w_x \mathbf{\hat{b}_x} + w_y \mathbf{\hat{b}_y} + w_z \mathbf{\hat{b}_z}]
关于角速度还有一些额外重要的点。首先是角速度的加法定理,一种关联多个物体和参考系角速度的方式。该定理如下:
[{\mathbf{N}}\mathbf{\omega}{\mathbf{D}} = {\mathbf{N}}\mathbf{\omega}{\mathbf{A}} + {\mathbf{A}}\mathbf{\omega}{\mathbf{B}} + {\mathbf{B}}\mathbf{\omega}{\mathbf{C}} + {\mathbf{C}}\mathbf{\omega}{\mathbf{D}}]
这也可以在以下示例中看到:
[\begin{split}{\mathbf{N}}\mathbf{\omega}{\mathbf{A}} &= 0\ {\mathbf{A}}\mathbf{\omega}{\mathbf{B}} &= \dot{q_1} \mathbf{\hat{a}_x}\ {\mathbf{B}}\mathbf{\omega}{\mathbf{C}} &= - \dot{q_2} \mathbf{\hat{b}_z}\ {\mathbf{C}}\mathbf{\omega}{\mathbf{D}} &= \dot{q_3} \mathbf{\hat{c}_y}\ {\mathbf{N}}\mathbf{\omega}{\mathbf{D}} &= \dot{q_1} \mathbf{\hat{a}_x} - \dot{q_2} \mathbf{\hat{b}_z} + \dot{q_3} \mathbf{\hat{c}_y}\\end{split}]
注意角速度定义中使用的符号,这些符号与在这种情况下如何定义位移角有关。
该定理使得定义多体系统的角速度变得更加简单,因为链中每个体的角速度只需相对于前一个体定义即可(并且第一个体需要在所需的参考系中定义)。下图展示了使用该定理可以简化问题的示例。
在这里,我们可以轻松地写出物体(\mathbf{D})在第一个物体(\mathbf{A})的参考系中的角速度:
[\begin{split}\mathbf{A}\mathbf{\omega}\mathbf{D} = w_1 \mathbf{\hat{p_1}} + w_2 \mathbf{\hat{p_2}} + w_3 \mathbf{\hat{p_3}}\\end{split}]
记住,只能用于角速度;不能用于点的速度。
还有一个常用的定理:导数定理。它提供了一种替代方法(可能更容易)来计算参考系中向量的时间导数:
[\frac{^{\mathbf{N}} d \mathbf{v}}{dt} = \frac{^{\mathbf{B}} d \mathbf{v}}{dt} + {\mathbf{N}}\mathbf{\omega}{\mathbf{B}} \times \mathbf{v}]
向量(\mathbf{v})可以是任何向量量:位置向量,速度向量,角速度向量等。而不是在(\mathbf{N})中取向量的时间导数,我们在(\mathbf{B})中取它,其中(\mathbf{B})可以是任何参考系或物体,通常是在其中容易对(\mathbf{v})取导数的一个。然后我们加上我们新参考系的角速度的叉乘积,({\mathbf{N}}\mathbf{\omega}{\mathbf{B}}) 和我们的向量量(\mathbf{v})。同样,你可以为此选择任何替代参考系。以下是例子:
角加速度
角加速度指的是角速度向量的时间变化率。正如角速度向量是对于一个物体的,并且在一个参考系中指定一样,角加速度向量也是对于一个物体的,并且在一个参考系中指定:({\mathbf{N}}\mathbf{\alpha}{\mathbf{B}}),或者是(\mathbf{B})在(\mathbf{N})中的角加速度,这是一个向量。
计算角加速度相对直接了当:
[{\mathbf{N}}\mathbf{\alpha}{\mathbf{B}} = \frac{^{\mathbf{N}} d {\mathbf{N}}\mathbf{\omega}{\mathbf{B}}}{dt}]
注意,可以用导数定理计算这个,当角速度在一个固定于物体的参考系中定义时,变得相当简单:
[ \begin{align}\begin{aligned}\begin{split}{\mathbf{N}}\mathbf{\alpha}{\mathbf{B}} &= \frac{^{\mathbf{N}} d {\mathbf{N}}\mathbf{\omega}{\mathbf{B}}}{dt}\\end{split}\\begin{split}{\mathbf{N}}\mathbf{\alpha}{\mathbf{B}} &= \frac{^{\mathbf{B}} d {\mathbf{N}}\mathbf{\omega}{\mathbf{B}}}{dt} + {\mathbf{N}}\mathbf{\omega}{\mathbf{B}} \times {\mathbf{N}}\mathbf{\omega}{\mathbf{B}}\\end{split}\\begin{split}\textrm{如果 } {\mathbf{N}}\mathbf{\omega}{\mathbf{B}} &= w_x \mathbf{\hat{b}_x} + w_y \mathbf{\hat{b}_y} + w_z \mathbf{\hat{b}z}\\end{split}\\begin{split}\textrm{那么 } {\mathbf{N}}\mathbf{\alpha}{\mathbf{B}} &= \frac{^{\mathbf{B}} d {\mathbf{N}}\mathbf{\omega}{\mathbf{B}}}{dt} + \underbrace{{\mathbf{N}}\mathbf{\omega}{\mathbf{B}} \times {\mathbf{N}}\mathbf{\omega}{\mathbf{B}}}{ \textrm{根据定义,这是 0}}\\end{split}\\begin{split}{\mathbf{N}}\mathbf{\alpha}{\mathbf{B}}&=\frac{d w_x}{dt}\mathbf{\hat{b}_x} + \frac{d w_y}{dt}\mathbf{\hat{b}_y} + \frac{d w_z}{dt}\mathbf{\hat{b}_z}\\end{split}\\begin{split}{\mathbf{N}}\mathbf{\alpha}{\mathbf{B}}&= \dot{w_x}\mathbf{\hat{b}_x} + \dot{w_y}\mathbf{\hat{b}_y} + \dot{w_z}\mathbf{\hat{b}_z}\\end{split}\end{aligned}\end{align} ]
再次强调,这仅适用于身体固定分量定义了角速度的情况。
点速度与加速度
考虑一个点 (P):我们可以定义该点的一些特性。首先,我们可以定义从其他点到 (P) 的位置矢量。其次,我们可以定义 (P) 在我们选择的参考系中的速度矢量。第三,我们可以定义 (P) 在我们选择的参考系中的加速度矢量。
这三个量读作:
[\begin{split}\mathbf{r}^{OP} \textrm{,从 } O \textrm{ 到 } P \textrm{ 的位置矢量}\ {\mathbf{N}}\mathbf{v}P \textrm{,点 } P \textrm{ 在参考系 } \mathbf{N} \textrm{ 中的速度}\ {\mathbf{N}}\mathbf{a}P \textrm{,点 } P \textrm{ 在参考系 } \mathbf{N} \textrm{ 中的加速度}\\end{split}]
注意,位置矢量没有与之关联的参考系;这是因为与速度和加速度矢量不同,它没有涉及时间导数。
对于一个简单的例子,我们可以轻松找到这些量。
[\begin{split}\textrm{Let's define: } \mathbf{r}^{OP} &= q_x \mathbf{\hat{n}_x} + q_y \mathbf{\hat{n}_y}\ {\mathbf{N}}\mathbf{v}P &= \frac{^{\mathbf{N}} d \mathbf{r}^{OP}}{dt}\ \textrm{then we can calculate: } {\mathbf{N}}\mathbf{v}P &= \dot{q}_x\mathbf{\hat{n}_x} + \dot{q}_y\mathbf{\hat{n}_y}\ \textrm{and :} {\mathbf{N}}\mathbf{a}P &= \frac{^{\mathbf{N}} d {\mathbf{N}}\mathbf{v}P}{dt}\ {\mathbf{N}}\mathbf{a}P &= \ddot{q}_x\mathbf{\hat{n}_x} + \ddot{q}_y\mathbf{\hat{n}_y}\\end{split}]
- 上述例子中,理解点 (O) 在参考系 (\mathbf{N}) 中固定是至关重要的。对于平移速度没有加法定理;后续将讨论替代方法。同时注意,不一定需要定义每个点的位置矢量来形成动力学运动方程。当你不想定义一个点的位置矢量时,可以先定义速度矢量。对于上述例子:
[\begin{split}\textrm{我们可以将速度向量定义为: } {\mathbf{N}}\mathbf{v}P &= u_x \mathbf{\hat{n}_x} + u_y \mathbf{\hat{n}_y}\ \textrm{那么加速度可以写为: } {\mathbf{N}}\mathbf{a}P &= \dot{u}_x \mathbf{\hat{n}_x} + \dot{u}_y \mathbf{\hat{n}_y}\\end{split}]
- 通常情况下,我们需要一个点的速度,同时已知相关点的速度。对于刚体上两个固定点的情况,我们使用 2 点定理:
假设我们知道点(S)的速度和物体(\mathbf{B})的角速度,两者均定义在参考系(\mathbf{N})中。我们可以计算点(P)在(\mathbf{N})中的速度和加速度如下:
[\begin{split}{\mathbf{N}}\mathbf{v}P &= \mathbf{N}\mathbf{v}S + \mathbf{N}\mathbf{\omega}\mathbf{B} \times \mathbf{r}^{SP}\ {\mathbf{N}}\mathbf{a}P &= \mathbf{N}\mathbf{a}S + \mathbf{N}\mathbf{\alpha}\mathbf{B} \times \mathbf{r}^{SP} + \mathbf{N}\mathbf{\omega}\mathbf{B} \times (\mathbf{N}\mathbf{\omega}\mathbf{B} \times \mathbf{r}^{SP})\\end{split}]
当两点中只有一个固定在物体上时,使用 1 点定理。
在这里,点(S)的速度在参考系(\mathbf{N})中已知,(\mathbf{B})的角速度在(\mathbf{N})中已知,并且点(P)在与刚体(\mathbf{B})相关联的参考系中的速度也已知。因此,我们可以写出点(P)在(\mathbf{N})中的速度和加速度:
[ \begin{align}\begin{aligned}\begin{split}{\mathbf{N}}\mathbf{v}P &= \mathbf{B}\mathbf{v}P + \mathbf{N}\mathbf{v}S + \mathbf{N}\mathbf{\omega}\mathbf{B} \times \mathbf{r}{SP}\\end{split}\\begin{split}{\mathbf{N}}\mathbf{a}^P &= \mathbf{B}\mathbf{a}S + \mathbf{N}\mathbf{a}O + \mathbf{N}\mathbf{\alpha}\mathbf{B} \times \mathbf{r}^{SP} + \mathbf{N}\mathbf{\omega}\mathbf{B} \times (\mathbf{N}\mathbf{\omega}\mathbf{B} \times \mathbf{r}^{SP}) + 2 \mathbf{N}\mathbf{\omega}\mathbf{B} \times ^\mathbf{B} \mathbf{v}^P \\end{split}\end{aligned}\end{align} ]
应用一点定理和二点定理的示例。
本例中,一个圆盘在平面内进行平移和旋转。我们可以很容易地定义身体(\mathbf{B})的角速度和点(O)的速度:
[\begin{split}\mathbf{N}\mathbf{\omega}\mathbf{B} &= u_3 \mathbf{\hat{n}_z} = u_3 \mathbf{\hat{b}_z}\ \mathbf{N}\mathbf{v}O &= u_1 \mathbf{\hat{n}_x} + u_2 \mathbf{\hat{n}_y}\\end{split}]
并且加速度可以写成:
[\begin{split}\mathbf{N}\mathbf{\alpha}\mathbf{B} &= \dot{u_3} \mathbf{\hat{n}_z} = \dot{u_3} \mathbf{\hat{b}_z}\ \mathbf{N}\mathbf{a}O &= \dot{u_1} \mathbf{\hat{n}_x} + \dot{u_2} \mathbf{\hat{n}_y}\\end{split}]
现在我们可以使用两点定理来计算点(P)的速度和加速度。
[\begin{split}\mathbf{r}^{OP} &= R \mathbf{\hat{b}_x}\ \mathbf{N}\mathbf{v}P &= \mathbf{N}\mathbf{v}O + \mathbf{N}\mathbf{\omega}\mathbf{B} \times \mathbf{r}^{OP}\ \mathbf{N}\mathbf{v}P &= u_1 \mathbf{\hat{n}_x} + u_2 \mathbf{\hat{n}_y} + u_3 \mathbf{\hat{b}_z} \times R \mathbf{\hat{b}_x} = u_1 \mathbf{\hat{n}_x} + u_2 \mathbf{\hat{n}_y} + u_3 R \mathbf{\hat{b}_y}\ {\mathbf{N}}\mathbf{a}P &= \mathbf{N}\mathbf{a}O + \mathbf{N}\mathbf{\alpha}\mathbf{B} \times \mathbf{r}^{OP} + \mathbf{N}\mathbf{\omega}\mathbf{B} \times (\mathbf{N}\mathbf{\omega}\mathbf{B} \times \mathbf{r}^{OP})\ {\mathbf{N}}\mathbf{a}P &= \dot{u_1} \mathbf{\hat{n}_x} + \dot{u_2} \mathbf{\hat{n}_y} + \dot{u_3}\mathbf{\hat{b}_z}\times R \mathbf{\hat{b}_x} +u_3\mathbf{\hat{b}_z}\times(u_3\mathbf{\hat{b}_z}\times R\mathbf{\hat{b}_x})\ {\mathbf{N}}\mathbf{a}P &= \dot{u_1} \mathbf{\hat{n}_x} + \dot{u_2} \mathbf{\hat{n}_y} + R\dot{u_3}\mathbf{\hat{b}_y} - R u_3² \mathbf{\hat{b}_x}\\end{split}]
在这个例子中,我们有一个双摆。我们可以在这里两次使用两点定理来找到点 (Q) 和 (P) 的速度;点 (O) 在 (\mathbf{N}) 中的速度为零。
[\begin{split}\mathbf{r}^{OQ} &= l \mathbf{\hat{b}_x}\ \mathbf{r}^{QP} &= l \mathbf{\hat{c}_x}\ \mathbf{N}\mathbf{\omega}\mathbf{B} &= u_1 \mathbf{\hat{b}_z}\ \mathbf{N}\mathbf{\omega}\mathbf{C} &= u_2 \mathbf{\hat{c}_z}\ \mathbf{N}\mathbf{v}Q &= \mathbf{N}\mathbf{v}O + \mathbf{N}\mathbf{\omega}\mathbf{B} \times \mathbf{r}^{OQ}\ \mathbf{N}\mathbf{v}Q &= u_1 l \mathbf{\hat{b}_y}\ \mathbf{N}\mathbf{v}P &= \mathbf{N}\mathbf{v}Q + \mathbf{N}\mathbf{\omega}\mathbf{C} \times \mathbf{r}^{QP}\ \mathbf{N}\mathbf{v}Q &= u_1 l \mathbf{\hat{b}_y} +u_2 \mathbf{\hat{c}_z} \times l \mathbf{\hat{c}_x}\ \mathbf{N}\mathbf{v}Q &= u_1 l\mathbf{\hat{b}_y}+u_2 l\mathbf{\hat{c}_y}\\end{split}]
在这个例子中,我们有一个粒子在环上运动;环由一个可以绕着(\mathbf{\hat{n}_x})轴旋转的杆支持。首先我们使用两点定理来找到环的中心点(Q)的速度,然后使用单点定理来找到环上粒子的速度。
[\begin{split}\mathbf{N}\mathbf{\omega}\mathbf{C} &= u_1 \mathbf{\hat{n}_x}\ \mathbf{r}^{OQ} &= -l \mathbf{\hat{c}_z}\ \mathbf{N}\mathbf{v}Q &= u_1 l \mathbf{\hat{c}_y}\ \mathbf{r}^{QP} &= R(cos(q_2) \mathbf{\hat{c}_x} + sin(q_2) \mathbf{\hat{c}_y} )\ \mathbf{C}\mathbf{v}P &= R u_2 (-sin(q_2) \mathbf{\hat{c}_x} + cos(q_2) \mathbf{\hat{c}_y} )\ \mathbf{N}\mathbf{v}P &= \mathbf{C}\mathbf{v}P +\mathbf{N}\mathbf{v}Q + \mathbf{N}\mathbf{\omega}\mathbf{C} \times \mathbf{r}^{QP}\ \mathbf{N}\mathbf{v}P &= R u_2 (-sin(q_2) \mathbf{\hat{c}_x} + cos(q_2) \mathbf{\hat{c}_y} ) + u_1 l \mathbf{\hat{c}_y} + u_1 \mathbf{\hat{c}_x} \times R(cos(q_2) \mathbf{\hat{c}_x} + sin(q_2) \mathbf{\hat{c}_y}\ \mathbf{N}\mathbf{v}P &= - R u_2 sin(q_2) \mathbf{\hat{c}_x} + (R u_2 cos(q_2)+u_1 l)\mathbf{\hat{c}_y} + R u_1 sin(q_2) \mathbf{\hat{c}_z}\\end{split}]
描述点速度的最后一个主题是滚动,或者更确切地说,是不打滑地滚动。如果两个物体在另一个参考系中接触点的速度相同,则称它们是不打滑地滚动。参见下图:
这里是 SVG 标签中文本框的内容。
这通常用于形成一个物体上的点在另一个固定物体上滚动的速度,例如以下示例:
物理学中的运动学
现在应该清楚,这里的运动学主题主要描述了正确操作向量以表示点的速度的方式。在sympy.physics.vector
中,有方便的方法来存储这些与参考系和点相关的速度。我们现在将重新访问上述示例,并展示如何在sympy
中表示它们。
参考系创建的主题已经涵盖过了。但是,当创建ReferenceFrame
时,它会自动使用 DCM 的时间导数和角速度定义来计算参考系的角速度。
>>> from sympy import Symbol, sin, cos
>>> from sympy.physics.vector import *
>>> init_vprinting(pretty_print=False)
>>> N = ReferenceFrame('N')
>>> q1 = dynamicsymbols('q1')
>>> A = N.orientnew('A', 'Axis', [q1, N.x])
>>> A.ang_vel_in(N)
q1'*N.x
注意,角速度可以以另一种方式定义:
>>> B = ReferenceFrame('B')
>>> u1 = dynamicsymbols('u1')
>>> B.set_ang_vel(N, u1 * B.y)
>>> B.ang_vel_in(N)
u1*B.y
>>> N.ang_vel_in(B)
- u1*B.y
在orientnew
期间创建参考系和调用set_ang_vel
时,如上所示,角速度在涉及的两个参考系中都设置了。
这里我们有多个与彼此相关联的角速度定义的物体。这被编码为:
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> B = ReferenceFrame('B')
>>> C = ReferenceFrame('C')
>>> D = ReferenceFrame('D')
>>> u1, u2, u3 = dynamicsymbols('u1 u2 u3')
>>> A.set_ang_vel(N, 0)
>>> B.set_ang_vel(A, u1 * A.x)
>>> C.set_ang_vel(B, -u2 * B.z)
>>> D.set_ang_vel(C, u3 * C.y)
>>> D.ang_vel_in(N)
u1*A.x - u2*B.z + u3*C.y
在 sympy.physics.vector
中,在查找角速度时使用两个框架之间的最短路径。这意味着,如果我们回去并设置:
>>> D.set_ang_vel(N, 0)
>>> D.ang_vel_in(N)
0
刚刚定义的路径是使用的路径。然而,这可能会导致问题,因为现在角速度的定义不一致。建议避免这样做。
Points 是与旋转 ReferenceFrame
对应的平移模拟。创建一个 Point
可以通过两种方式完成,就像 ReferenceFrame
一样:
>>> O = Point('O')
>>> P = O.locatenew('P', 3 * N.x + N.y)
>>> P.pos_from(O)
3*N.x + N.y
>>> Q = Point('Q')
>>> Q.set_pos(P, N.z)
>>> Q.pos_from(P)
N.z
>>> Q.pos_from(O)
3*N.x + N.y + N.z
类似于 ReferenceFrame
,两点之间的位置矢量是通过它们之间的最短路径(中间点的数量)找到的。与旋转运动不同的是,点的速度没有加法定理。为了在 ReferenceFrame
中有一个 Point
的速度,您必须设置该值。
>>> O = Point('O')
>>> O.set_vel(N, u1*N.x)
>>> O.vel(N)
u1*N.x
对于平移和旋转加速度,值是通过取适当速度的时间导数来计算的,除非用户另行设置。
>>> O.acc(N)
u1'*N.x
>>> O.set_acc(N, u2*u1*N.y)
>>> O.acc(N)
u1*u2*N.y
接下来是关于 sympy
中使用的两点和一点定理的描述。
首先是翻译、旋转的盘片。
>>> N = ReferenceFrame('N')
>>> u1, u2, u3 = dynamicsymbols('u1 u2 u3')
>>> R = Symbol('R')
>>> B = ReferenceFrame('B')
>>> O = Point('O')
>>> O.set_vel(N, u1 * N.x + u2 * N.y)
>>> P = O.locatenew('P', R * B.x)
>>> B.set_ang_vel(N, u3 * B.z)
>>> P.v2pt_theory(O, N, B)
u1*N.x + u2*N.y + R*u3*B.y
>>> P.a2pt_theory(O, N, B)
u1'*N.x + u2'*N.y - R*u3**2*B.x + R*u3'*B.y
我们还将涵盖 1 点定理的实现。
这是粒子再次在一个环上运动。
>>> N = ReferenceFrame('N')
>>> u1, u2 = dynamicsymbols('u1 u2')
>>> q1, q2 = dynamicsymbols('q1 q2')
>>> l = Symbol('l')
>>> R = Symbol('R')
>>> C = N.orientnew('C', 'Axis', [q1, N.x])
>>> C.set_ang_vel(N, u1 * N.x)
>>> O = Point('O')
>>> O.set_vel(N, 0)
>>> Q = O.locatenew('Q', -l * C.z)
>>> P = Q.locatenew('P', R * (cos(q2) * C.x + sin(q2) * C.y))
>>> P.set_vel(C, R * u2 * (-sin(q2) * C.x + cos(q2) * C.y))
>>> Q.v2pt_theory(O, N, C)
l*u1*C.y
>>> P.v1pt_theory(Q, N, C)
- R*u2*sin(q2)*C.x + (R*u2*cos(q2) + l*u1)*C.y + R*u1*sin(q2)*C.z
物理学中的潜在问题/高级主题/未来功能/向量模块
原文链接:
docs.sympy.org/latest/modules/physics/vector/advanced.html
本文将描述此模块提供但不是“官方”接口的一些更高级功能。此外,将涵盖一些将来将实施的功能,以及关于正确功能的未解答问题。还将讨论常见问题及其解决方案。
二元向量
在 sympy.physics.mechanics
中,二元用于表示惯性 ([Kane1985], [WikiDyadics], [WikiDyadicProducts])。二元是由分量单位二元的线性多项式,类似于向量是由分量单位向量的线性多项式。二元是两个向量的外积,返回一个新的量,表示这两个向量的并置。例如:
[\begin{split}\mathbf{\hat{a}_x} \otimes \mathbf{\hat{a}_x} &= \mathbf{\hat{a}_x} \mathbf{\hat{a}_x}\ \mathbf{\hat{a}_x} \otimes \mathbf{\hat{a}_y} &= \mathbf{\hat{a}_x} \mathbf{\hat{a}_y}\\end{split}]
其中 (\mathbf{\hat{a}_x}\mathbf{\hat{a}_x}) 和 (\mathbf{\hat{a}_x}\mathbf{\hat{a}_y}) 是通过将左侧作为列向量乘以右侧作为行向量获得的外积。注意顺序很重要。
一些二元向量的额外属性包括:
[\begin{split}(x \mathbf{v}) \otimes \mathbf{w} &= \mathbf{v} \otimes (x \mathbf{w}) = x (\mathbf{v} \otimes \mathbf{w})\ \mathbf{v} \otimes (\mathbf{w} + \mathbf{u}) &= \mathbf{v} \otimes \mathbf{w} + \mathbf{v} \otimes \mathbf{u}\ (\mathbf{v} + \mathbf{w}) \otimes \mathbf{u} &= \mathbf{v} \otimes \mathbf{u} + \mathbf{w} \otimes \mathbf{u}\\end{split}]
参考系中的向量可以表示为 (\begin{bmatrix}a\b\c\end{bmatrix}) 或 (a \mathbf{\hat{i}} + b \mathbf{\hat{j}} + c \mathbf{\hat{k}})。类似地,二元可以用张量形式表示:
[\begin{split}\begin{bmatrix} a_{11} & a_{12} & a_{13} \ a_{21} & a_{22} & a_{23} \ a_{31} & a_{32} & a_{33} \end{bmatrix}\\end{split}]
或以二元形式:
[\begin{split}a_{11} \mathbf{\hat{a}_x}\mathbf{\hat{a}x} + a \mathbf{\hat{a}_x}\mathbf{\hat{a}y} + a \mathbf{\hat{a}_x}\mathbf{\hat{a}z} + a \mathbf{\hat{a}_y}\mathbf{\hat{a}x} + a \mathbf{\hat{a}_y}\mathbf{\hat{a}y} + a \mathbf{\hat{a}_y}\mathbf{\hat{a}z} + a \mathbf{\hat{a}_z}\mathbf{\hat{a}x} + a \mathbf{\hat{a}_z}\mathbf{\hat{a}y} + a \mathbf{\hat{a}_z}\mathbf{\hat{a}_z}\\end{split}]
就像向量一样,后续的表示使得可以跟踪张量与哪些参考系有关。此外,张量每项的两个分量不必在同一个参考系中。以下是有效的:
[\mathbf{\hat{a}_x} \otimes \mathbf{\hat{b}_y} = \mathbf{\hat{a}_x} \mathbf{\hat{b}_y}]
二阶张量也可以与向量进行叉乘和点乘;再次强调顺序的重要性:
[\begin{split}\mathbf{\hat{a}_x}\mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x} &= \mathbf{\hat{a}_x}\ \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x} &= \mathbf{\hat{a}_y}\ \mathbf{\hat{a}_x}\mathbf{\hat{a}_y} \cdot \mathbf{\hat{a}_x} &= 0\ \mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x}\mathbf{\hat{a}_x} &= \mathbf{\hat{a}_x}\ \mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x}\mathbf{\hat{a}_y} &= \mathbf{\hat{a}_y}\ \mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} &= 0\ \mathbf{\hat{a}_x} \times \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} &= \mathbf{\hat{a}_z}\mathbf{\hat{a}_x}\ \mathbf{\hat{a}_x} \times \mathbf{\hat{a}_x}\mathbf{\hat{a}_x} &= 0\ \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} \times \mathbf{\hat{a}_z} &= - \mathbf{\hat{a}_y}\mathbf{\hat{a}_y}\\end{split}]
你也可以对二阶张量进行时间导数,或者在不同参考系中表示它们,就像对向量一样。
常见问题
在这里,可能会出现与数值积分代码、坐标和速度表示的 dynamicsymbols
选择、打印、微分和替换相关的问题。
打印
默认的打印选项是对Vector
和Dyadic
测量数使用排序,并且从vprint
、vpprint
和vlatex
函数有未排序的输出。如果要打印大量内容,请使用这些函数之一,因为排序可能会将打印时间从几秒钟增加到几分钟。
替换
替换到大表达式中可能会很慢,并且需要几分钟的时间。
点的加速度
至少,点需要定义它们的速度,因为加速度可以通过在相同参考系中对速度的时间导数来计算。如果使用一点或两点定理来计算速度,那么速度表达式的时间导数很可能比使用一级和二级定理来计算的更复杂。使用加速度级别的方法可以在这一点上导致较短的表达式,这将在形成 Kane 方程时导致较短的表达式。
高级接口
这里我们将涵盖ReferenceFrame
、dynamicsymbols
和一些相关功能的高级选项。
参考系
ReferenceFrame
被显示为具有 .name
属性和 .x
, .y
, 和 .z
属性用于访问基向量,并且有一个相当严格定义的打印输出。如果你希望有一个不同的索引集定义,这也是可以的。这也将需要一个不同的接口来访问基向量。
>>> from sympy.physics.vector import ReferenceFrame, vprint, vpprint, vlatex
>>> N = ReferenceFrame('N', indices=['i', 'j', 'k'])
>>> N['i']
N['i']
>>> N.x
N['i']
>>> vlatex(N.x)
'\\mathbf{\\hat{n}_{i}}'
此外,latex 输出可以有自定义字符串;而不仅仅是指标,每个基向量的整体都可以指定。自定义 latex 字符串可以不带自定义指标而发生,也覆盖了如果有自定义指标则将使用的 latex 字符串。
>>> from sympy.physics.vector import ReferenceFrame, vlatex
>>> N = ReferenceFrame('N', latexs=['n1','\\mathbf{n}_2','cat'])
>>> vlatex(N.x)
'n1'
>>> vlatex(N.y)
'\\mathbf{n}_2'
>>> vlatex(N.z)
'cat'
动态符号
dynamicsymbols
函数还具有‘隐藏’功能;与时间相关联的变量可以更改,以及用于打印导数的符号。
>>> from sympy import symbols
>>> from sympy.physics.vector import dynamicsymbols, vprint
>>> q1 = dynamicsymbols('q1')
>>> q1
q1(t)
>>> dynamicsymbols._t = symbols('T')
>>> q2 = dynamicsymbols('q2')
>>> q2
q2(T)
>>> q1
q1(t)
>>> q1d = dynamicsymbols('q1', 1)
>>> vprint(q1d)
q1'
>>> dynamicsymbols._str = 'd'
>>> vprint(q1d)
q1d
>>> dynamicsymbols._str = '\''
>>> dynamicsymbols._t = symbols('t')
注意,仅在更改后创建的动态符号不同。这对于(._str)属性并非如此;这仅影响打印输出,因此在更改前后创建的动态符号将以相同的方式打印。
还要注意,Vector
的.dt
方法使用dynamicsymbols
的._t
属性,以及其他一些重要的函数和方法。不要混合表示时间的符号。
解向量方程
要解决涉及向量的方程,不能直接使用向量上的解函数。相反,必须将向量转换为一组标量方程。
假设我们有两个框架N
和A
,其中A
相对于N
绕 z 轴旋转 30 度。
>>> from sympy import pi, symbols, solve
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame("N")
>>> A = ReferenceFrame("A")
>>> A.orient_axis(N, pi / 6, N.z)
假设我们有两个向量v1
和v2
,它们用不同的符号表示相同的向量。
>>> v1x, v1y, v1z = symbols("v1x v1y v1z")
>>> v2x, v2y, v2z = symbols("v2x v2y v2z")
>>> v1 = v1x * N.x + v1y * N.y + v1z * N.z
>>> v2 = v2x * A.x + v2y * A.y + v2z * A.z
我们的目标是找到v2
中使用的符号与v1
中使用的符号之间的关系。我们可以通过将向量转换为矩阵,然后使用sympy.solvers.solvers.solve()
来实现这一点。
>>> solve((v1 - v2).to_matrix(N), [v2x, v2y, v2z])
{v2x: sqrt(3)*v1x/2 + v1y/2, v2y: -v1x/2 + sqrt(3)*v1y/2, v2z: v1z}
标量和矢量场功能
介绍
矢量和标量
在物理学中,我们处理两种量 - 标量和矢量。
标量是仅具有大小而没有方向的实体。标量量例如质量、电荷、温度、距离等。
另一方面,矢量是由大小和方向特征的实体。矢量量的例子包括位移、速度、磁场等。
标量可以仅用一个数字表示,例如 300K 的温度。另一方面,矢量量如加速度通常用矢量表示。给定一个矢量(\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}})给出。
场
一般来说,一个(场)是可以作为位置函数在空间中的每个位置指定的矢量或标量量(注意,通常情况下场也可能依赖于时间和其他自定义变量)。在本模块中,我们只处理三维空间。因此,场被定义为(x)、(y)和(z)坐标的函数,对应于 3D 空间中的位置。
例如,三维空间中的温度(温度场)可以写为(T(x, y, z)) - 位置的标量函数。在电磁学中标量场的例子是电势。
类似地,矢量场可以定义为空间中任意点((x, y, z))位置的矢量函数。
例如,地球上的每一点都可以看作处于地球的重力场中。我们可以通过每个空间点处的加速度(即单位质量的力)(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}})的标量场。
在sympy.physics.vector
中的场的实现
在sympy.physics.vector
模块中,每个ReferenceFrame
实例都被分配了对应于(X)、(Y)和(Z)方向的基向量。这些可以通过分别命名为x
、y
和z
的属性来访问。因此,要在给定的参考框架(\mathbf{R})中定义形式为(3\mathbf{\hat{i}} + 4\mathbf{\hat{j}} + 5\mathbf{\hat{k}})的向量(\mathbf{v}),你可以这样做:
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> v = 3*R.x + 4*R.y + 5*R.z
有关向量及其对应的基本微积分操作,本模块文档的其他部分已经有详细阐述。
另一方面,基标量(或坐标变量)被实现为分配给每个参考框架的特殊 SymPy Symbol
,每个方向从(X)、(Y)和(Z)各有一个。对于框架R
,(X)、(Y)和(Z)基标量Symbol
可以分别通过R[0]
、R[1]
和R[2]
表达式访问。
因此,要生成上述电势场(2{x}^{2}y)的表达式,你需要这样做:
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> electric_potential = 2*R[0]**2*R[1]
>>> electric_potential
2*R_x**2*R_y
在字符串表示中,R_x
表示分配给ReferenceFrame
R
的(X)基标量。实质上,R_x
是R[0]
的字符串表示。
标量场可以像任何其他 SymPy 表达式一样用于任何数学/微积分功能。因此,要相对于(x)(即R[0]
)对上述电势进行微分,你需要使用diff
函数。
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> electric_potential = 2*R[0]**2*R[1]
>>> from sympy import diff
>>> diff(electric_potential, R[0])
4*R_x*R_y
与向量(和向量场)类似,标量场也可以在除定义它们的框架之外的其他参考框架中重新表达,假设所涉及的框架之间存在方向关系。这可以使用sympy.physics.vector.vector.Vector.express
方法完成,方法类似于向量,但variables
参数设置为True
。
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> electric_potential = 2*R[0]**2*R[1]
>>> from sympy.physics.vector import dynamicsymbols, express
>>> q = dynamicsymbols('q')
>>> R1 = R.orientnew('R1', rot_type = 'Axis', amounts = [q, R.z])
>>> express(electric_potential, R1, variables=True)
2*(R1_x*sin(q(t)) + R1_y*cos(q(t)))*(R1_x*cos(q(t)) - R1_y*sin(q(t)))**2
此外,考虑到标量也可以是时间的函数,就像矢量一样,可以进行时间微分。根据表达式中的Symbol
和进行时间微分的参考框架,输出会改变/保持不变。
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> electric_potential = 2*R[0]**2*R[1]
>>> q = dynamicsymbols('q')
>>> R1 = R.orientnew('R1', rot_type = 'Axis', amounts = [q, R.z])
>>> from sympy.physics.vector import time_derivative
>>> time_derivative(electric_potential, R)
0
>>> time_derivative(electric_potential, R1).simplify()
2*(R1_x*cos(q(t)) - R1_y*sin(q(t)))*(3*R1_x**2*cos(2*q(t))/2 -
R1_x**2/2 - 3*R1_x*R1_y*sin(2*q(t)) - 3*R1_y**2*cos(2*q(t))/2 -
R1_y**2/2)*Derivative(q(t), t)
场算符和其他相关函数
这里我们描述了在 sympy.physics.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.physics.vector
中计算矢量场的旋度,您可以执行以下操作:
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> from sympy.physics.vector import curl
>>> field = R[0]*R[1]*R[2]*R.x
>>> curl(field, R)
R_x*R_y*R.y - R_x*R_z*R.z
散度
散度是一个矢量算子,用于衡量矢量场在给定点的源或汇的大小,以有符号标量形式表示。
散度算子在作用于矢量后始终返回一个标量。
在 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.physics.vector
中计算矢量场的散度,您可以执行以下操作:
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> from sympy.physics.vector import divergence
>>> field = R[0]*R[1]*R[2] * (R.x+R.y+R.z)
>>> divergence(field, R)
R_x*R_y + R_x*R_z + R_y*R_z
梯度
考虑在三维空间中的标量场( f(x, y, z) )。该场的梯度定义为关于( X ),( Y )和( Z )方向上( f )的三个偏导数的向量。
在 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.physics.vector
中计算标量场的梯度,您可以执行以下操作:
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> from sympy.physics.vector import gradient
>>> scalar_field = R[0]*R[1]*R[2]
>>> gradient(scalar_field, R)
R_y*R_z*R.x + R_x*R_z*R.y + R_x*R_y*R.z
保守与旋度场
在向量微积分中,保守场是某个标量场的梯度。保守场具有这样的性质,即其沿任意路径的线积分仅依赖于端点,并且与路径本身无关。保守矢量场也被称为‘无旋场’,因为保守场的旋度始终为零。
在物理学中,保守场代表能量守恒的物理系统中的力。
若要检查向量场在 sympy.physics.vector
中是否为保守场,请使用 sympy.physics.vector.fieldfunctions.is_conservative
函数。
>>> from sympy.physics.vector import ReferenceFrame, is_conservative
>>> R = ReferenceFrame('R')
>>> field = R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z
>>> is_conservative(field)
True
>>> curl(field, R)
0
另一方面,旋量场是指其在空间中所有点的散度均为零的向量场。
若要检查向量场在 sympy.physics.vector
中是否为旋量场,请使用 sympy.physics.vector.fieldfunctions.is_solenoidal
函数。
>>> from sympy.physics.vector import ReferenceFrame, is_solenoidal
>>> R = ReferenceFrame('R')
>>> field = R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z
>>> is_solenoidal(field)
True
>>> divergence(field, R)
0
标量势函数
我们之前提到,每个保守场都可以被定义为某个标量场的梯度。这个标量场也被称为与前述保守场对应的‘标量势场’。
sympy.physics.vector.fieldfunctions.scalar_potential
函数在 sympy.physics.vector
中计算给定三维空间中保守矢量场对应的标量势场 - 当然要减去积分的额外常数。
使用示例 -
>>> from sympy.physics.vector import ReferenceFrame, scalar_potential
>>> R = ReferenceFrame('R')
>>> conservative_field = 4*R[0]*R[1]*R[2]*R.x + 2*R[0]**2*R[2]*R.y + 2*R[0]**2*R[1]*R.z
>>> scalar_potential(conservative_field, R)
2*R_x**2*R_y*R_z
将非保守矢量场作为参数提供给 sympy.physics.vector.fieldfunctions.scalar_potential
会引发 ValueError
。
对应于保守矢量场的标量势差,或简称‘势差’,可以定义为空间中两点处其标量势函数值的差。这在计算关于保守函数的线积分中非常有用,因为它仅依赖于路径的端点。
在 sympy.physics.vector
中,该计算执行如下。
>>> from sympy.physics.vector import ReferenceFrame, Point
>>> from sympy.physics.vector import scalar_potential_difference
>>> R = ReferenceFrame('R')
>>> O = Point('O')
>>> P = O.locatenew('P', 1*R.x + 2*R.y + 3*R.z)
>>> vectfield = 4*R[0]*R[1]*R.x + 2*R[0]**2*R.y
>>> scalar_potential_difference(vectfield, R, O, P, O)
4
如果提供的是标量表达式而不是矢量场,sympy.physics.vector.fieldfunctions.scalar_potential_difference
返回空间中两个给定点处该标量场值的差异。
物理矢量 API
原文:
docs.sympy.org/latest/modules/physics/vector/api/index.html
-
基本类
-
运动学(文档字符串)
-
打印(文档字符串)
-
基本函数(文档字符串)
-
基本场函数的文档字符串
关键类
原文:
docs.sympy.org/latest/modules/physics/vector/api/classes.html
class sympy.physics.vector.frame.CoordinateSym(name, frame, index)
与参考框架相关的坐标符号/基量标量。
理想情况下,用户不应该实例化这个类。这个类的实例必须仅通过相应的框架作为‘frame[index]’来访问。
具有相同框架和索引参数的 CoordinateSyms 是相等的(即使它们可能是分别实例化的)。
参数:
name:字符串
CoordinateSym 的显示名称
frame:ReferenceFrame
此基量标量所属的参考框架
index:0、1 或 2
由此坐标变量表示的维度的索引
示例
>>> from sympy.physics.vector import ReferenceFrame, CoordinateSym
>>> A = ReferenceFrame('A')
>>> A[1]
A_y
>>> type(A[0])
<class 'sympy.physics.vector.frame.CoordinateSym'>
>>> a_y = CoordinateSym('a_y', A, 1)
>>> a_y == A[1]
True
class sympy.physics.vector.frame.ReferenceFrame(name, indices=None, latexs=None, variables=None)
经典力学中的参考框架。
ReferenceFrame 是用于表示经典力学中参考框架的类。它在框架的 x、y 和 z 方向具有标准基向量。
它也可以相对于父框架进行旋转;这种旋转由一个方向余弦矩阵定义,将该框架的基向量与父框架的基向量相关联。它还可以具有在另一个框架中定义的角速度矢量。
ang_acc_in(otherframe)
返回参考框架的角加速度矢量。
有效地返回矢量:
N_alpha_B
其中 N 表示 B 在 N 中的角加速度,其中 B 是自身,N 是 otherframe。
参数:
otherframe:ReferenceFrame
返回角加速度的 ReferenceFrame。
示例
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_acc(N, V)
>>> A.ang_acc_in(N)
10*N.x
ang_vel_in(otherframe)
返回参考框架的角速度矢量。
有效地返回矢量:
^N omega ^B
其中 N 表示 B 在 N 中的角速度,其中 B 是自身,N 是 otherframe。
参数:
otherframe:ReferenceFrame
返回角速度的 ReferenceFrame。
示例
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_vel(N, V)
>>> A.ang_vel_in(N)
10*N.x
dcm(otherframe)
返回相对于提供的参考框架的此参考框架的方向余弦矩阵。
返回的矩阵可用于用otherframe
的正交单位向量表示该框架的正交单位向量。
参数:
otherframe:ReferenceFrame
形成此框架的方向余弦矩阵相对于的参考框架。
示例
以下示例通过简单旋转将参考框架 A 相对于 N 旋转,然后计算 N 相对于 A 的方向余弦矩阵。
>>> from sympy import symbols, sin, cos
>>> from sympy.physics.vector import ReferenceFrame
>>> q1 = symbols('q1')
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> A.orient_axis(N, q1, N.x)
>>> N.dcm(A)
Matrix([
[1, 0, 0],
[0, cos(q1), -sin(q1)],
[0, sin(q1), cos(q1)]])
上述方向余弦矩阵的第二行表示在 A 中表示的 N.y 单位向量N.y
。如下所示:
>>> Ny = 0*A.x + cos(q1)*A.y - sin(q1)*A.z
因此,在 A 中表达N.y
应该返回相同的结果:
>>> N.y.express(A)
cos(q1)*A.y - sin(q1)*A.z
注释
知道返回的方向余弦矩阵的形式很重要。如果调用B.dcm(A)
,表示“B 相对于 A 旋转的方向余弦矩阵”。这是下面关系中显示的矩阵 ({}B\mathbf{C}A):
[\begin{split}\begin{bmatrix} \hat{\mathbf{b}}_1 \ \hat{\mathbf{b}}_2 \ \hat{\mathbf{b}}_3 \end{bmatrix} = {}B\mathbf{C}A \begin{bmatrix} \hat{\mathbf{a}}_1 \ \hat{\mathbf{a}}_2 \ \hat{\mathbf{a}}_3 \end{bmatrix}.\end{split}]
({}B\mathbf{C}A)是表达 B 单位向量与 A 单位向量关系的矩阵。
orient(parent, rot_type, amounts, rot_order='')
设置此参考框架相对于另一个(父)参考框架的方向。
注意
现在建议使用.orient_axis, .orient_body_fixed, .orient_space_fixed, .orient_quaternion
方法来处理不同的旋转类型。
参数:
parent:参考框架。
将此参考框架旋转到的参考框架。
rot_type:字符串。
生成方向余弦矩阵的方法。支持的方法有:
'Axis'
:围绕单个共同轴的简单旋转。'DCM'
:用于直接设置方向余弦矩阵。'Body'
:围绕新中间轴的三次连续旋转,也称为“欧拉和泰特-布赖恩角”。'Space'
:围绕父框架单位向量的三次连续旋转。'Quaternion'
:由四个参数定义的旋转,其结果是一个无奇点的方向余弦矩阵。
amounts:
定义旋转角度或方向余弦矩阵的表达式。这些必须与
rot_type
匹配。有关详细信息,请参见下面的示例。输入类型为:
'Axis'
:2 元组(表达式/符号/函数,矢量)。'DCM'
:矩阵,形状(3,3)。'Body'
:三元组表达式、符号或函数。'Space'
:三元组表达式、符号或函数。'Quaternion'
:四元组表达式、符号或函数。
rot_order:字符串或整数,可选。
如果适用,表示连续旋转的顺序。例如,字符串
'123'
和整数123
是等效的。对'Body'
和'Space'
类型是必需的。
警告:
用户警告
如果方向创建了一个运动学闭环。
orient_axis(parent, axis, angle)
通过绕父参考框架中固定轴旋转角度,设置此参考框架的方向。
参数:
parent:参考框架。
将此参考框架旋转到的参考框架。
axis:矢量。
固定在父框架中的矢量,围绕其旋转的框架。它不需要是单位向量,旋转遵循右手规则。
angle:可合并。
以弧度表示的旋转角度。
警告:
用户警告
如果方向创建了一个运动学闭环。
示例
为示例设置变量:
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q1 = symbols('q1')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
>>> B.orient_axis(N, N.x, q1)
orient_axis()
方法生成一个方向余弦矩阵及其转置,定义了 B 相对于 N 的方向和反向。一旦调用orient
,dcm()
输出适当的方向余弦矩阵:
>>> B.dcm(N)
Matrix([
[1, 0, 0],
[0, cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])
>>> N.dcm(B)
Matrix([
[1, 0, 0],
[0, cos(q1), -sin(q1)],
[0, sin(q1), cos(q1)]])
下面两行表明旋转的方向可以通过对向量方向或角度取反来定义。这两行都会产生相同的结果。
>>> B.orient_axis(N, -N.x, q1)
>>> B.orient_axis(N, N.x, -q1)
orient_body_fixed(parent, angles, rotation_order)
将此参考框架相对于父参考框架通过连续的身体固定简单轴旋转右手旋转。每个后续旋转轴围绕新的中间参考框架的“身体固定”单位向量。这种旋转类型也称为绕欧拉和 Tait-Bryan 角度旋转。
该方法中计算的角速度默认以子框架的形式表示,因此最好使用 u1 * child.x + u2 * child.y + u3 * child.z
作为广义速度。
参数:
parent :参考框架
将相对于父参考框架设置此参考框架的方向。
angles :3-tuple of sympifiable
三个用于连续旋转的弧度角。
rotation_order :3 个字符字符串或 3 位整数
关于每个中间参考框架单位向量的旋转顺序。关于 X、Z'、X'' 轴的欧拉旋转可以用字符串
'XZX'
、'131'
或整数131
来指定。有 12 个唯一的有效旋转顺序(6 个欧拉和 6 个 Tait-Bryan):zxz、xyx、yzy、zyz、xzx、yxy、xyz、yzx、zxy、xzy、zyx 和 yxz。
警告:
用户警告
如果方向创建一个运动学环路。
示例
为示例设置变量:
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q1, q2, q3 = symbols('q1, q2, q3')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
>>> B1 = ReferenceFrame('B1')
>>> B2 = ReferenceFrame('B2')
>>> B3 = ReferenceFrame('B3')
例如,经典的欧拉角旋转可以通过以下方式完成:
>>> B.orient_body_fixed(N, (q1, q2, q3), 'XYX')
>>> B.dcm(N)
Matrix([
[ cos(q2), sin(q1)*sin(q2), -sin(q2)*cos(q1)],
[sin(q2)*sin(q3), -sin(q1)*sin(q3)*cos(q2) + cos(q1)*cos(q3), sin(q1)*cos(q3) + sin(q3)*cos(q1)*cos(q2)],
[sin(q2)*cos(q3), -sin(q1)*cos(q2)*cos(q3) - sin(q3)*cos(q1), -sin(q1)*sin(q3) + cos(q1)*cos(q2)*cos(q3)]])
这将参考框架 B 相对于参考框架 N 通过 q1
关于 N.x
的旋转,然后再次通过 q2
关于 B.y
的旋转,并最终通过 q3
关于 B.x
的旋转。这相当于三个连续的 orient_axis()
调用:
>>> B1.orient_axis(N, N.x, q1)
>>> B2.orient_axis(B1, B1.y, q2)
>>> B3.orient_axis(B2, B2.x, q3)
>>> B3.dcm(N)
Matrix([
[ cos(q2), sin(q1)*sin(q2), -sin(q2)*cos(q1)],
[sin(q2)*sin(q3), -sin(q1)*sin(q3)*cos(q2) + cos(q1)*cos(q3), sin(q1)*cos(q3) + sin(q3)*cos(q1)*cos(q2)],
[sin(q2)*cos(q3), -sin(q1)*cos(q2)*cos(q3) - sin(q3)*cos(q1), -sin(q1)*sin(q3) + cos(q1)*cos(q2)*cos(q3)]])
可接受的旋转顺序长度为 3,表示为字符串 'XYZ'
或 '123'
或整数 123
。禁止连续两次绕一个轴旋转。
>>> B.orient_body_fixed(N, (q1, q2, 0), 'ZXZ')
>>> B.orient_body_fixed(N, (q1, q2, 0), '121')
>>> B.orient_body_fixed(N, (q1, q2, q3), 123)
orient_dcm(parent, dcm)
使用描述从子参考框架到父参考框架的旋转的方向余弦矩阵设置此参考框架的方向。
参数:
parent :参考框架
将相对于另一个(父级)参考框架设置此参考框架的方向。
dcm :矩阵,形状(3, 3)
指定两个参考框架之间相对旋转的方向余弦矩阵。
警告:
用户警告
如果方向创建一个运动学环路。
示例
为示例设置变量:
>>> from sympy import symbols, Matrix, sin, cos
>>> from sympy.physics.vector import ReferenceFrame
>>> q1 = symbols('q1')
>>> A = ReferenceFrame('A')
>>> B = ReferenceFrame('B')
>>> N = ReferenceFrame('N')
简单的相对于 N
关于 N.x
的旋转由以下方向余弦矩阵定义:
>>> dcm = Matrix([[1, 0, 0],
... [0, cos(q1), sin(q1)],
... [0, -sin(q1), cos(q1)]])
>>> A.orient_dcm(N, dcm)
>>> A.dcm(N)
Matrix([
[1, 0, 0],
[0, cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])
这相当于使用 orient_axis()
:
>>> B.orient_axis(N, N.x, q1)
>>> B.dcm(N)
Matrix([
[1, 0, 0],
[0, cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])
orient_quaternion(parent, numbers)
通过方向余弦矩阵设置此参考框架相对于父参考框架的方向。方向余弦矩阵被定义为由角度 theta
的单位向量 (lambda_x, lambda_y, lambda_z)
绕一个轴进行的有限旋转。方向余弦矩阵由四个参数描述:
-
q0 = cos(theta/2)
-
q1 = lambda_x*sin(theta/2)
-
q2 = lambda_y*sin(theta/2)
-
q3 = lambda_z*sin(theta/2)
更多信息请参见四元数和空间旋转在维基百科上。
参数:
parent : ReferenceFrame
将旋转相对于此参考系的参考系。
numbers : sympy 化的 4 元组
四个四元数标量数如上定义:
q0
,q1
,q2
,q3
。
警告:
UserWarning
如果方向性创建了一个运动学回路。
示例
设置示例变量:
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
设置方向:
>>> B.orient_quaternion(N, (q0, q1, q2, q3))
>>> B.dcm(N)
Matrix([
[q0**2 + q1**2 - q2**2 - q3**2, 2*q0*q3 + 2*q1*q2, -2*q0*q2 + 2*q1*q3],
[ -2*q0*q3 + 2*q1*q2, q0**2 - q1**2 + q2**2 - q3**2, 2*q0*q1 + 2*q2*q3],
[ 2*q0*q2 + 2*q1*q3, -2*q0*q1 + 2*q2*q3, q0**2 - q1**2 - q2**2 + q3**2]])
orient_space_fixed(parent, angles, rotation_order)
相对于父参考系通过右手侧旋转的三个连续空间固定简单轴旋转旋转此参考系。每个后续旋转轴都是关于父参考系的“空间固定”单位向量。
本方法中计算的角速度默认为在子参考系中表示,因此最好使用u1 * child.x + u2 * child.y + u3 * child.z
作为广义速度。
参数:
parent : ReferenceFrame
将旋转相对于此参考系的参考系。
angles : sympy 化的 3 元组
用于连续旋转的三个弧度角。
rotation_order : 3 个字符字符串或 3 位整数
父参考系单位向量的旋转顺序。顺序可以由字符串
'XZX'
,'131'
或整数131
指定。有 12 个唯一的有效旋转顺序。
警告:
UserWarning
如果方向性创建了一个运动学回路。
示例
设置示例变量:
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q1, q2, q3 = symbols('q1, q2, q3')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
>>> B1 = ReferenceFrame('B1')
>>> B2 = ReferenceFrame('B2')
>>> B3 = ReferenceFrame('B3')
>>> B.orient_space_fixed(N, (q1, q2, q3), '312')
>>> B.dcm(N)
Matrix([
[ sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1)],
[-sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3)],
[ sin(q3)*cos(q2), -sin(q2), cos(q2)*cos(q3)]])
等价于:
>>> B1.orient_axis(N, N.z, q1)
>>> B2.orient_axis(B1, N.x, q2)
>>> B3.orient_axis(B2, N.y, q3)
>>> B3.dcm(N).simplify()
Matrix([
[ sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1)],
[-sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3)],
[ sin(q3)*cos(q2), -sin(q2), cos(q2)*cos(q3)]])
值得注意的是,空间固定和体固定旋转通过旋转顺序相关联,即体固定的逆顺序将给出空间固定,反之亦然。
>>> B.orient_space_fixed(N, (q1, q2, q3), '231')
>>> B.dcm(N)
Matrix([
[cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3), -sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1)],
[ -sin(q2), cos(q2)*cos(q3), sin(q3)*cos(q2)],
[sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1), sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3)]])
>>> B.orient_body_fixed(N, (q3, q2, q1), '132')
>>> B.dcm(N)
Matrix([
[cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3), -sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1)],
[ -sin(q2), cos(q2)*cos(q3), sin(q3)*cos(q2)],
[sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1), sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3)]])
orientnew(newname, rot_type, amounts, rot_order='', variables=None, indices=None, latexs=None)
返回相对于此参考系定向的新参考系。
参见ReferenceFrame.orient()
,了解如何定向参考系的详细示例。
参数:
newname : 字符串
新参考系的名称。
rot_type : 字符串
生成方向余弦矩阵的方法。支持的方法有:
'Axis'
: 简单绕单一公共轴旋转'DCM'
: 用于直接设置方向余弦矩阵'Body'
: 关于新中间轴的三个连续旋转,也称为“欧拉和泰特-布赖恩角”'Space'
: 关于父参考系单位向量的三个连续旋转'Quaternion'
: 由四个参数定义的旋转,其结果是无奇点的方向余弦矩阵
amounts :
定义旋转角度或方向余弦矩阵的表达式。这些必须与
rot_type
匹配。有关详细信息,请参阅下面的示例。
'Axis'
: 2 元组(表达式/符号/函数,向量)'DCM'
: 矩阵,形状(3,3)'Body'
: 表达式、符号或函数的 3 元组'Space'
: 表达式、符号或函数的 3 元组'Quaternion'
: 表达式、符号或函数的 4 元组
rot_order : 字符串或整数,可选
如果适用,旋转顺序的顺序。例如字符串
'123'
和整数123
是等效的。对'Body'
和'Space'
是必需的。
indices : 字符串元组
使得可以通过 Python 的方括号索引符号访问参考框架的基单位向量,使用提供的三个索引字符串,并修改单元向量的打印以反映此选择。
latexs : 字符串元组
修改参考框架的基单位向量的 LaTeX 打印为提供的三个有效的 LaTeX 字符串。
例子
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame, vlatex
>>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
>>> N = ReferenceFrame('N')
创建一个通过简单旋转相对于 N 旋转的新参考框架 A。
>>> A = N.orientnew('A', 'Axis', (q0, N.x))
创建一个通过体固定旋转相对于 N 旋转的新参考框架 B。
>>> B = N.orientnew('B', 'Body', (q1, q2, q3), '123')
创建一个通过简单旋转相对于 N 旋转的新参考框架 C,具有独特的索引和 LaTeX 打印。
>>> C = N.orientnew('C', 'Axis', (q0, N.x), indices=('1', '2', '3'),
... latexs=(r'\hat{\mathbf{c}}_1',r'\hat{\mathbf{c}}_2',
... r'\hat{\mathbf{c}}_3'))
>>> C['1']
C['1']
>>> print(vlatex(C['1']))
\hat{\mathbf{c}}_1
partial_velocity(frame, *gen_speeds)
返回该框架在给定框架中关于一个或多个提供的广义速度的部分角速度。
参数:
frame : 参考框架
定义角速度相对于的框架。
gen_speeds : 时间的函数
广义速度。
返回:
partial_velocities : 向量元组
对应于所提供广义速度的部分角速度向量。
例子
>>> from sympy.physics.vector import ReferenceFrame, dynamicsymbols
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> u1, u2 = dynamicsymbols('u1, u2')
>>> A.set_ang_vel(N, u1 * A.x + u2 * N.y)
>>> A.partial_velocity(N, u1)
A.x
>>> A.partial_velocity(N, u1, u2)
(A.x, N.y)
set_ang_acc(otherframe, value)
在参考框架中定义角加速度向量。
定义该参考框架的角加速度,另一种。 角加速度可以相对于多个不同的参考框架定义。 必须小心,以免创建不一致的循环。
参数:
otherframe : 参考框架
定义角加速度的参考框架
value : 向量
表示角加速度的向量
例子
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_acc(N, V)
>>> A.ang_acc_in(N)
10*N.x
set_ang_vel(otherframe, value)
在参考框架中定义角速度向量。
定义该参考框架的角速度,另一种。 角速度可以相对于多个不同的参考框架定义。 必须小心,以免创建不一致的循环。
参数:
otherframe : 参考框架
定义角速度的参考框架
value : 向量
表示角速度的向量
例子
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_vel(N, V)
>>> A.ang_vel_in(N)
10*N.x
property u
参考框架的单位二重项。
variable_map(otherframe)
返回一个表达该框架的坐标变量与其他框架变量的字典。
如果 Vector.simp 为 True,则返回映射值的简化版本。 否则,返回未简化的值。
简化表达可能需要时间。
参数:
otherframe : 参考框架
映射变量到另一个框架
例子
>>> from sympy.physics.vector import ReferenceFrame, dynamicsymbols
>>> A = ReferenceFrame('A')
>>> q = dynamicsymbols('q')
>>> B = A.orientnew('B', 'Axis', [q, A.z])
>>> A.variable_map(B)
{A_x: B_x*cos(q(t)) - B_y*sin(q(t)), A_y: B_x*sin(q(t)) + B_y*cos(q(t)), A_z: B_z}
property x
参考框架中 x 方向的基向量。
property xx
参考框架中基向量 x 和 x 的单位二重项。
property xy
参考框架中基向量 x 和 y 的单位二重项。
property xz
参考框架中基向量 x 和 z 的单位二重项。
property y
参考框架中 y 方向的基向量。
property yx
参考框架中基向量 y 和 x 的单位二重项。
property yy
参考框架中基向量 y 和 y 的单位二重项。
property yz
参考框架中基向量 y 和 z 的单位二重项。
property z
参考框架中 z 方向的基向量。
property zx
参考框架中基向量 z 和 x 的单位二重项。
property zy
与参考框架中基向量 z 和 y 的单位二重
property zz
用于参考框架中基向量 z 和 z 的单位二重
class sympy.physics.vector.vector.Vector(inlist)
用于定义向量的类。
它以及 ReferenceFrame 是在 PyDy 和 sympy.physics.vector 中描述经典力学系统的基本构件。
属性
simp | (布尔值) 允许某些方法在其输出上使用 trigsimp |
---|
angle_between(vec)
返回向量 'vec' 和自身之间的最小角度。
警告
Python 忽略前导负号,可能导致错误结果。-A.x.angle_between()
将被处理为 -(A.x.angle_between())
,而不是 (-A.x).angle_between()
。
参数
vecVector
需要角度的两个向量之间的向量。
示例
>>> from sympy.physics.vector import ReferenceFrame
>>> A = ReferenceFrame("A")
>>> v1 = A.x
>>> v2 = A.y
>>> v1.angle_between(v2)
pi/2
>>> v3 = A.x + A.y + A.z
>>> v1.angle_between(v3)
acos(sqrt(3)/3)
applyfunc(f)
对向量的每个分量应用一个函数。
cross(other)
两个向量的叉乘算子。
返回一个与自身相同参考框架表达的向量。
参数:
other:Vector
我们正在与之交叉的向量
示例
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame, cross
>>> q1 = symbols('q1')
>>> N = ReferenceFrame('N')
>>> cross(N.x, N.y)
N.z
>>> A = ReferenceFrame('A')
>>> A.orient_axis(N, q1, N.x)
>>> cross(A.x, N.y)
N.z
>>> cross(N.y, A.x)
- sin(q1)*A.y - cos(q1)*A.z
diff(var, frame, var_in_dcm=True)
返回相对于所提供参考框架中变量的向量的偏导数。
参数:
var:Symbol
所取偏导数的对象。
frame:ReferenceFrame
在其中进行时间导数计算的参考框架。
var_in_dcm:布尔值
如果为 true,则差异化算法假定该变量可能存在于将框架与向量任何分量的框架相关联的方向余弦矩阵中。但如果已知该变量不存在于方向余弦矩阵中,则可以设置 false 以跳过完全重新表达为所需框架。
示例
>>> from sympy import Symbol
>>> from sympy.physics.vector import dynamicsymbols, ReferenceFrame
>>> from sympy.physics.vector import init_vprinting
>>> init_vprinting(pretty_print=False)
>>> t = Symbol('t')
>>> q1 = dynamicsymbols('q1')
>>> N = ReferenceFrame('N')
>>> A = N.orientnew('A', 'Axis', [q1, N.y])
>>> A.x.diff(t, N)
- sin(q1)*q1'*N.x - cos(q1)*q1'*N.z
>>> A.x.diff(t, N).express(A).simplify()
- q1'*A.z
>>> B = ReferenceFrame('B')
>>> u1, u2 = dynamicsymbols('u1, u2')
>>> v = u1 * A.x + u2 * B.y
>>> v.diff(u2, N, var_in_dcm=False)
B.y
doit(**hints)
在向量的每个项上调用 .doit()
dot(other)
两个向量的点积。
返回一个标量,两个向量的点积
参数:
other:Vector
我们正在与之做点乘的向量
示例
>>> from sympy.physics.vector import ReferenceFrame, dot
>>> from sympy import symbols
>>> q1 = symbols('q1')
>>> N = ReferenceFrame('N')
>>> dot(N.x, N.x)
1
>>> dot(N.x, N.y)
0
>>> A = N.orientnew('A', 'Axis', [q1, N.x])
>>> dot(N.y, A.y)
cos(q1)
dt(otherframe)
返回一个在其他帧中时间导数的向量。
调用全局 time_derivative 方法
参数:
otherframe:ReferenceFrame
计算时间导数的框架
express(otherframe, variables=False)
返回等效于此向量的向量,表达为 otherframe。使用全局 express 方法。
参数:
otherframe:ReferenceFrame
描述此向量的帧
variables:布尔值
如果为 True,则此向量中的坐标符号(如果存在)将重新表达为其他帧的术语
示例
>>> from sympy.physics.vector import ReferenceFrame, dynamicsymbols
>>> from sympy.physics.vector import init_vprinting
>>> init_vprinting(pretty_print=False)
>>> q1 = dynamicsymbols('q1')
>>> N = ReferenceFrame('N')
>>> A = N.orientnew('A', 'Axis', [q1, N.y])
>>> A.x.express(N)
cos(q1)*N.x - sin(q1)*N.z
free_dynamicsymbols(reference_frame)
返回在给定参考框架中表达的向量中的自由动态符号(时间函数 t
)。
参数:
reference_frame:ReferenceFrame
要确定给定向量的自由动态符号的框架。
返回:
set
时间函数
t
的集合,例如Function('f')(me.dynamicsymbols._t)
。
free_symbols(reference_frame)
返回在给定参考框架中表达的向量的测量数字中的自由符号。
参数:
reference_frame:ReferenceFrame
要确定给定向量自由符号的框架。
返回:
一组 Symbol
表达参考框架的测量数中存在的符号集。
property func
返回类向量。
magnitude()
返回自身的大小(欧几里得范数)。
警告
Python 忽略了前导负号,这可能导致错误的结果。-A.x.magnitude()
会被视为 -(A.x.magnitude())
,而不是 (-A.x).magnitude()
。
normalize()
返回大小为 1、与自身共向的向量。
outer(other)
两个向量之间的外积。
一个增加秩的操作,从两个向量返回一个二元组
参数:
其他 : 向量
与向量进行外积。
例子
>>> from sympy.physics.vector import ReferenceFrame, outer
>>> N = ReferenceFrame('N')
>>> outer(N.x, N.x)
(N.x|N.x)
separate()
根据其定义,这个向量在不同参考框架中的组成部分。
返回将每个参考框架映射到相应组成向量的字典。
例子
>>> from sympy.physics.vector import ReferenceFrame
>>> R1 = ReferenceFrame('R1')
>>> R2 = ReferenceFrame('R2')
>>> v = R1.x + R2.x
>>> v.separate() == {R1: R1.x, R2: R2.x}
True
simplify()
返回一个简化的向量。
subs(*args, **kwargs)
对向量进行替换。
例子
>>> from sympy.physics.vector import ReferenceFrame
>>> from sympy import Symbol
>>> N = ReferenceFrame('N')
>>> s = Symbol('s')
>>> a = N.x * s
>>> a.subs({s: 2})
2*N.x
to_matrix(reference_frame)
返回给定框架下向量的矩阵形式。
参数:
参考框架 : 参考框架
矩阵的行对应的参考框架。
返回:
矩阵 : 不可变矩阵,形状(3,1)
提供给 1D 向量的矩阵。
例子
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> a, b, c = symbols('a, b, c')
>>> N = ReferenceFrame('N')
>>> vector = a * N.x + b * N.y + c * N.z
>>> vector.to_matrix(N)
Matrix([
[a],
[b],
[c]])
>>> beta = symbols('beta')
>>> A = N.orientnew('A', 'Axis', (beta, N.x))
>>> vector.to_matrix(A)
Matrix([
[ a],
[ b*cos(beta) + c*sin(beta)],
[-b*sin(beta) + c*cos(beta)]])
xreplace(rule)
替换向量的测量数内的对象出现。
参数:
规则 : 类似字典
表达替换规则。
返回:
向量
替换结果。
例子
>>> from sympy import symbols, pi
>>> from sympy.physics.vector import ReferenceFrame
>>> A = ReferenceFrame('A')
>>> x, y, z = symbols('x y z')
>>> ((1 + x*y) * A.x).xreplace({x: pi})
(pi*y + 1)*A.x
>>> ((1 + x*y) * A.x).xreplace({x: pi, y: 2})
(1 + 2*pi)*A.x
仅当匹配表达树中的整个节点时才进行替换:
>>> ((x*y + z) * A.x).xreplace({x*y: pi})
(z + pi)*A.x
>>> ((x*y*z) * A.x).xreplace({x*y: pi})
x*y*z*A.x
class sympy.physics.vector.dyadic.Dyadic(inlist)
一个二元组对象。
见:en.wikipedia.org/wiki/Dyadic_tensor
Kane, T., Levinson, D. Dynamics Theory and Applications. 1985 McGraw-Hill
更强大地表示刚体的惯性的一种方法。虽然更复杂,但通过选择二元组的分量为体固定基向量,得到的矩阵等效于惯性张量。
applyfunc(f)
对二元组的每个分量应用函数。
cross(other)
返回二元组与向量的叉积结果:二元组 x 向量。
参数:
其他 : 向量
与之交叉的向量。
例子
>>> from sympy.physics.vector import ReferenceFrame, outer, cross
>>> N = ReferenceFrame('N')
>>> d = outer(N.x, N.x)
>>> cross(d, N.y)
(N.x|N.z)
doit(**hints)
对二元组中的每个项调用 .doit()
dot(other)
二元组和二元组或向量的内积运算符。
参数:
其他 : 二元组或向量
与二元组或向量进行内积的其他二元组或向量
例子
>>> from sympy.physics.vector import ReferenceFrame, outer
>>> N = ReferenceFrame('N')
>>> D1 = outer(N.x, N.y)
>>> D2 = outer(N.y, N.y)
>>> D1.dot(D2)
(N.x|N.y)
>>> D1.dot(N.y)
N.x
dt(frame)
对此二元组在一个框架中进行时间导数。
此函数调用全局 time_derivative 方法
参数:
框架 : 参考框架
用于进行时间导数的框架
例子
>>> from sympy.physics.vector import ReferenceFrame, outer, dynamicsymbols
>>> from sympy.physics.vector import init_vprinting
>>> init_vprinting(pretty_print=False)
>>> N = ReferenceFrame('N')
>>> q = dynamicsymbols('q')
>>> B = N.orientnew('B', 'Axis', [q, N.z])
>>> d = outer(N.x, N.x)
>>> d.dt(B)
- q'*(N.y|N.x) - q'*(N.x|N.y)
express(frame1, frame2=None)
表达该二元组在备用框架中
第一个框架是列表达表达式,第二个框架是右边;如果二元组以 A.x|B.y 形式存在,则可以在两个不同的框架中表达它。如果没有给出第二个框架,则二元组只在一个框架中表达。
调用全局表达函数
参数:
框架 1 : 参考框架
表达二元组左侧的框架
框架 2 : 参考框架
如果提供,则表达二元组右侧的框架
例子
>>> from sympy.physics.vector import ReferenceFrame, outer, dynamicsymbols
>>> from sympy.physics.vector import init_vprinting
>>> init_vprinting(pretty_print=False)
>>> N = ReferenceFrame('N')
>>> q = dynamicsymbols('q')
>>> B = N.orientnew('B', 'Axis', [q, N.z])
>>> d = outer(N.x, N.x)
>>> d.express(B, N)
cos(q)*(B.x|N.x) - sin(q)*(B.y|N.x)
property func
返回类二元组。
simplify()
返回一个简化的二元组。
subs(*args, **kwargs)
对二元组进行替换。
例子
>>> from sympy.physics.vector import ReferenceFrame
>>> from sympy import Symbol
>>> N = ReferenceFrame('N')
>>> s = Symbol('s')
>>> a = s*(N.x|N.x)
>>> a.subs({s: 2})
2*(N.x|N.x)
to_matrix(reference_frame, second_reference_frame=None)
返回与一个或两个参考框架相关的二阶张量形式的矩阵。
参数:
reference_frame:参考框架
矩阵的行和列所对应的参考框架。如果提供了第二个参考框架,这仅对矩阵的行起作用。
second_reference_frame:参考框架,可选,默认为 None
矩阵的列所对应的参考框架。
返回:
matrix:ImmutableMatrix,形状为(3,3)
给出二维张量形式的矩阵。
示例
>>> from sympy import symbols, trigsimp
>>> from sympy.physics.vector import ReferenceFrame
>>> from sympy.physics.mechanics import inertia
>>> Ixx, Iyy, Izz, Ixy, Iyz, Ixz = symbols('Ixx, Iyy, Izz, Ixy, Iyz, Ixz')
>>> N = ReferenceFrame('N')
>>> inertia_dyadic = inertia(N, Ixx, Iyy, Izz, Ixy, Iyz, Ixz)
>>> inertia_dyadic.to_matrix(N)
Matrix([
[Ixx, Ixy, Ixz],
[Ixy, Iyy, Iyz],
[Ixz, Iyz, Izz]])
>>> beta = symbols('beta')
>>> A = N.orientnew('A', 'Axis', (beta, N.x))
>>> trigsimp(inertia_dyadic.to_matrix(A))
Matrix([
[ Ixx, Ixy*cos(beta) + Ixz*sin(beta), -Ixy*sin(beta) + Ixz*cos(beta)],
[ Ixy*cos(beta) + Ixz*sin(beta), Iyy*cos(2*beta)/2 + Iyy/2 + Iyz*sin(2*beta) - Izz*cos(2*beta)/2 + Izz/2, -Iyy*sin(2*beta)/2 + Iyz*cos(2*beta) + Izz*sin(2*beta)/2],
[-Ixy*sin(beta) + Ixz*cos(beta), -Iyy*sin(2*beta)/2 + Iyz*cos(2*beta) + Izz*sin(2*beta)/2, -Iyy*cos(2*beta)/2 + Iyy/2 - Iyz*sin(2*beta) + Izz*cos(2*beta)/2 + Izz/2]])
xreplace(rule)
替换二阶张量测量数中对象的出现。
参数:
rule:类似字典
表达一个替换规则。
返回:
二阶张量
替换的结果。
示例
>>> from sympy import symbols, pi
>>> from sympy.physics.vector import ReferenceFrame, outer
>>> N = ReferenceFrame('N')
>>> D = outer(N.x, N.x)
>>> x, y, z = symbols('x y z')
>>> ((1 + x*y) * D).xreplace({x: pi})
(pi*y + 1)*(N.x|N.x)
>>> ((1 + x*y) * D).xreplace({x: pi, y: 2})
(1 + 2*pi)*(N.x|N.x)
只有在匹配表达式树中的整个节点时才会发生替换:
>>> ((x*y + z) * D).xreplace({x*y: pi})
(z + pi)*(N.x|N.x)
>>> ((x*y*z) * D).xreplace({x*y: pi})
x*y*z*(N.x|N.x)