Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_561/data-v1-dl-52739.arff.gz +3 -0
- .venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_61/api-v1-jd-61.json.gz +3 -0
- .venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_61/api-v1-jdf-61.json.gz +3 -0
- .venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_61/api-v1-jdq-61.json.gz +3 -0
- .venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_62/api-v1-jdf-62.json.gz +3 -0
- .venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_62/api-v1-jdq-62.json.gz +3 -0
- .venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_62/data-v1-dl-52352.arff.gz +3 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/__init__.py +0 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_operator.py +263 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_operatorordering.py +50 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_operatorset.py +68 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_pauli.py +159 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_piab.py +29 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_printing.py +900 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_qapply.py +150 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_qasm.py +89 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_qexpr.py +52 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_qft.py +52 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_state.py +248 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_tensorproduct.py +137 -0
- .venv/Lib/site-packages/sympy/physics/quantum/tests/test_trace.py +109 -0
- .venv/Lib/site-packages/sympy/physics/tests/__init__.py +0 -0
- .venv/Lib/site-packages/sympy/physics/tests/test_clebsch_gordan.py +198 -0
- .venv/Lib/site-packages/sympy/physics/tests/test_hydrogen.py +126 -0
- .venv/Lib/site-packages/sympy/physics/tests/test_paulialgebra.py +57 -0
- .venv/Lib/site-packages/sympy/physics/tests/test_physics_matrices.py +84 -0
- .venv/Lib/site-packages/sympy/physics/tests/test_pring.py +41 -0
- .venv/Lib/site-packages/sympy/physics/tests/test_qho_1d.py +50 -0
- .venv/Lib/site-packages/sympy/physics/tests/test_secondquant.py +1280 -0
- .venv/Lib/site-packages/sympy/physics/tests/test_sho.py +21 -0
- .venv/Lib/site-packages/sympy/physics/units/__init__.py +453 -0
- .venv/Lib/site-packages/sympy/physics/units/definitions/__init__.py +265 -0
- .venv/Lib/site-packages/sympy/physics/units/definitions/dimension_definitions.py +43 -0
- .venv/Lib/site-packages/sympy/physics/units/definitions/unit_definitions.py +407 -0
- .venv/Lib/site-packages/sympy/physics/units/dimensions.py +590 -0
- .venv/Lib/site-packages/sympy/physics/units/prefixes.py +219 -0
- .venv/Lib/site-packages/sympy/physics/units/quantities.py +152 -0
- .venv/Lib/site-packages/sympy/physics/units/systems/__init__.py +6 -0
- .venv/Lib/site-packages/sympy/physics/units/systems/cgs.py +82 -0
- .venv/Lib/site-packages/sympy/physics/units/systems/length_weight_time.py +156 -0
- .venv/Lib/site-packages/sympy/physics/units/systems/mks.py +46 -0
- .venv/Lib/site-packages/sympy/physics/units/systems/mksa.py +54 -0
- .venv/Lib/site-packages/sympy/physics/units/systems/natural.py +27 -0
- .venv/Lib/site-packages/sympy/physics/units/systems/si.py +377 -0
- .venv/Lib/site-packages/sympy/physics/units/tests/__init__.py +0 -0
- .venv/Lib/site-packages/sympy/physics/units/tests/test_dimensions.py +150 -0
- .venv/Lib/site-packages/sympy/physics/units/tests/test_dimensionsystem.py +95 -0
- .venv/Lib/site-packages/sympy/physics/units/tests/test_prefixes.py +86 -0
- .venv/Lib/site-packages/sympy/physics/units/tests/test_quantities.py +575 -0
- .venv/Lib/site-packages/sympy/physics/units/tests/test_unit_system_cgs_gauss.py +55 -0
.venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_561/data-v1-dl-52739.arff.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e96142b5e00dfec2617b0c22d7192b340ae2c28ec3ffc3a894c5be746b970a59
|
| 3 |
+
size 3303
|
.venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_61/api-v1-jd-61.json.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a5c7e79aa41ef580838fb9fc1906280f076c47be1741fddd5004ddb500eb57fe
|
| 3 |
+
size 898
|
.venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_61/api-v1-jdf-61.json.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:33cbd6ae945ba04969370ab35604e9363c87256393493382b5118a89d59386d6
|
| 3 |
+
size 268
|
.venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_61/api-v1-jdq-61.json.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:424cd47c12a51c7bb8d8169fac80fb5601f152bd78468b241d4b115bf7d22f20
|
| 3 |
+
size 1121
|
.venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_62/api-v1-jdf-62.json.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:489b177126cb7f335cb220709233b946d3a0ad71d38bba6d48b79187146e585a
|
| 3 |
+
size 817
|
.venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_62/api-v1-jdq-62.json.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:278a52a52d569f07d14c6a7877b104762c77daac429fb1fd9817a0378d6ec634
|
| 3 |
+
size 805
|
.venv/Lib/site-packages/sklearn/datasets/tests/data/openml/id_62/data-v1-dl-52352.arff.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:fb5830c82112f62a400c82ac1f1b5eb61c29c0a7cc72ba56d2aeff0fae8a60f9
|
| 3 |
+
size 1625
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/__init__.py
ADDED
|
File without changes
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_operator.py
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.function import (Derivative, Function, diff)
|
| 2 |
+
from sympy.core.mul import Mul
|
| 3 |
+
from sympy.core.numbers import (Integer, pi)
|
| 4 |
+
from sympy.core.symbol import (Symbol, symbols)
|
| 5 |
+
from sympy.functions.elementary.trigonometric import sin
|
| 6 |
+
from sympy.physics.quantum.qexpr import QExpr
|
| 7 |
+
from sympy.physics.quantum.dagger import Dagger
|
| 8 |
+
from sympy.physics.quantum.hilbert import HilbertSpace
|
| 9 |
+
from sympy.physics.quantum.operator import (Operator, UnitaryOperator,
|
| 10 |
+
HermitianOperator, OuterProduct,
|
| 11 |
+
DifferentialOperator,
|
| 12 |
+
IdentityOperator)
|
| 13 |
+
from sympy.physics.quantum.state import Ket, Bra, Wavefunction
|
| 14 |
+
from sympy.physics.quantum.qapply import qapply
|
| 15 |
+
from sympy.physics.quantum.represent import represent
|
| 16 |
+
from sympy.physics.quantum.spin import JzKet, JzBra
|
| 17 |
+
from sympy.physics.quantum.trace import Tr
|
| 18 |
+
from sympy.matrices import eye
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
class CustomKet(Ket):
|
| 22 |
+
@classmethod
|
| 23 |
+
def default_args(self):
|
| 24 |
+
return ("t",)
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
class CustomOp(HermitianOperator):
|
| 28 |
+
@classmethod
|
| 29 |
+
def default_args(self):
|
| 30 |
+
return ("T",)
|
| 31 |
+
|
| 32 |
+
t_ket = CustomKet()
|
| 33 |
+
t_op = CustomOp()
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def test_operator():
|
| 37 |
+
A = Operator('A')
|
| 38 |
+
B = Operator('B')
|
| 39 |
+
C = Operator('C')
|
| 40 |
+
|
| 41 |
+
assert isinstance(A, Operator)
|
| 42 |
+
assert isinstance(A, QExpr)
|
| 43 |
+
|
| 44 |
+
assert A.label == (Symbol('A'),)
|
| 45 |
+
assert A.is_commutative is False
|
| 46 |
+
assert A.hilbert_space == HilbertSpace()
|
| 47 |
+
|
| 48 |
+
assert A*B != B*A
|
| 49 |
+
|
| 50 |
+
assert (A*(B + C)).expand() == A*B + A*C
|
| 51 |
+
assert ((A + B)**2).expand() == A**2 + A*B + B*A + B**2
|
| 52 |
+
|
| 53 |
+
assert t_op.label[0] == Symbol(t_op.default_args()[0])
|
| 54 |
+
|
| 55 |
+
assert Operator() == Operator("O")
|
| 56 |
+
assert A*IdentityOperator() == A
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def test_operator_inv():
|
| 60 |
+
A = Operator('A')
|
| 61 |
+
assert A*A.inv() == 1
|
| 62 |
+
assert A.inv()*A == 1
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def test_hermitian():
|
| 66 |
+
H = HermitianOperator('H')
|
| 67 |
+
|
| 68 |
+
assert isinstance(H, HermitianOperator)
|
| 69 |
+
assert isinstance(H, Operator)
|
| 70 |
+
|
| 71 |
+
assert Dagger(H) == H
|
| 72 |
+
assert H.inv() != H
|
| 73 |
+
assert H.is_commutative is False
|
| 74 |
+
assert Dagger(H).is_commutative is False
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def test_unitary():
|
| 78 |
+
U = UnitaryOperator('U')
|
| 79 |
+
|
| 80 |
+
assert isinstance(U, UnitaryOperator)
|
| 81 |
+
assert isinstance(U, Operator)
|
| 82 |
+
|
| 83 |
+
assert U.inv() == Dagger(U)
|
| 84 |
+
assert U*Dagger(U) == 1
|
| 85 |
+
assert Dagger(U)*U == 1
|
| 86 |
+
assert U.is_commutative is False
|
| 87 |
+
assert Dagger(U).is_commutative is False
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def test_identity():
|
| 91 |
+
I = IdentityOperator()
|
| 92 |
+
O = Operator('O')
|
| 93 |
+
x = Symbol("x")
|
| 94 |
+
|
| 95 |
+
assert isinstance(I, IdentityOperator)
|
| 96 |
+
assert isinstance(I, Operator)
|
| 97 |
+
|
| 98 |
+
assert I * O == O
|
| 99 |
+
assert O * I == O
|
| 100 |
+
assert I * Dagger(O) == Dagger(O)
|
| 101 |
+
assert Dagger(O) * I == Dagger(O)
|
| 102 |
+
assert isinstance(I * I, IdentityOperator)
|
| 103 |
+
assert isinstance(3 * I, Mul)
|
| 104 |
+
assert isinstance(I * x, Mul)
|
| 105 |
+
assert I.inv() == I
|
| 106 |
+
assert Dagger(I) == I
|
| 107 |
+
assert qapply(I * O) == O
|
| 108 |
+
assert qapply(O * I) == O
|
| 109 |
+
|
| 110 |
+
for n in [2, 3, 5]:
|
| 111 |
+
assert represent(IdentityOperator(n)) == eye(n)
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
def test_outer_product():
|
| 115 |
+
k = Ket('k')
|
| 116 |
+
b = Bra('b')
|
| 117 |
+
op = OuterProduct(k, b)
|
| 118 |
+
|
| 119 |
+
assert isinstance(op, OuterProduct)
|
| 120 |
+
assert isinstance(op, Operator)
|
| 121 |
+
|
| 122 |
+
assert op.ket == k
|
| 123 |
+
assert op.bra == b
|
| 124 |
+
assert op.label == (k, b)
|
| 125 |
+
assert op.is_commutative is False
|
| 126 |
+
|
| 127 |
+
op = k*b
|
| 128 |
+
|
| 129 |
+
assert isinstance(op, OuterProduct)
|
| 130 |
+
assert isinstance(op, Operator)
|
| 131 |
+
|
| 132 |
+
assert op.ket == k
|
| 133 |
+
assert op.bra == b
|
| 134 |
+
assert op.label == (k, b)
|
| 135 |
+
assert op.is_commutative is False
|
| 136 |
+
|
| 137 |
+
op = 2*k*b
|
| 138 |
+
|
| 139 |
+
assert op == Mul(Integer(2), k, b)
|
| 140 |
+
|
| 141 |
+
op = 2*(k*b)
|
| 142 |
+
|
| 143 |
+
assert op == Mul(Integer(2), OuterProduct(k, b))
|
| 144 |
+
|
| 145 |
+
assert Dagger(k*b) == OuterProduct(Dagger(b), Dagger(k))
|
| 146 |
+
assert Dagger(k*b).is_commutative is False
|
| 147 |
+
|
| 148 |
+
#test the _eval_trace
|
| 149 |
+
assert Tr(OuterProduct(JzKet(1, 1), JzBra(1, 1))).doit() == 1
|
| 150 |
+
|
| 151 |
+
# test scaled kets and bras
|
| 152 |
+
assert OuterProduct(2 * k, b) == 2 * OuterProduct(k, b)
|
| 153 |
+
assert OuterProduct(k, 2 * b) == 2 * OuterProduct(k, b)
|
| 154 |
+
|
| 155 |
+
# test sums of kets and bras
|
| 156 |
+
k1, k2 = Ket('k1'), Ket('k2')
|
| 157 |
+
b1, b2 = Bra('b1'), Bra('b2')
|
| 158 |
+
assert (OuterProduct(k1 + k2, b1) ==
|
| 159 |
+
OuterProduct(k1, b1) + OuterProduct(k2, b1))
|
| 160 |
+
assert (OuterProduct(k1, b1 + b2) ==
|
| 161 |
+
OuterProduct(k1, b1) + OuterProduct(k1, b2))
|
| 162 |
+
assert (OuterProduct(1 * k1 + 2 * k2, 3 * b1 + 4 * b2) ==
|
| 163 |
+
3 * OuterProduct(k1, b1) +
|
| 164 |
+
4 * OuterProduct(k1, b2) +
|
| 165 |
+
6 * OuterProduct(k2, b1) +
|
| 166 |
+
8 * OuterProduct(k2, b2))
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
def test_operator_dagger():
|
| 170 |
+
A = Operator('A')
|
| 171 |
+
B = Operator('B')
|
| 172 |
+
assert Dagger(A*B) == Dagger(B)*Dagger(A)
|
| 173 |
+
assert Dagger(A + B) == Dagger(A) + Dagger(B)
|
| 174 |
+
assert Dagger(A**2) == Dagger(A)**2
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
def test_differential_operator():
|
| 178 |
+
x = Symbol('x')
|
| 179 |
+
f = Function('f')
|
| 180 |
+
d = DifferentialOperator(Derivative(f(x), x), f(x))
|
| 181 |
+
g = Wavefunction(x**2, x)
|
| 182 |
+
assert qapply(d*g) == Wavefunction(2*x, x)
|
| 183 |
+
assert d.expr == Derivative(f(x), x)
|
| 184 |
+
assert d.function == f(x)
|
| 185 |
+
assert d.variables == (x,)
|
| 186 |
+
assert diff(d, x) == DifferentialOperator(Derivative(f(x), x, 2), f(x))
|
| 187 |
+
|
| 188 |
+
d = DifferentialOperator(Derivative(f(x), x, 2), f(x))
|
| 189 |
+
g = Wavefunction(x**3, x)
|
| 190 |
+
assert qapply(d*g) == Wavefunction(6*x, x)
|
| 191 |
+
assert d.expr == Derivative(f(x), x, 2)
|
| 192 |
+
assert d.function == f(x)
|
| 193 |
+
assert d.variables == (x,)
|
| 194 |
+
assert diff(d, x) == DifferentialOperator(Derivative(f(x), x, 3), f(x))
|
| 195 |
+
|
| 196 |
+
d = DifferentialOperator(1/x*Derivative(f(x), x), f(x))
|
| 197 |
+
assert d.expr == 1/x*Derivative(f(x), x)
|
| 198 |
+
assert d.function == f(x)
|
| 199 |
+
assert d.variables == (x,)
|
| 200 |
+
assert diff(d, x) == \
|
| 201 |
+
DifferentialOperator(Derivative(1/x*Derivative(f(x), x), x), f(x))
|
| 202 |
+
assert qapply(d*g) == Wavefunction(3*x, x)
|
| 203 |
+
|
| 204 |
+
# 2D cartesian Laplacian
|
| 205 |
+
y = Symbol('y')
|
| 206 |
+
d = DifferentialOperator(Derivative(f(x, y), x, 2) +
|
| 207 |
+
Derivative(f(x, y), y, 2), f(x, y))
|
| 208 |
+
w = Wavefunction(x**3*y**2 + y**3*x**2, x, y)
|
| 209 |
+
assert d.expr == Derivative(f(x, y), x, 2) + Derivative(f(x, y), y, 2)
|
| 210 |
+
assert d.function == f(x, y)
|
| 211 |
+
assert d.variables == (x, y)
|
| 212 |
+
assert diff(d, x) == \
|
| 213 |
+
DifferentialOperator(Derivative(d.expr, x), f(x, y))
|
| 214 |
+
assert diff(d, y) == \
|
| 215 |
+
DifferentialOperator(Derivative(d.expr, y), f(x, y))
|
| 216 |
+
assert qapply(d*w) == Wavefunction(2*x**3 + 6*x*y**2 + 6*x**2*y + 2*y**3,
|
| 217 |
+
x, y)
|
| 218 |
+
|
| 219 |
+
# 2D polar Laplacian (th = theta)
|
| 220 |
+
r, th = symbols('r th')
|
| 221 |
+
d = DifferentialOperator(1/r*Derivative(r*Derivative(f(r, th), r), r) +
|
| 222 |
+
1/(r**2)*Derivative(f(r, th), th, 2), f(r, th))
|
| 223 |
+
w = Wavefunction(r**2*sin(th), r, (th, 0, pi))
|
| 224 |
+
assert d.expr == \
|
| 225 |
+
1/r*Derivative(r*Derivative(f(r, th), r), r) + \
|
| 226 |
+
1/(r**2)*Derivative(f(r, th), th, 2)
|
| 227 |
+
assert d.function == f(r, th)
|
| 228 |
+
assert d.variables == (r, th)
|
| 229 |
+
assert diff(d, r) == \
|
| 230 |
+
DifferentialOperator(Derivative(d.expr, r), f(r, th))
|
| 231 |
+
assert diff(d, th) == \
|
| 232 |
+
DifferentialOperator(Derivative(d.expr, th), f(r, th))
|
| 233 |
+
assert qapply(d*w) == Wavefunction(3*sin(th), r, (th, 0, pi))
|
| 234 |
+
|
| 235 |
+
|
| 236 |
+
def test_eval_power():
|
| 237 |
+
from sympy.core import Pow
|
| 238 |
+
from sympy.core.expr import unchanged
|
| 239 |
+
O = Operator('O')
|
| 240 |
+
U = UnitaryOperator('U')
|
| 241 |
+
H = HermitianOperator('H')
|
| 242 |
+
assert O**-1 == O.inv() # same as doc test
|
| 243 |
+
assert U**-1 == U.inv()
|
| 244 |
+
assert H**-1 == H.inv()
|
| 245 |
+
x = symbols("x", commutative = True)
|
| 246 |
+
assert unchanged(Pow, H, x) # verify Pow(H,x)=="X^n"
|
| 247 |
+
assert H**x == Pow(H, x)
|
| 248 |
+
assert Pow(H,x) == Pow(H, x, evaluate=False) # Just check
|
| 249 |
+
from sympy.physics.quantum.gate import XGate
|
| 250 |
+
X = XGate(0) # is hermitian and unitary
|
| 251 |
+
assert unchanged(Pow, X, x) # verify Pow(X,x)=="X^x"
|
| 252 |
+
assert X**x == Pow(X, x)
|
| 253 |
+
assert Pow(X, x, evaluate=False) == Pow(X, x) # Just check
|
| 254 |
+
n = symbols("n", integer=True, even=True)
|
| 255 |
+
assert X**n == 1
|
| 256 |
+
n = symbols("n", integer=True, odd=True)
|
| 257 |
+
assert X**n == X
|
| 258 |
+
n = symbols("n", integer=True)
|
| 259 |
+
assert unchanged(Pow, X, n) # verify Pow(X,n)=="X^n"
|
| 260 |
+
assert X**n == Pow(X, n)
|
| 261 |
+
assert Pow(X, n, evaluate=False)==Pow(X, n) # Just check
|
| 262 |
+
assert X**4 == 1
|
| 263 |
+
assert X**7 == X
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_operatorordering.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.physics.quantum import Dagger
|
| 2 |
+
from sympy.physics.quantum.boson import BosonOp
|
| 3 |
+
from sympy.physics.quantum.fermion import FermionOp
|
| 4 |
+
from sympy.physics.quantum.operatorordering import (normal_order,
|
| 5 |
+
normal_ordered_form)
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def test_normal_order():
|
| 9 |
+
a = BosonOp('a')
|
| 10 |
+
|
| 11 |
+
c = FermionOp('c')
|
| 12 |
+
|
| 13 |
+
assert normal_order(a * Dagger(a)) == Dagger(a) * a
|
| 14 |
+
assert normal_order(Dagger(a) * a) == Dagger(a) * a
|
| 15 |
+
assert normal_order(a * Dagger(a) ** 2) == Dagger(a) ** 2 * a
|
| 16 |
+
|
| 17 |
+
assert normal_order(c * Dagger(c)) == - Dagger(c) * c
|
| 18 |
+
assert normal_order(Dagger(c) * c) == Dagger(c) * c
|
| 19 |
+
assert normal_order(c * Dagger(c) ** 2) == Dagger(c) ** 2 * c
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def test_normal_ordered_form():
|
| 23 |
+
a = BosonOp('a')
|
| 24 |
+
b = BosonOp('b')
|
| 25 |
+
|
| 26 |
+
c = FermionOp('c')
|
| 27 |
+
d = FermionOp('d')
|
| 28 |
+
|
| 29 |
+
assert normal_ordered_form(Dagger(a) * a) == Dagger(a) * a
|
| 30 |
+
assert normal_ordered_form(a * Dagger(a)) == 1 + Dagger(a) * a
|
| 31 |
+
assert normal_ordered_form(a ** 2 * Dagger(a)) == \
|
| 32 |
+
2 * a + Dagger(a) * a ** 2
|
| 33 |
+
assert normal_ordered_form(a ** 3 * Dagger(a)) == \
|
| 34 |
+
3 * a ** 2 + Dagger(a) * a ** 3
|
| 35 |
+
|
| 36 |
+
assert normal_ordered_form(Dagger(c) * c) == Dagger(c) * c
|
| 37 |
+
assert normal_ordered_form(c * Dagger(c)) == 1 - Dagger(c) * c
|
| 38 |
+
assert normal_ordered_form(c ** 2 * Dagger(c)) == Dagger(c) * c ** 2
|
| 39 |
+
assert normal_ordered_form(c ** 3 * Dagger(c)) == \
|
| 40 |
+
c ** 2 - Dagger(c) * c ** 3
|
| 41 |
+
|
| 42 |
+
assert normal_ordered_form(a * Dagger(b), True) == Dagger(b) * a
|
| 43 |
+
assert normal_ordered_form(Dagger(a) * b, True) == Dagger(a) * b
|
| 44 |
+
assert normal_ordered_form(b * a, True) == a * b
|
| 45 |
+
assert normal_ordered_form(Dagger(b) * Dagger(a), True) == Dagger(a) * Dagger(b)
|
| 46 |
+
|
| 47 |
+
assert normal_ordered_form(c * Dagger(d), True) == -Dagger(d) * c
|
| 48 |
+
assert normal_ordered_form(Dagger(c) * d, True) == Dagger(c) * d
|
| 49 |
+
assert normal_ordered_form(d * c, True) == -c * d
|
| 50 |
+
assert normal_ordered_form(Dagger(d) * Dagger(c), True) == -Dagger(c) * Dagger(d)
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_operatorset.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.singleton import S
|
| 2 |
+
|
| 3 |
+
from sympy.physics.quantum.operatorset import (
|
| 4 |
+
operators_to_state, state_to_operators
|
| 5 |
+
)
|
| 6 |
+
|
| 7 |
+
from sympy.physics.quantum.cartesian import (
|
| 8 |
+
XOp, XKet, PxOp, PxKet, XBra, PxBra
|
| 9 |
+
)
|
| 10 |
+
|
| 11 |
+
from sympy.physics.quantum.state import Ket, Bra
|
| 12 |
+
from sympy.physics.quantum.operator import Operator
|
| 13 |
+
from sympy.physics.quantum.spin import (
|
| 14 |
+
JxKet, JyKet, JzKet, JxBra, JyBra, JzBra,
|
| 15 |
+
JxOp, JyOp, JzOp, J2Op
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
from sympy.testing.pytest import raises
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def test_spin():
|
| 22 |
+
assert operators_to_state({J2Op, JxOp}) == JxKet
|
| 23 |
+
assert operators_to_state({J2Op, JyOp}) == JyKet
|
| 24 |
+
assert operators_to_state({J2Op, JzOp}) == JzKet
|
| 25 |
+
assert operators_to_state({J2Op(), JxOp()}) == JxKet
|
| 26 |
+
assert operators_to_state({J2Op(), JyOp()}) == JyKet
|
| 27 |
+
assert operators_to_state({J2Op(), JzOp()}) == JzKet
|
| 28 |
+
|
| 29 |
+
assert state_to_operators(JxKet) == {J2Op, JxOp}
|
| 30 |
+
assert state_to_operators(JyKet) == {J2Op, JyOp}
|
| 31 |
+
assert state_to_operators(JzKet) == {J2Op, JzOp}
|
| 32 |
+
assert state_to_operators(JxBra) == {J2Op, JxOp}
|
| 33 |
+
assert state_to_operators(JyBra) == {J2Op, JyOp}
|
| 34 |
+
assert state_to_operators(JzBra) == {J2Op, JzOp}
|
| 35 |
+
|
| 36 |
+
assert state_to_operators(JxKet(S.Half, S.Half)) == {J2Op(), JxOp()}
|
| 37 |
+
assert state_to_operators(JyKet(S.Half, S.Half)) == {J2Op(), JyOp()}
|
| 38 |
+
assert state_to_operators(JzKet(S.Half, S.Half)) == {J2Op(), JzOp()}
|
| 39 |
+
assert state_to_operators(JxBra(S.Half, S.Half)) == {J2Op(), JxOp()}
|
| 40 |
+
assert state_to_operators(JyBra(S.Half, S.Half)) == {J2Op(), JyOp()}
|
| 41 |
+
assert state_to_operators(JzBra(S.Half, S.Half)) == {J2Op(), JzOp()}
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def test_op_to_state():
|
| 45 |
+
assert operators_to_state(XOp) == XKet()
|
| 46 |
+
assert operators_to_state(PxOp) == PxKet()
|
| 47 |
+
assert operators_to_state(Operator) == Ket()
|
| 48 |
+
|
| 49 |
+
assert state_to_operators(operators_to_state(XOp("Q"))) == XOp("Q")
|
| 50 |
+
assert state_to_operators(operators_to_state(XOp())) == XOp()
|
| 51 |
+
|
| 52 |
+
raises(NotImplementedError, lambda: operators_to_state(XKet))
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def test_state_to_op():
|
| 56 |
+
assert state_to_operators(XKet) == XOp()
|
| 57 |
+
assert state_to_operators(PxKet) == PxOp()
|
| 58 |
+
assert state_to_operators(XBra) == XOp()
|
| 59 |
+
assert state_to_operators(PxBra) == PxOp()
|
| 60 |
+
assert state_to_operators(Ket) == Operator()
|
| 61 |
+
assert state_to_operators(Bra) == Operator()
|
| 62 |
+
|
| 63 |
+
assert operators_to_state(state_to_operators(XKet("test"))) == XKet("test")
|
| 64 |
+
assert operators_to_state(state_to_operators(XBra("test"))) == XKet("test")
|
| 65 |
+
assert operators_to_state(state_to_operators(XKet())) == XKet()
|
| 66 |
+
assert operators_to_state(state_to_operators(XBra())) == XKet()
|
| 67 |
+
|
| 68 |
+
raises(NotImplementedError, lambda: state_to_operators(XOp))
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_pauli.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.mul import Mul
|
| 2 |
+
from sympy.core.numbers import I
|
| 3 |
+
from sympy.matrices.dense import Matrix
|
| 4 |
+
from sympy.printing.latex import latex
|
| 5 |
+
from sympy.physics.quantum import (Dagger, Commutator, AntiCommutator, qapply,
|
| 6 |
+
Operator, represent)
|
| 7 |
+
from sympy.physics.quantum.pauli import (SigmaOpBase, SigmaX, SigmaY, SigmaZ,
|
| 8 |
+
SigmaMinus, SigmaPlus,
|
| 9 |
+
qsimplify_pauli)
|
| 10 |
+
from sympy.physics.quantum.pauli import SigmaZKet, SigmaZBra
|
| 11 |
+
from sympy.testing.pytest import raises
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
sx, sy, sz = SigmaX(), SigmaY(), SigmaZ()
|
| 15 |
+
sx1, sy1, sz1 = SigmaX(1), SigmaY(1), SigmaZ(1)
|
| 16 |
+
sx2, sy2, sz2 = SigmaX(2), SigmaY(2), SigmaZ(2)
|
| 17 |
+
|
| 18 |
+
sm, sp = SigmaMinus(), SigmaPlus()
|
| 19 |
+
sm1, sp1 = SigmaMinus(1), SigmaPlus(1)
|
| 20 |
+
A, B = Operator("A"), Operator("B")
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def test_pauli_operators_types():
|
| 24 |
+
|
| 25 |
+
assert isinstance(sx, SigmaOpBase) and isinstance(sx, SigmaX)
|
| 26 |
+
assert isinstance(sy, SigmaOpBase) and isinstance(sy, SigmaY)
|
| 27 |
+
assert isinstance(sz, SigmaOpBase) and isinstance(sz, SigmaZ)
|
| 28 |
+
assert isinstance(sm, SigmaOpBase) and isinstance(sm, SigmaMinus)
|
| 29 |
+
assert isinstance(sp, SigmaOpBase) and isinstance(sp, SigmaPlus)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def test_pauli_operators_commutator():
|
| 33 |
+
|
| 34 |
+
assert Commutator(sx, sy).doit() == 2 * I * sz
|
| 35 |
+
assert Commutator(sy, sz).doit() == 2 * I * sx
|
| 36 |
+
assert Commutator(sz, sx).doit() == 2 * I * sy
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def test_pauli_operators_commutator_with_labels():
|
| 40 |
+
|
| 41 |
+
assert Commutator(sx1, sy1).doit() == 2 * I * sz1
|
| 42 |
+
assert Commutator(sy1, sz1).doit() == 2 * I * sx1
|
| 43 |
+
assert Commutator(sz1, sx1).doit() == 2 * I * sy1
|
| 44 |
+
|
| 45 |
+
assert Commutator(sx2, sy2).doit() == 2 * I * sz2
|
| 46 |
+
assert Commutator(sy2, sz2).doit() == 2 * I * sx2
|
| 47 |
+
assert Commutator(sz2, sx2).doit() == 2 * I * sy2
|
| 48 |
+
|
| 49 |
+
assert Commutator(sx1, sy2).doit() == 0
|
| 50 |
+
assert Commutator(sy1, sz2).doit() == 0
|
| 51 |
+
assert Commutator(sz1, sx2).doit() == 0
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def test_pauli_operators_anticommutator():
|
| 55 |
+
|
| 56 |
+
assert AntiCommutator(sy, sz).doit() == 0
|
| 57 |
+
assert AntiCommutator(sz, sx).doit() == 0
|
| 58 |
+
assert AntiCommutator(sx, sm).doit() == 1
|
| 59 |
+
assert AntiCommutator(sx, sp).doit() == 1
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def test_pauli_operators_adjoint():
|
| 63 |
+
|
| 64 |
+
assert Dagger(sx) == sx
|
| 65 |
+
assert Dagger(sy) == sy
|
| 66 |
+
assert Dagger(sz) == sz
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def test_pauli_operators_adjoint_with_labels():
|
| 70 |
+
|
| 71 |
+
assert Dagger(sx1) == sx1
|
| 72 |
+
assert Dagger(sy1) == sy1
|
| 73 |
+
assert Dagger(sz1) == sz1
|
| 74 |
+
|
| 75 |
+
assert Dagger(sx1) != sx2
|
| 76 |
+
assert Dagger(sy1) != sy2
|
| 77 |
+
assert Dagger(sz1) != sz2
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def test_pauli_operators_multiplication():
|
| 81 |
+
|
| 82 |
+
assert qsimplify_pauli(sx * sx) == 1
|
| 83 |
+
assert qsimplify_pauli(sy * sy) == 1
|
| 84 |
+
assert qsimplify_pauli(sz * sz) == 1
|
| 85 |
+
|
| 86 |
+
assert qsimplify_pauli(sx * sy) == I * sz
|
| 87 |
+
assert qsimplify_pauli(sy * sz) == I * sx
|
| 88 |
+
assert qsimplify_pauli(sz * sx) == I * sy
|
| 89 |
+
|
| 90 |
+
assert qsimplify_pauli(sy * sx) == - I * sz
|
| 91 |
+
assert qsimplify_pauli(sz * sy) == - I * sx
|
| 92 |
+
assert qsimplify_pauli(sx * sz) == - I * sy
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
def test_pauli_operators_multiplication_with_labels():
|
| 96 |
+
|
| 97 |
+
assert qsimplify_pauli(sx1 * sx1) == 1
|
| 98 |
+
assert qsimplify_pauli(sy1 * sy1) == 1
|
| 99 |
+
assert qsimplify_pauli(sz1 * sz1) == 1
|
| 100 |
+
|
| 101 |
+
assert isinstance(sx1 * sx2, Mul)
|
| 102 |
+
assert isinstance(sy1 * sy2, Mul)
|
| 103 |
+
assert isinstance(sz1 * sz2, Mul)
|
| 104 |
+
|
| 105 |
+
assert qsimplify_pauli(sx1 * sy1 * sx2 * sy2) == - sz1 * sz2
|
| 106 |
+
assert qsimplify_pauli(sy1 * sz1 * sz2 * sx2) == - sx1 * sy2
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def test_pauli_states():
|
| 110 |
+
sx, sz = SigmaX(), SigmaZ()
|
| 111 |
+
|
| 112 |
+
up = SigmaZKet(0)
|
| 113 |
+
down = SigmaZKet(1)
|
| 114 |
+
|
| 115 |
+
assert qapply(sx * up) == down
|
| 116 |
+
assert qapply(sx * down) == up
|
| 117 |
+
assert qapply(sz * up) == up
|
| 118 |
+
assert qapply(sz * down) == - down
|
| 119 |
+
|
| 120 |
+
up = SigmaZBra(0)
|
| 121 |
+
down = SigmaZBra(1)
|
| 122 |
+
|
| 123 |
+
assert qapply(up * sx, dagger=True) == down
|
| 124 |
+
assert qapply(down * sx, dagger=True) == up
|
| 125 |
+
assert qapply(up * sz, dagger=True) == up
|
| 126 |
+
assert qapply(down * sz, dagger=True) == - down
|
| 127 |
+
|
| 128 |
+
assert Dagger(SigmaZKet(0)) == SigmaZBra(0)
|
| 129 |
+
assert Dagger(SigmaZBra(1)) == SigmaZKet(1)
|
| 130 |
+
raises(ValueError, lambda: SigmaZBra(2))
|
| 131 |
+
raises(ValueError, lambda: SigmaZKet(2))
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def test_use_name():
|
| 135 |
+
assert sm.use_name is False
|
| 136 |
+
assert sm1.use_name is True
|
| 137 |
+
assert sx.use_name is False
|
| 138 |
+
assert sx1.use_name is True
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def test_printing():
|
| 142 |
+
assert latex(sx) == r'{\sigma_x}'
|
| 143 |
+
assert latex(sx1) == r'{\sigma_x^{(1)}}'
|
| 144 |
+
assert latex(sy) == r'{\sigma_y}'
|
| 145 |
+
assert latex(sy1) == r'{\sigma_y^{(1)}}'
|
| 146 |
+
assert latex(sz) == r'{\sigma_z}'
|
| 147 |
+
assert latex(sz1) == r'{\sigma_z^{(1)}}'
|
| 148 |
+
assert latex(sm) == r'{\sigma_-}'
|
| 149 |
+
assert latex(sm1) == r'{\sigma_-^{(1)}}'
|
| 150 |
+
assert latex(sp) == r'{\sigma_+}'
|
| 151 |
+
assert latex(sp1) == r'{\sigma_+^{(1)}}'
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def test_represent():
|
| 155 |
+
assert represent(sx) == Matrix([[0, 1], [1, 0]])
|
| 156 |
+
assert represent(sy) == Matrix([[0, -I], [I, 0]])
|
| 157 |
+
assert represent(sz) == Matrix([[1, 0], [0, -1]])
|
| 158 |
+
assert represent(sm) == Matrix([[0, 0], [1, 0]])
|
| 159 |
+
assert represent(sp) == Matrix([[0, 1], [0, 0]])
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_piab.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Tests for piab.py"""
|
| 2 |
+
|
| 3 |
+
from sympy.core.numbers import pi
|
| 4 |
+
from sympy.core.singleton import S
|
| 5 |
+
from sympy.core.symbol import symbols
|
| 6 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 7 |
+
from sympy.functions.elementary.trigonometric import sin
|
| 8 |
+
from sympy.sets.sets import Interval
|
| 9 |
+
from sympy.functions.special.tensor_functions import KroneckerDelta
|
| 10 |
+
from sympy.physics.quantum import L2, qapply, hbar, represent
|
| 11 |
+
from sympy.physics.quantum.piab import PIABHamiltonian, PIABKet, PIABBra, m, L
|
| 12 |
+
|
| 13 |
+
i, j, n, x = symbols('i j n x')
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def test_H():
|
| 17 |
+
assert PIABHamiltonian('H').hilbert_space == \
|
| 18 |
+
L2(Interval(S.NegativeInfinity, S.Infinity))
|
| 19 |
+
assert qapply(PIABHamiltonian('H')*PIABKet(n)) == \
|
| 20 |
+
(n**2*pi**2*hbar**2)/(2*m*L**2)*PIABKet(n)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def test_states():
|
| 24 |
+
assert PIABKet(n).dual_class() == PIABBra
|
| 25 |
+
assert PIABKet(n).hilbert_space == \
|
| 26 |
+
L2(Interval(S.NegativeInfinity, S.Infinity))
|
| 27 |
+
assert represent(PIABKet(n)) == sqrt(2/L)*sin(n*pi*x/L)
|
| 28 |
+
assert (PIABBra(i)*PIABKet(j)).doit() == KroneckerDelta(i, j)
|
| 29 |
+
assert PIABBra(n).dual_class() == PIABKet
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_printing.py
ADDED
|
@@ -0,0 +1,900 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- encoding: utf-8 -*-
|
| 2 |
+
"""
|
| 3 |
+
TODO:
|
| 4 |
+
* Address Issue 2251, printing of spin states
|
| 5 |
+
"""
|
| 6 |
+
from __future__ import annotations
|
| 7 |
+
from typing import Any
|
| 8 |
+
|
| 9 |
+
from sympy.physics.quantum.anticommutator import AntiCommutator
|
| 10 |
+
from sympy.physics.quantum.cg import CG, Wigner3j, Wigner6j, Wigner9j
|
| 11 |
+
from sympy.physics.quantum.commutator import Commutator
|
| 12 |
+
from sympy.physics.quantum.constants import hbar
|
| 13 |
+
from sympy.physics.quantum.dagger import Dagger
|
| 14 |
+
from sympy.physics.quantum.gate import CGate, CNotGate, IdentityGate, UGate, XGate
|
| 15 |
+
from sympy.physics.quantum.hilbert import ComplexSpace, FockSpace, HilbertSpace, L2
|
| 16 |
+
from sympy.physics.quantum.innerproduct import InnerProduct
|
| 17 |
+
from sympy.physics.quantum.operator import Operator, OuterProduct, DifferentialOperator
|
| 18 |
+
from sympy.physics.quantum.qexpr import QExpr
|
| 19 |
+
from sympy.physics.quantum.qubit import Qubit, IntQubit
|
| 20 |
+
from sympy.physics.quantum.spin import Jz, J2, JzBra, JzBraCoupled, JzKet, JzKetCoupled, Rotation, WignerD
|
| 21 |
+
from sympy.physics.quantum.state import Bra, Ket, TimeDepBra, TimeDepKet
|
| 22 |
+
from sympy.physics.quantum.tensorproduct import TensorProduct
|
| 23 |
+
from sympy.physics.quantum.sho1d import RaisingOp
|
| 24 |
+
|
| 25 |
+
from sympy.core.function import (Derivative, Function)
|
| 26 |
+
from sympy.core.numbers import oo
|
| 27 |
+
from sympy.core.power import Pow
|
| 28 |
+
from sympy.core.singleton import S
|
| 29 |
+
from sympy.core.symbol import (Symbol, symbols)
|
| 30 |
+
from sympy.matrices.dense import Matrix
|
| 31 |
+
from sympy.sets.sets import Interval
|
| 32 |
+
from sympy.testing.pytest import XFAIL
|
| 33 |
+
|
| 34 |
+
# Imports used in srepr strings
|
| 35 |
+
from sympy.physics.quantum.spin import JzOp
|
| 36 |
+
|
| 37 |
+
from sympy.printing import srepr
|
| 38 |
+
from sympy.printing.pretty import pretty as xpretty
|
| 39 |
+
from sympy.printing.latex import latex
|
| 40 |
+
|
| 41 |
+
MutableDenseMatrix = Matrix
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
ENV: dict[str, Any] = {}
|
| 45 |
+
exec('from sympy import *', ENV)
|
| 46 |
+
exec('from sympy.physics.quantum import *', ENV)
|
| 47 |
+
exec('from sympy.physics.quantum.cg import *', ENV)
|
| 48 |
+
exec('from sympy.physics.quantum.spin import *', ENV)
|
| 49 |
+
exec('from sympy.physics.quantum.hilbert import *', ENV)
|
| 50 |
+
exec('from sympy.physics.quantum.qubit import *', ENV)
|
| 51 |
+
exec('from sympy.physics.quantum.qexpr import *', ENV)
|
| 52 |
+
exec('from sympy.physics.quantum.gate import *', ENV)
|
| 53 |
+
exec('from sympy.physics.quantum.constants import *', ENV)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def sT(expr, string):
|
| 57 |
+
"""
|
| 58 |
+
sT := sreprTest
|
| 59 |
+
from sympy/printing/tests/test_repr.py
|
| 60 |
+
"""
|
| 61 |
+
assert srepr(expr) == string
|
| 62 |
+
assert eval(string, ENV) == expr
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def pretty(expr):
|
| 66 |
+
"""ASCII pretty-printing"""
|
| 67 |
+
return xpretty(expr, use_unicode=False, wrap_line=False)
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
def upretty(expr):
|
| 71 |
+
"""Unicode pretty-printing"""
|
| 72 |
+
return xpretty(expr, use_unicode=True, wrap_line=False)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def test_anticommutator():
|
| 76 |
+
A = Operator('A')
|
| 77 |
+
B = Operator('B')
|
| 78 |
+
ac = AntiCommutator(A, B)
|
| 79 |
+
ac_tall = AntiCommutator(A**2, B)
|
| 80 |
+
assert str(ac) == '{A,B}'
|
| 81 |
+
assert pretty(ac) == '{A,B}'
|
| 82 |
+
assert upretty(ac) == '{A,B}'
|
| 83 |
+
assert latex(ac) == r'\left\{A,B\right\}'
|
| 84 |
+
sT(ac, "AntiCommutator(Operator(Symbol('A')),Operator(Symbol('B')))")
|
| 85 |
+
assert str(ac_tall) == '{A**2,B}'
|
| 86 |
+
ascii_str = \
|
| 87 |
+
"""\
|
| 88 |
+
/ 2 \\\n\
|
| 89 |
+
<A ,B>\n\
|
| 90 |
+
\\ /\
|
| 91 |
+
"""
|
| 92 |
+
ucode_str = \
|
| 93 |
+
"""\
|
| 94 |
+
⎧ 2 ⎫\n\
|
| 95 |
+
⎨A ,B⎬\n\
|
| 96 |
+
⎩ ⎭\
|
| 97 |
+
"""
|
| 98 |
+
assert pretty(ac_tall) == ascii_str
|
| 99 |
+
assert upretty(ac_tall) == ucode_str
|
| 100 |
+
assert latex(ac_tall) == r'\left\{A^{2},B\right\}'
|
| 101 |
+
sT(ac_tall, "AntiCommutator(Pow(Operator(Symbol('A')), Integer(2)),Operator(Symbol('B')))")
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def test_cg():
|
| 105 |
+
cg = CG(1, 2, 3, 4, 5, 6)
|
| 106 |
+
wigner3j = Wigner3j(1, 2, 3, 4, 5, 6)
|
| 107 |
+
wigner6j = Wigner6j(1, 2, 3, 4, 5, 6)
|
| 108 |
+
wigner9j = Wigner9j(1, 2, 3, 4, 5, 6, 7, 8, 9)
|
| 109 |
+
assert str(cg) == 'CG(1, 2, 3, 4, 5, 6)'
|
| 110 |
+
ascii_str = \
|
| 111 |
+
"""\
|
| 112 |
+
5,6 \n\
|
| 113 |
+
C \n\
|
| 114 |
+
1,2,3,4\
|
| 115 |
+
"""
|
| 116 |
+
ucode_str = \
|
| 117 |
+
"""\
|
| 118 |
+
5,6 \n\
|
| 119 |
+
C \n\
|
| 120 |
+
1,2,3,4\
|
| 121 |
+
"""
|
| 122 |
+
assert pretty(cg) == ascii_str
|
| 123 |
+
assert upretty(cg) == ucode_str
|
| 124 |
+
assert latex(cg) == 'C^{5,6}_{1,2,3,4}'
|
| 125 |
+
assert latex(cg ** 2) == R'\left(C^{5,6}_{1,2,3,4}\right)^{2}'
|
| 126 |
+
sT(cg, "CG(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))")
|
| 127 |
+
assert str(wigner3j) == 'Wigner3j(1, 2, 3, 4, 5, 6)'
|
| 128 |
+
ascii_str = \
|
| 129 |
+
"""\
|
| 130 |
+
/1 3 5\\\n\
|
| 131 |
+
| |\n\
|
| 132 |
+
\\2 4 6/\
|
| 133 |
+
"""
|
| 134 |
+
ucode_str = \
|
| 135 |
+
"""\
|
| 136 |
+
⎛1 3 5⎞\n\
|
| 137 |
+
⎜ ⎟\n\
|
| 138 |
+
⎝2 4 6⎠\
|
| 139 |
+
"""
|
| 140 |
+
assert pretty(wigner3j) == ascii_str
|
| 141 |
+
assert upretty(wigner3j) == ucode_str
|
| 142 |
+
assert latex(wigner3j) == \
|
| 143 |
+
r'\left(\begin{array}{ccc} 1 & 3 & 5 \\ 2 & 4 & 6 \end{array}\right)'
|
| 144 |
+
sT(wigner3j, "Wigner3j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))")
|
| 145 |
+
assert str(wigner6j) == 'Wigner6j(1, 2, 3, 4, 5, 6)'
|
| 146 |
+
ascii_str = \
|
| 147 |
+
"""\
|
| 148 |
+
/1 2 3\\\n\
|
| 149 |
+
< >\n\
|
| 150 |
+
\\4 5 6/\
|
| 151 |
+
"""
|
| 152 |
+
ucode_str = \
|
| 153 |
+
"""\
|
| 154 |
+
⎧1 2 3⎫\n\
|
| 155 |
+
⎨ ⎬\n\
|
| 156 |
+
⎩4 5 6⎭\
|
| 157 |
+
"""
|
| 158 |
+
assert pretty(wigner6j) == ascii_str
|
| 159 |
+
assert upretty(wigner6j) == ucode_str
|
| 160 |
+
assert latex(wigner6j) == \
|
| 161 |
+
r'\left\{\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \end{array}\right\}'
|
| 162 |
+
sT(wigner6j, "Wigner6j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))")
|
| 163 |
+
assert str(wigner9j) == 'Wigner9j(1, 2, 3, 4, 5, 6, 7, 8, 9)'
|
| 164 |
+
ascii_str = \
|
| 165 |
+
"""\
|
| 166 |
+
/1 2 3\\\n\
|
| 167 |
+
| |\n\
|
| 168 |
+
<4 5 6>\n\
|
| 169 |
+
| |\n\
|
| 170 |
+
\\7 8 9/\
|
| 171 |
+
"""
|
| 172 |
+
ucode_str = \
|
| 173 |
+
"""\
|
| 174 |
+
⎧1 2 3⎫\n\
|
| 175 |
+
⎪ ⎪\n\
|
| 176 |
+
⎨4 5 6⎬\n\
|
| 177 |
+
⎪ ⎪\n\
|
| 178 |
+
⎩7 8 9⎭\
|
| 179 |
+
"""
|
| 180 |
+
assert pretty(wigner9j) == ascii_str
|
| 181 |
+
assert upretty(wigner9j) == ucode_str
|
| 182 |
+
assert latex(wigner9j) == \
|
| 183 |
+
r'\left\{\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{array}\right\}'
|
| 184 |
+
sT(wigner9j, "Wigner9j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6), Integer(7), Integer(8), Integer(9))")
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
def test_commutator():
|
| 188 |
+
A = Operator('A')
|
| 189 |
+
B = Operator('B')
|
| 190 |
+
c = Commutator(A, B)
|
| 191 |
+
c_tall = Commutator(A**2, B)
|
| 192 |
+
assert str(c) == '[A,B]'
|
| 193 |
+
assert pretty(c) == '[A,B]'
|
| 194 |
+
assert upretty(c) == '[A,B]'
|
| 195 |
+
assert latex(c) == r'\left[A,B\right]'
|
| 196 |
+
sT(c, "Commutator(Operator(Symbol('A')),Operator(Symbol('B')))")
|
| 197 |
+
assert str(c_tall) == '[A**2,B]'
|
| 198 |
+
ascii_str = \
|
| 199 |
+
"""\
|
| 200 |
+
[ 2 ]\n\
|
| 201 |
+
[A ,B]\
|
| 202 |
+
"""
|
| 203 |
+
ucode_str = \
|
| 204 |
+
"""\
|
| 205 |
+
⎡ 2 ⎤\n\
|
| 206 |
+
⎣A ,B⎦\
|
| 207 |
+
"""
|
| 208 |
+
assert pretty(c_tall) == ascii_str
|
| 209 |
+
assert upretty(c_tall) == ucode_str
|
| 210 |
+
assert latex(c_tall) == r'\left[A^{2},B\right]'
|
| 211 |
+
sT(c_tall, "Commutator(Pow(Operator(Symbol('A')), Integer(2)),Operator(Symbol('B')))")
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def test_constants():
|
| 215 |
+
assert str(hbar) == 'hbar'
|
| 216 |
+
assert pretty(hbar) == 'hbar'
|
| 217 |
+
assert upretty(hbar) == 'ℏ'
|
| 218 |
+
assert latex(hbar) == r'\hbar'
|
| 219 |
+
sT(hbar, "HBar()")
|
| 220 |
+
|
| 221 |
+
|
| 222 |
+
def test_dagger():
|
| 223 |
+
x = symbols('x')
|
| 224 |
+
expr = Dagger(x)
|
| 225 |
+
assert str(expr) == 'Dagger(x)'
|
| 226 |
+
ascii_str = \
|
| 227 |
+
"""\
|
| 228 |
+
+\n\
|
| 229 |
+
x \
|
| 230 |
+
"""
|
| 231 |
+
ucode_str = \
|
| 232 |
+
"""\
|
| 233 |
+
†\n\
|
| 234 |
+
x \
|
| 235 |
+
"""
|
| 236 |
+
assert pretty(expr) == ascii_str
|
| 237 |
+
assert upretty(expr) == ucode_str
|
| 238 |
+
assert latex(expr) == r'x^{\dagger}'
|
| 239 |
+
sT(expr, "Dagger(Symbol('x'))")
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
@XFAIL
|
| 243 |
+
def test_gate_failing():
|
| 244 |
+
a, b, c, d = symbols('a,b,c,d')
|
| 245 |
+
uMat = Matrix([[a, b], [c, d]])
|
| 246 |
+
g = UGate((0,), uMat)
|
| 247 |
+
assert str(g) == 'U(0)'
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
def test_gate():
|
| 251 |
+
a, b, c, d = symbols('a,b,c,d')
|
| 252 |
+
uMat = Matrix([[a, b], [c, d]])
|
| 253 |
+
q = Qubit(1, 0, 1, 0, 1)
|
| 254 |
+
g1 = IdentityGate(2)
|
| 255 |
+
g2 = CGate((3, 0), XGate(1))
|
| 256 |
+
g3 = CNotGate(1, 0)
|
| 257 |
+
g4 = UGate((0,), uMat)
|
| 258 |
+
assert str(g1) == '1(2)'
|
| 259 |
+
assert pretty(g1) == '1 \n 2'
|
| 260 |
+
assert upretty(g1) == '1 \n 2'
|
| 261 |
+
assert latex(g1) == r'1_{2}'
|
| 262 |
+
sT(g1, "IdentityGate(Integer(2))")
|
| 263 |
+
assert str(g1*q) == '1(2)*|10101>'
|
| 264 |
+
ascii_str = \
|
| 265 |
+
"""\
|
| 266 |
+
1 *|10101>\n\
|
| 267 |
+
2 \
|
| 268 |
+
"""
|
| 269 |
+
ucode_str = \
|
| 270 |
+
"""\
|
| 271 |
+
1 ⋅❘10101⟩\n\
|
| 272 |
+
2 \
|
| 273 |
+
"""
|
| 274 |
+
assert pretty(g1*q) == ascii_str
|
| 275 |
+
assert upretty(g1*q) == ucode_str
|
| 276 |
+
assert latex(g1*q) == r'1_{2} {\left|10101\right\rangle }'
|
| 277 |
+
sT(g1*q, "Mul(IdentityGate(Integer(2)), Qubit(Integer(1),Integer(0),Integer(1),Integer(0),Integer(1)))")
|
| 278 |
+
assert str(g2) == 'C((3,0),X(1))'
|
| 279 |
+
ascii_str = \
|
| 280 |
+
"""\
|
| 281 |
+
C /X \\\n\
|
| 282 |
+
3,0\\ 1/\
|
| 283 |
+
"""
|
| 284 |
+
ucode_str = \
|
| 285 |
+
"""\
|
| 286 |
+
C ⎛X ⎞\n\
|
| 287 |
+
3,0⎝ 1⎠\
|
| 288 |
+
"""
|
| 289 |
+
assert pretty(g2) == ascii_str
|
| 290 |
+
assert upretty(g2) == ucode_str
|
| 291 |
+
assert latex(g2) == r'C_{3,0}{\left(X_{1}\right)}'
|
| 292 |
+
sT(g2, "CGate(Tuple(Integer(3), Integer(0)),XGate(Integer(1)))")
|
| 293 |
+
assert str(g3) == 'CNOT(1,0)'
|
| 294 |
+
ascii_str = \
|
| 295 |
+
"""\
|
| 296 |
+
CNOT \n\
|
| 297 |
+
1,0\
|
| 298 |
+
"""
|
| 299 |
+
ucode_str = \
|
| 300 |
+
"""\
|
| 301 |
+
CNOT \n\
|
| 302 |
+
1,0\
|
| 303 |
+
"""
|
| 304 |
+
assert pretty(g3) == ascii_str
|
| 305 |
+
assert upretty(g3) == ucode_str
|
| 306 |
+
assert latex(g3) == r'\text{CNOT}_{1,0}'
|
| 307 |
+
sT(g3, "CNotGate(Integer(1),Integer(0))")
|
| 308 |
+
ascii_str = \
|
| 309 |
+
"""\
|
| 310 |
+
U \n\
|
| 311 |
+
0\
|
| 312 |
+
"""
|
| 313 |
+
ucode_str = \
|
| 314 |
+
"""\
|
| 315 |
+
U \n\
|
| 316 |
+
0\
|
| 317 |
+
"""
|
| 318 |
+
assert str(g4) == \
|
| 319 |
+
"""\
|
| 320 |
+
U((0,),Matrix([\n\
|
| 321 |
+
[a, b],\n\
|
| 322 |
+
[c, d]]))\
|
| 323 |
+
"""
|
| 324 |
+
assert pretty(g4) == ascii_str
|
| 325 |
+
assert upretty(g4) == ucode_str
|
| 326 |
+
assert latex(g4) == r'U_{0}'
|
| 327 |
+
sT(g4, "UGate(Tuple(Integer(0)),ImmutableDenseMatrix([[Symbol('a'), Symbol('b')], [Symbol('c'), Symbol('d')]]))")
|
| 328 |
+
|
| 329 |
+
|
| 330 |
+
def test_hilbert():
|
| 331 |
+
h1 = HilbertSpace()
|
| 332 |
+
h2 = ComplexSpace(2)
|
| 333 |
+
h3 = FockSpace()
|
| 334 |
+
h4 = L2(Interval(0, oo))
|
| 335 |
+
assert str(h1) == 'H'
|
| 336 |
+
assert pretty(h1) == 'H'
|
| 337 |
+
assert upretty(h1) == 'H'
|
| 338 |
+
assert latex(h1) == r'\mathcal{H}'
|
| 339 |
+
sT(h1, "HilbertSpace()")
|
| 340 |
+
assert str(h2) == 'C(2)'
|
| 341 |
+
ascii_str = \
|
| 342 |
+
"""\
|
| 343 |
+
2\n\
|
| 344 |
+
C \
|
| 345 |
+
"""
|
| 346 |
+
ucode_str = \
|
| 347 |
+
"""\
|
| 348 |
+
2\n\
|
| 349 |
+
C \
|
| 350 |
+
"""
|
| 351 |
+
assert pretty(h2) == ascii_str
|
| 352 |
+
assert upretty(h2) == ucode_str
|
| 353 |
+
assert latex(h2) == r'\mathcal{C}^{2}'
|
| 354 |
+
sT(h2, "ComplexSpace(Integer(2))")
|
| 355 |
+
assert str(h3) == 'F'
|
| 356 |
+
assert pretty(h3) == 'F'
|
| 357 |
+
assert upretty(h3) == 'F'
|
| 358 |
+
assert latex(h3) == r'\mathcal{F}'
|
| 359 |
+
sT(h3, "FockSpace()")
|
| 360 |
+
assert str(h4) == 'L2(Interval(0, oo))'
|
| 361 |
+
ascii_str = \
|
| 362 |
+
"""\
|
| 363 |
+
2\n\
|
| 364 |
+
L \
|
| 365 |
+
"""
|
| 366 |
+
ucode_str = \
|
| 367 |
+
"""\
|
| 368 |
+
2\n\
|
| 369 |
+
L \
|
| 370 |
+
"""
|
| 371 |
+
assert pretty(h4) == ascii_str
|
| 372 |
+
assert upretty(h4) == ucode_str
|
| 373 |
+
assert latex(h4) == r'{\mathcal{L}^2}\left( \left[0, \infty\right) \right)'
|
| 374 |
+
sT(h4, "L2(Interval(Integer(0), oo, false, true))")
|
| 375 |
+
assert str(h1 + h2) == 'H+C(2)'
|
| 376 |
+
ascii_str = \
|
| 377 |
+
"""\
|
| 378 |
+
2\n\
|
| 379 |
+
H + C \
|
| 380 |
+
"""
|
| 381 |
+
ucode_str = \
|
| 382 |
+
"""\
|
| 383 |
+
2\n\
|
| 384 |
+
H ⊕ C \
|
| 385 |
+
"""
|
| 386 |
+
assert pretty(h1 + h2) == ascii_str
|
| 387 |
+
assert upretty(h1 + h2) == ucode_str
|
| 388 |
+
assert latex(h1 + h2)
|
| 389 |
+
sT(h1 + h2, "DirectSumHilbertSpace(HilbertSpace(),ComplexSpace(Integer(2)))")
|
| 390 |
+
assert str(h1*h2) == "H*C(2)"
|
| 391 |
+
ascii_str = \
|
| 392 |
+
"""\
|
| 393 |
+
2\n\
|
| 394 |
+
H x C \
|
| 395 |
+
"""
|
| 396 |
+
ucode_str = \
|
| 397 |
+
"""\
|
| 398 |
+
2\n\
|
| 399 |
+
H ⨂ C \
|
| 400 |
+
"""
|
| 401 |
+
assert pretty(h1*h2) == ascii_str
|
| 402 |
+
assert upretty(h1*h2) == ucode_str
|
| 403 |
+
assert latex(h1*h2)
|
| 404 |
+
sT(h1*h2,
|
| 405 |
+
"TensorProductHilbertSpace(HilbertSpace(),ComplexSpace(Integer(2)))")
|
| 406 |
+
assert str(h1**2) == 'H**2'
|
| 407 |
+
ascii_str = \
|
| 408 |
+
"""\
|
| 409 |
+
x2\n\
|
| 410 |
+
H \
|
| 411 |
+
"""
|
| 412 |
+
ucode_str = \
|
| 413 |
+
"""\
|
| 414 |
+
⨂2\n\
|
| 415 |
+
H \
|
| 416 |
+
"""
|
| 417 |
+
assert pretty(h1**2) == ascii_str
|
| 418 |
+
assert upretty(h1**2) == ucode_str
|
| 419 |
+
assert latex(h1**2) == r'{\mathcal{H}}^{\otimes 2}'
|
| 420 |
+
sT(h1**2, "TensorPowerHilbertSpace(HilbertSpace(),Integer(2))")
|
| 421 |
+
|
| 422 |
+
|
| 423 |
+
def test_innerproduct():
|
| 424 |
+
x = symbols('x')
|
| 425 |
+
ip1 = InnerProduct(Bra(), Ket())
|
| 426 |
+
ip2 = InnerProduct(TimeDepBra(), TimeDepKet())
|
| 427 |
+
ip3 = InnerProduct(JzBra(1, 1), JzKet(1, 1))
|
| 428 |
+
ip4 = InnerProduct(JzBraCoupled(1, 1, (1, 1)), JzKetCoupled(1, 1, (1, 1)))
|
| 429 |
+
ip_tall1 = InnerProduct(Bra(x/2), Ket(x/2))
|
| 430 |
+
ip_tall2 = InnerProduct(Bra(x), Ket(x/2))
|
| 431 |
+
ip_tall3 = InnerProduct(Bra(x/2), Ket(x))
|
| 432 |
+
assert str(ip1) == '<psi|psi>'
|
| 433 |
+
assert pretty(ip1) == '<psi|psi>'
|
| 434 |
+
assert upretty(ip1) == '⟨ψ❘ψ⟩'
|
| 435 |
+
assert latex(
|
| 436 |
+
ip1) == r'\left\langle \psi \right. {\left|\psi\right\rangle }'
|
| 437 |
+
sT(ip1, "InnerProduct(Bra(Symbol('psi')),Ket(Symbol('psi')))")
|
| 438 |
+
assert str(ip2) == '<psi;t|psi;t>'
|
| 439 |
+
assert pretty(ip2) == '<psi;t|psi;t>'
|
| 440 |
+
assert upretty(ip2) == '⟨ψ;t❘ψ;t⟩'
|
| 441 |
+
assert latex(ip2) == \
|
| 442 |
+
r'\left\langle \psi;t \right. {\left|\psi;t\right\rangle }'
|
| 443 |
+
sT(ip2, "InnerProduct(TimeDepBra(Symbol('psi'),Symbol('t')),TimeDepKet(Symbol('psi'),Symbol('t')))")
|
| 444 |
+
assert str(ip3) == "<1,1|1,1>"
|
| 445 |
+
assert pretty(ip3) == '<1,1|1,1>'
|
| 446 |
+
assert upretty(ip3) == '⟨1,1❘1,1⟩'
|
| 447 |
+
assert latex(ip3) == r'\left\langle 1,1 \right. {\left|1,1\right\rangle }'
|
| 448 |
+
sT(ip3, "InnerProduct(JzBra(Integer(1),Integer(1)),JzKet(Integer(1),Integer(1)))")
|
| 449 |
+
assert str(ip4) == "<1,1,j1=1,j2=1|1,1,j1=1,j2=1>"
|
| 450 |
+
assert pretty(ip4) == '<1,1,j1=1,j2=1|1,1,j1=1,j2=1>'
|
| 451 |
+
assert upretty(ip4) == '⟨1,1,j₁=1,j₂=1❘1,1,j₁=1,j₂=1⟩'
|
| 452 |
+
assert latex(ip4) == \
|
| 453 |
+
r'\left\langle 1,1,j_{1}=1,j_{2}=1 \right. {\left|1,1,j_{1}=1,j_{2}=1\right\rangle }'
|
| 454 |
+
sT(ip4, "InnerProduct(JzBraCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))),JzKetCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))))")
|
| 455 |
+
assert str(ip_tall1) == '<x/2|x/2>'
|
| 456 |
+
ascii_str = \
|
| 457 |
+
"""\
|
| 458 |
+
/ | \\ \n\
|
| 459 |
+
/ x|x \\\n\
|
| 460 |
+
\\ -|- /\n\
|
| 461 |
+
\\2|2/ \
|
| 462 |
+
"""
|
| 463 |
+
ucode_str = \
|
| 464 |
+
"""\
|
| 465 |
+
╱ │ ╲ \n\
|
| 466 |
+
╱ x│x ╲\n\
|
| 467 |
+
╲ ─│─ ╱\n\
|
| 468 |
+
╲2│2╱ \
|
| 469 |
+
"""
|
| 470 |
+
assert pretty(ip_tall1) == ascii_str
|
| 471 |
+
assert upretty(ip_tall1) == ucode_str
|
| 472 |
+
assert latex(ip_tall1) == \
|
| 473 |
+
r'\left\langle \frac{x}{2} \right. {\left|\frac{x}{2}\right\rangle }'
|
| 474 |
+
sT(ip_tall1, "InnerProduct(Bra(Mul(Rational(1, 2), Symbol('x'))),Ket(Mul(Rational(1, 2), Symbol('x'))))")
|
| 475 |
+
assert str(ip_tall2) == '<x|x/2>'
|
| 476 |
+
ascii_str = \
|
| 477 |
+
"""\
|
| 478 |
+
/ | \\ \n\
|
| 479 |
+
/ |x \\\n\
|
| 480 |
+
\\ x|- /\n\
|
| 481 |
+
\\ |2/ \
|
| 482 |
+
"""
|
| 483 |
+
ucode_str = \
|
| 484 |
+
"""\
|
| 485 |
+
╱ │ ╲ \n\
|
| 486 |
+
╱ │x ╲\n\
|
| 487 |
+
╲ x│─ ╱\n\
|
| 488 |
+
╲ │2╱ \
|
| 489 |
+
"""
|
| 490 |
+
assert pretty(ip_tall2) == ascii_str
|
| 491 |
+
assert upretty(ip_tall2) == ucode_str
|
| 492 |
+
assert latex(ip_tall2) == \
|
| 493 |
+
r'\left\langle x \right. {\left|\frac{x}{2}\right\rangle }'
|
| 494 |
+
sT(ip_tall2,
|
| 495 |
+
"InnerProduct(Bra(Symbol('x')),Ket(Mul(Rational(1, 2), Symbol('x'))))")
|
| 496 |
+
assert str(ip_tall3) == '<x/2|x>'
|
| 497 |
+
ascii_str = \
|
| 498 |
+
"""\
|
| 499 |
+
/ | \\ \n\
|
| 500 |
+
/ x| \\\n\
|
| 501 |
+
\\ -|x /\n\
|
| 502 |
+
\\2| / \
|
| 503 |
+
"""
|
| 504 |
+
ucode_str = \
|
| 505 |
+
"""\
|
| 506 |
+
╱ │ ╲ \n\
|
| 507 |
+
╱ x│ ╲\n\
|
| 508 |
+
╲ ─│x ╱\n\
|
| 509 |
+
╲2│ ╱ \
|
| 510 |
+
"""
|
| 511 |
+
assert pretty(ip_tall3) == ascii_str
|
| 512 |
+
assert upretty(ip_tall3) == ucode_str
|
| 513 |
+
assert latex(ip_tall3) == \
|
| 514 |
+
r'\left\langle \frac{x}{2} \right. {\left|x\right\rangle }'
|
| 515 |
+
sT(ip_tall3,
|
| 516 |
+
"InnerProduct(Bra(Mul(Rational(1, 2), Symbol('x'))),Ket(Symbol('x')))")
|
| 517 |
+
|
| 518 |
+
|
| 519 |
+
def test_operator():
|
| 520 |
+
a = Operator('A')
|
| 521 |
+
b = Operator('B', Symbol('t'), S.Half)
|
| 522 |
+
inv = a.inv()
|
| 523 |
+
f = Function('f')
|
| 524 |
+
x = symbols('x')
|
| 525 |
+
d = DifferentialOperator(Derivative(f(x), x), f(x))
|
| 526 |
+
op = OuterProduct(Ket(), Bra())
|
| 527 |
+
assert str(a) == 'A'
|
| 528 |
+
assert pretty(a) == 'A'
|
| 529 |
+
assert upretty(a) == 'A'
|
| 530 |
+
assert latex(a) == 'A'
|
| 531 |
+
sT(a, "Operator(Symbol('A'))")
|
| 532 |
+
assert str(inv) == 'A**(-1)'
|
| 533 |
+
ascii_str = \
|
| 534 |
+
"""\
|
| 535 |
+
-1\n\
|
| 536 |
+
A \
|
| 537 |
+
"""
|
| 538 |
+
ucode_str = \
|
| 539 |
+
"""\
|
| 540 |
+
-1\n\
|
| 541 |
+
A \
|
| 542 |
+
"""
|
| 543 |
+
assert pretty(inv) == ascii_str
|
| 544 |
+
assert upretty(inv) == ucode_str
|
| 545 |
+
assert latex(inv) == r'A^{-1}'
|
| 546 |
+
sT(inv, "Pow(Operator(Symbol('A')), Integer(-1))")
|
| 547 |
+
assert str(d) == 'DifferentialOperator(Derivative(f(x), x),f(x))'
|
| 548 |
+
ascii_str = \
|
| 549 |
+
"""\
|
| 550 |
+
/d \\\n\
|
| 551 |
+
DifferentialOperator|--(f(x)),f(x)|\n\
|
| 552 |
+
\\dx /\
|
| 553 |
+
"""
|
| 554 |
+
ucode_str = \
|
| 555 |
+
"""\
|
| 556 |
+
⎛d ⎞\n\
|
| 557 |
+
DifferentialOperator⎜──(f(x)),f(x)⎟\n\
|
| 558 |
+
⎝dx ⎠\
|
| 559 |
+
"""
|
| 560 |
+
assert pretty(d) == ascii_str
|
| 561 |
+
assert upretty(d) == ucode_str
|
| 562 |
+
assert latex(d) == \
|
| 563 |
+
r'DifferentialOperator\left(\frac{d}{d x} f{\left(x \right)},f{\left(x \right)}\right)'
|
| 564 |
+
sT(d, "DifferentialOperator(Derivative(Function('f')(Symbol('x')), Tuple(Symbol('x'), Integer(1))),Function('f')(Symbol('x')))")
|
| 565 |
+
assert str(b) == 'Operator(B,t,1/2)'
|
| 566 |
+
assert pretty(b) == 'Operator(B,t,1/2)'
|
| 567 |
+
assert upretty(b) == 'Operator(B,t,1/2)'
|
| 568 |
+
assert latex(b) == r'Operator\left(B,t,\frac{1}{2}\right)'
|
| 569 |
+
sT(b, "Operator(Symbol('B'),Symbol('t'),Rational(1, 2))")
|
| 570 |
+
assert str(op) == '|psi><psi|'
|
| 571 |
+
assert pretty(op) == '|psi><psi|'
|
| 572 |
+
assert upretty(op) == '❘ψ⟩⟨ψ❘'
|
| 573 |
+
assert latex(op) == r'{\left|\psi\right\rangle }{\left\langle \psi\right|}'
|
| 574 |
+
sT(op, "OuterProduct(Ket(Symbol('psi')),Bra(Symbol('psi')))")
|
| 575 |
+
|
| 576 |
+
|
| 577 |
+
def test_qexpr():
|
| 578 |
+
q = QExpr('q')
|
| 579 |
+
assert str(q) == 'q'
|
| 580 |
+
assert pretty(q) == 'q'
|
| 581 |
+
assert upretty(q) == 'q'
|
| 582 |
+
assert latex(q) == r'q'
|
| 583 |
+
sT(q, "QExpr(Symbol('q'))")
|
| 584 |
+
|
| 585 |
+
|
| 586 |
+
def test_qubit():
|
| 587 |
+
q1 = Qubit('0101')
|
| 588 |
+
q2 = IntQubit(8)
|
| 589 |
+
assert str(q1) == '|0101>'
|
| 590 |
+
assert pretty(q1) == '|0101>'
|
| 591 |
+
assert upretty(q1) == '❘0101⟩'
|
| 592 |
+
assert latex(q1) == r'{\left|0101\right\rangle }'
|
| 593 |
+
sT(q1, "Qubit(Integer(0),Integer(1),Integer(0),Integer(1))")
|
| 594 |
+
assert str(q2) == '|8>'
|
| 595 |
+
assert pretty(q2) == '|8>'
|
| 596 |
+
assert upretty(q2) == '❘8⟩'
|
| 597 |
+
assert latex(q2) == r'{\left|8\right\rangle }'
|
| 598 |
+
sT(q2, "IntQubit(8)")
|
| 599 |
+
|
| 600 |
+
|
| 601 |
+
def test_spin():
|
| 602 |
+
lz = JzOp('L')
|
| 603 |
+
ket = JzKet(1, 0)
|
| 604 |
+
bra = JzBra(1, 0)
|
| 605 |
+
cket = JzKetCoupled(1, 0, (1, 2))
|
| 606 |
+
cbra = JzBraCoupled(1, 0, (1, 2))
|
| 607 |
+
cket_big = JzKetCoupled(1, 0, (1, 2, 3))
|
| 608 |
+
cbra_big = JzBraCoupled(1, 0, (1, 2, 3))
|
| 609 |
+
rot = Rotation(1, 2, 3)
|
| 610 |
+
bigd = WignerD(1, 2, 3, 4, 5, 6)
|
| 611 |
+
smalld = WignerD(1, 2, 3, 0, 4, 0)
|
| 612 |
+
assert str(lz) == 'Lz'
|
| 613 |
+
ascii_str = \
|
| 614 |
+
"""\
|
| 615 |
+
L \n\
|
| 616 |
+
z\
|
| 617 |
+
"""
|
| 618 |
+
ucode_str = \
|
| 619 |
+
"""\
|
| 620 |
+
L \n\
|
| 621 |
+
z\
|
| 622 |
+
"""
|
| 623 |
+
assert pretty(lz) == ascii_str
|
| 624 |
+
assert upretty(lz) == ucode_str
|
| 625 |
+
assert latex(lz) == 'L_z'
|
| 626 |
+
sT(lz, "JzOp(Symbol('L'))")
|
| 627 |
+
assert str(J2) == 'J2'
|
| 628 |
+
ascii_str = \
|
| 629 |
+
"""\
|
| 630 |
+
2\n\
|
| 631 |
+
J \
|
| 632 |
+
"""
|
| 633 |
+
ucode_str = \
|
| 634 |
+
"""\
|
| 635 |
+
2\n\
|
| 636 |
+
J \
|
| 637 |
+
"""
|
| 638 |
+
assert pretty(J2) == ascii_str
|
| 639 |
+
assert upretty(J2) == ucode_str
|
| 640 |
+
assert latex(J2) == r'J^2'
|
| 641 |
+
sT(J2, "J2Op(Symbol('J'))")
|
| 642 |
+
assert str(Jz) == 'Jz'
|
| 643 |
+
ascii_str = \
|
| 644 |
+
"""\
|
| 645 |
+
J \n\
|
| 646 |
+
z\
|
| 647 |
+
"""
|
| 648 |
+
ucode_str = \
|
| 649 |
+
"""\
|
| 650 |
+
J \n\
|
| 651 |
+
z\
|
| 652 |
+
"""
|
| 653 |
+
assert pretty(Jz) == ascii_str
|
| 654 |
+
assert upretty(Jz) == ucode_str
|
| 655 |
+
assert latex(Jz) == 'J_z'
|
| 656 |
+
sT(Jz, "JzOp(Symbol('J'))")
|
| 657 |
+
assert str(ket) == '|1,0>'
|
| 658 |
+
assert pretty(ket) == '|1,0>'
|
| 659 |
+
assert upretty(ket) == '❘1,0⟩'
|
| 660 |
+
assert latex(ket) == r'{\left|1,0\right\rangle }'
|
| 661 |
+
sT(ket, "JzKet(Integer(1),Integer(0))")
|
| 662 |
+
assert str(bra) == '<1,0|'
|
| 663 |
+
assert pretty(bra) == '<1,0|'
|
| 664 |
+
assert upretty(bra) == '⟨1,0❘'
|
| 665 |
+
assert latex(bra) == r'{\left\langle 1,0\right|}'
|
| 666 |
+
sT(bra, "JzBra(Integer(1),Integer(0))")
|
| 667 |
+
assert str(cket) == '|1,0,j1=1,j2=2>'
|
| 668 |
+
assert pretty(cket) == '|1,0,j1=1,j2=2>'
|
| 669 |
+
assert upretty(cket) == '❘1,0,j₁=1,j₂=2⟩'
|
| 670 |
+
assert latex(cket) == r'{\left|1,0,j_{1}=1,j_{2}=2\right\rangle }'
|
| 671 |
+
sT(cket, "JzKetCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(2)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))")
|
| 672 |
+
assert str(cbra) == '<1,0,j1=1,j2=2|'
|
| 673 |
+
assert pretty(cbra) == '<1,0,j1=1,j2=2|'
|
| 674 |
+
assert upretty(cbra) == '⟨1,0,j₁=1,j₂=2❘'
|
| 675 |
+
assert latex(cbra) == r'{\left\langle 1,0,j_{1}=1,j_{2}=2\right|}'
|
| 676 |
+
sT(cbra, "JzBraCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(2)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))")
|
| 677 |
+
assert str(cket_big) == '|1,0,j1=1,j2=2,j3=3,j(1,2)=3>'
|
| 678 |
+
# TODO: Fix non-unicode pretty printing
|
| 679 |
+
# i.e. j1,2 -> j(1,2)
|
| 680 |
+
assert pretty(cket_big) == '|1,0,j1=1,j2=2,j3=3,j1,2=3>'
|
| 681 |
+
assert upretty(cket_big) == '❘1,0,j₁=1,j₂=2,j₃=3,j₁,₂=3⟩'
|
| 682 |
+
assert latex(cket_big) == \
|
| 683 |
+
r'{\left|1,0,j_{1}=1,j_{2}=2,j_{3}=3,j_{1,2}=3\right\rangle }'
|
| 684 |
+
sT(cket_big, "JzKetCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(2), Integer(3)),Tuple(Tuple(Integer(1), Integer(2), Integer(3)), Tuple(Integer(1), Integer(3), Integer(1))))")
|
| 685 |
+
assert str(cbra_big) == '<1,0,j1=1,j2=2,j3=3,j(1,2)=3|'
|
| 686 |
+
assert pretty(cbra_big) == '<1,0,j1=1,j2=2,j3=3,j1,2=3|'
|
| 687 |
+
assert upretty(cbra_big) == '⟨1,0,j₁=1,j₂=2,j₃=3,j₁,₂=3❘'
|
| 688 |
+
assert latex(cbra_big) == \
|
| 689 |
+
r'{\left\langle 1,0,j_{1}=1,j_{2}=2,j_{3}=3,j_{1,2}=3\right|}'
|
| 690 |
+
sT(cbra_big, "JzBraCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(2), Integer(3)),Tuple(Tuple(Integer(1), Integer(2), Integer(3)), Tuple(Integer(1), Integer(3), Integer(1))))")
|
| 691 |
+
assert str(rot) == 'R(1,2,3)'
|
| 692 |
+
assert pretty(rot) == 'R (1,2,3)'
|
| 693 |
+
assert upretty(rot) == 'ℛ (1,2,3)'
|
| 694 |
+
assert latex(rot) == r'\mathcal{R}\left(1,2,3\right)'
|
| 695 |
+
sT(rot, "Rotation(Integer(1),Integer(2),Integer(3))")
|
| 696 |
+
assert str(bigd) == 'WignerD(1, 2, 3, 4, 5, 6)'
|
| 697 |
+
ascii_str = \
|
| 698 |
+
"""\
|
| 699 |
+
1 \n\
|
| 700 |
+
D (4,5,6)\n\
|
| 701 |
+
2,3 \
|
| 702 |
+
"""
|
| 703 |
+
ucode_str = \
|
| 704 |
+
"""\
|
| 705 |
+
1 \n\
|
| 706 |
+
D (4,5,6)\n\
|
| 707 |
+
2,3 \
|
| 708 |
+
"""
|
| 709 |
+
assert pretty(bigd) == ascii_str
|
| 710 |
+
assert upretty(bigd) == ucode_str
|
| 711 |
+
assert latex(bigd) == r'D^{1}_{2,3}\left(4,5,6\right)'
|
| 712 |
+
sT(bigd, "WignerD(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6))")
|
| 713 |
+
assert str(smalld) == 'WignerD(1, 2, 3, 0, 4, 0)'
|
| 714 |
+
ascii_str = \
|
| 715 |
+
"""\
|
| 716 |
+
1 \n\
|
| 717 |
+
d (4)\n\
|
| 718 |
+
2,3 \
|
| 719 |
+
"""
|
| 720 |
+
ucode_str = \
|
| 721 |
+
"""\
|
| 722 |
+
1 \n\
|
| 723 |
+
d (4)\n\
|
| 724 |
+
2,3 \
|
| 725 |
+
"""
|
| 726 |
+
assert pretty(smalld) == ascii_str
|
| 727 |
+
assert upretty(smalld) == ucode_str
|
| 728 |
+
assert latex(smalld) == r'd^{1}_{2,3}\left(4\right)'
|
| 729 |
+
sT(smalld, "WignerD(Integer(1), Integer(2), Integer(3), Integer(0), Integer(4), Integer(0))")
|
| 730 |
+
|
| 731 |
+
|
| 732 |
+
def test_state():
|
| 733 |
+
x = symbols('x')
|
| 734 |
+
bra = Bra()
|
| 735 |
+
ket = Ket()
|
| 736 |
+
bra_tall = Bra(x/2)
|
| 737 |
+
ket_tall = Ket(x/2)
|
| 738 |
+
tbra = TimeDepBra()
|
| 739 |
+
tket = TimeDepKet()
|
| 740 |
+
assert str(bra) == '<psi|'
|
| 741 |
+
assert pretty(bra) == '<psi|'
|
| 742 |
+
assert upretty(bra) == '⟨ψ❘'
|
| 743 |
+
assert latex(bra) == r'{\left\langle \psi\right|}'
|
| 744 |
+
sT(bra, "Bra(Symbol('psi'))")
|
| 745 |
+
assert str(ket) == '|psi>'
|
| 746 |
+
assert pretty(ket) == '|psi>'
|
| 747 |
+
assert upretty(ket) == '❘ψ⟩'
|
| 748 |
+
assert latex(ket) == r'{\left|\psi\right\rangle }'
|
| 749 |
+
sT(ket, "Ket(Symbol('psi'))")
|
| 750 |
+
assert str(bra_tall) == '<x/2|'
|
| 751 |
+
ascii_str = \
|
| 752 |
+
"""\
|
| 753 |
+
/ |\n\
|
| 754 |
+
/ x|\n\
|
| 755 |
+
\\ -|\n\
|
| 756 |
+
\\2|\
|
| 757 |
+
"""
|
| 758 |
+
ucode_str = \
|
| 759 |
+
"""\
|
| 760 |
+
╱ │\n\
|
| 761 |
+
╱ x│\n\
|
| 762 |
+
╲ ─│\n\
|
| 763 |
+
╲2│\
|
| 764 |
+
"""
|
| 765 |
+
assert pretty(bra_tall) == ascii_str
|
| 766 |
+
assert upretty(bra_tall) == ucode_str
|
| 767 |
+
assert latex(bra_tall) == r'{\left\langle \frac{x}{2}\right|}'
|
| 768 |
+
sT(bra_tall, "Bra(Mul(Rational(1, 2), Symbol('x')))")
|
| 769 |
+
assert str(ket_tall) == '|x/2>'
|
| 770 |
+
ascii_str = \
|
| 771 |
+
"""\
|
| 772 |
+
| \\ \n\
|
| 773 |
+
|x \\\n\
|
| 774 |
+
|- /\n\
|
| 775 |
+
|2/ \
|
| 776 |
+
"""
|
| 777 |
+
ucode_str = \
|
| 778 |
+
"""\
|
| 779 |
+
│ ╲ \n\
|
| 780 |
+
│x ╲\n\
|
| 781 |
+
│─ ╱\n\
|
| 782 |
+
│2╱ \
|
| 783 |
+
"""
|
| 784 |
+
assert pretty(ket_tall) == ascii_str
|
| 785 |
+
assert upretty(ket_tall) == ucode_str
|
| 786 |
+
assert latex(ket_tall) == r'{\left|\frac{x}{2}\right\rangle }'
|
| 787 |
+
sT(ket_tall, "Ket(Mul(Rational(1, 2), Symbol('x')))")
|
| 788 |
+
assert str(tbra) == '<psi;t|'
|
| 789 |
+
assert pretty(tbra) == '<psi;t|'
|
| 790 |
+
assert upretty(tbra) == '⟨ψ;t❘'
|
| 791 |
+
assert latex(tbra) == r'{\left\langle \psi;t\right|}'
|
| 792 |
+
sT(tbra, "TimeDepBra(Symbol('psi'),Symbol('t'))")
|
| 793 |
+
assert str(tket) == '|psi;t>'
|
| 794 |
+
assert pretty(tket) == '|psi;t>'
|
| 795 |
+
assert upretty(tket) == '❘ψ;t⟩'
|
| 796 |
+
assert latex(tket) == r'{\left|\psi;t\right\rangle }'
|
| 797 |
+
sT(tket, "TimeDepKet(Symbol('psi'),Symbol('t'))")
|
| 798 |
+
|
| 799 |
+
|
| 800 |
+
def test_tensorproduct():
|
| 801 |
+
tp = TensorProduct(JzKet(1, 1), JzKet(1, 0))
|
| 802 |
+
assert str(tp) == '|1,1>x|1,0>'
|
| 803 |
+
assert pretty(tp) == '|1,1>x |1,0>'
|
| 804 |
+
assert upretty(tp) == '❘1,1⟩⨂ ❘1,0⟩'
|
| 805 |
+
assert latex(tp) == \
|
| 806 |
+
r'{{\left|1,1\right\rangle }}\otimes {{\left|1,0\right\rangle }}'
|
| 807 |
+
sT(tp, "TensorProduct(JzKet(Integer(1),Integer(1)), JzKet(Integer(1),Integer(0)))")
|
| 808 |
+
|
| 809 |
+
|
| 810 |
+
def test_big_expr():
|
| 811 |
+
f = Function('f')
|
| 812 |
+
x = symbols('x')
|
| 813 |
+
e1 = Dagger(AntiCommutator(Operator('A') + Operator('B'), Pow(DifferentialOperator(Derivative(f(x), x), f(x)), 3))*TensorProduct(Jz**2, Operator('A') + Operator('B')))*(JzBra(1, 0) + JzBra(1, 1))*(JzKet(0, 0) + JzKet(1, -1))
|
| 814 |
+
e2 = Commutator(Jz**2, Operator('A') + Operator('B'))*AntiCommutator(Dagger(Operator('C')*Operator('D')), Operator('E').inv()**2)*Dagger(Commutator(Jz, J2))
|
| 815 |
+
e3 = Wigner3j(1, 2, 3, 4, 5, 6)*TensorProduct(Commutator(Operator('A') + Dagger(Operator('B')), Operator('C') + Operator('D')), Jz - J2)*Dagger(OuterProduct(Dagger(JzBra(1, 1)), JzBra(1, 0)))*TensorProduct(JzKetCoupled(1, 1, (1, 1)) + JzKetCoupled(1, 0, (1, 1)), JzKetCoupled(1, -1, (1, 1)))
|
| 816 |
+
e4 = (ComplexSpace(1)*ComplexSpace(2) + FockSpace()**2)*(L2(Interval(
|
| 817 |
+
0, oo)) + HilbertSpace())
|
| 818 |
+
assert str(e1) == '(Jz**2)x(Dagger(A) + Dagger(B))*{Dagger(DifferentialOperator(Derivative(f(x), x),f(x)))**3,Dagger(A) + Dagger(B)}*(<1,0| + <1,1|)*(|0,0> + |1,-1>)'
|
| 819 |
+
ascii_str = \
|
| 820 |
+
"""\
|
| 821 |
+
/ 3 \\ \n\
|
| 822 |
+
|/ +\\ | \n\
|
| 823 |
+
2 / + +\\ <| /d \\ | + +> \n\
|
| 824 |
+
/J \\ x \\A + B /*||DifferentialOperator|--(f(x)),f(x)| | ,A + B |*(<1,0| + <1,1|)*(|0,0> + |1,-1>)\n\
|
| 825 |
+
\\ z/ \\\\ \\dx / / / \
|
| 826 |
+
"""
|
| 827 |
+
ucode_str = \
|
| 828 |
+
"""\
|
| 829 |
+
⎧ 3 ⎫ \n\
|
| 830 |
+
⎪⎛ †⎞ ⎪ \n\
|
| 831 |
+
2 ⎛ † †⎞ ⎨⎜ ⎛d ⎞ ⎟ † †⎬ \n\
|
| 832 |
+
⎛J ⎞ ⨂ ⎝A + B ⎠⋅⎪⎜DifferentialOperator⎜──(f(x)),f(x)⎟ ⎟ ,A + B ⎪⋅(⟨1,0❘ + ⟨1,1❘)⋅(❘0,0⟩ + ❘1,-1⟩)\n\
|
| 833 |
+
⎝ z⎠ ⎩⎝ ⎝dx ⎠ ⎠ ⎭ \
|
| 834 |
+
"""
|
| 835 |
+
assert pretty(e1) == ascii_str
|
| 836 |
+
assert upretty(e1) == ucode_str
|
| 837 |
+
assert latex(e1) == \
|
| 838 |
+
r'{J_z^{2}}\otimes \left({A^{\dagger} + B^{\dagger}}\right) \left\{\left(DifferentialOperator\left(\frac{d}{d x} f{\left(x \right)},f{\left(x \right)}\right)^{\dagger}\right)^{3},A^{\dagger} + B^{\dagger}\right\} \left({\left\langle 1,0\right|} + {\left\langle 1,1\right|}\right) \left({\left|0,0\right\rangle } + {\left|1,-1\right\rangle }\right)'
|
| 839 |
+
sT(e1, "Mul(TensorProduct(Pow(JzOp(Symbol('J')), Integer(2)), Add(Dagger(Operator(Symbol('A'))), Dagger(Operator(Symbol('B'))))), AntiCommutator(Pow(Dagger(DifferentialOperator(Derivative(Function('f')(Symbol('x')), Tuple(Symbol('x'), Integer(1))),Function('f')(Symbol('x')))), Integer(3)),Add(Dagger(Operator(Symbol('A'))), Dagger(Operator(Symbol('B'))))), Add(JzBra(Integer(1),Integer(0)), JzBra(Integer(1),Integer(1))), Add(JzKet(Integer(0),Integer(0)), JzKet(Integer(1),Integer(-1))))")
|
| 840 |
+
assert str(e2) == '[Jz**2,A + B]*{E**(-2),Dagger(D)*Dagger(C)}*[J2,Jz]'
|
| 841 |
+
ascii_str = \
|
| 842 |
+
"""\
|
| 843 |
+
[ 2 ] / -2 + +\\ [ 2 ]\n\
|
| 844 |
+
[/J \\ ,A + B]*<E ,D *C >*[J ,J ]\n\
|
| 845 |
+
[\\ z/ ] \\ / [ z]\
|
| 846 |
+
"""
|
| 847 |
+
ucode_str = \
|
| 848 |
+
"""\
|
| 849 |
+
⎡ 2 ⎤ ⎧ -2 † †⎫ ⎡ 2 ⎤\n\
|
| 850 |
+
⎢⎛J ⎞ ,A + B⎥⋅⎨E ,D ⋅C ⎬⋅⎢J ,J ⎥\n\
|
| 851 |
+
⎣⎝ z⎠ ⎦ ⎩ ⎭ ⎣ z⎦\
|
| 852 |
+
"""
|
| 853 |
+
assert pretty(e2) == ascii_str
|
| 854 |
+
assert upretty(e2) == ucode_str
|
| 855 |
+
assert latex(e2) == \
|
| 856 |
+
r'\left[J_z^{2},A + B\right] \left\{E^{-2},D^{\dagger} C^{\dagger}\right\} \left[J^2,J_z\right]'
|
| 857 |
+
sT(e2, "Mul(Commutator(Pow(JzOp(Symbol('J')), Integer(2)),Add(Operator(Symbol('A')), Operator(Symbol('B')))), AntiCommutator(Pow(Operator(Symbol('E')), Integer(-2)),Mul(Dagger(Operator(Symbol('D'))), Dagger(Operator(Symbol('C'))))), Commutator(J2Op(Symbol('J')),JzOp(Symbol('J'))))")
|
| 858 |
+
assert str(e3) == \
|
| 859 |
+
"Wigner3j(1, 2, 3, 4, 5, 6)*[Dagger(B) + A,C + D]x(-J2 + Jz)*|1,0><1,1|*(|1,0,j1=1,j2=1> + |1,1,j1=1,j2=1>)x|1,-1,j1=1,j2=1>"
|
| 860 |
+
ascii_str = \
|
| 861 |
+
"""\
|
| 862 |
+
[ + ] / 2 \\ \n\
|
| 863 |
+
/1 3 5\\*[B + A,C + D]x |- J + J |*|1,0><1,1|*(|1,0,j1=1,j2=1> + |1,1,j1=1,j2=1>)x |1,-1,j1=1,j2=1>\n\
|
| 864 |
+
| | \\ z/ \n\
|
| 865 |
+
\\2 4 6/ \
|
| 866 |
+
"""
|
| 867 |
+
ucode_str = \
|
| 868 |
+
"""\
|
| 869 |
+
⎡ † ⎤ ⎛ 2 ⎞ \n\
|
| 870 |
+
⎛1 3 5⎞⋅⎣B + A,C + D⎦⨂ ⎜- J + J ⎟⋅❘1,0⟩⟨1,1❘⋅(❘1,0,j₁=1,j₂=1⟩ + ❘1,1,j₁=1,j₂=1⟩)⨂ ❘1,-1,j₁=1,j₂=1⟩\n\
|
| 871 |
+
⎜ ⎟ ⎝ z⎠ \n\
|
| 872 |
+
⎝2 4 6⎠ \
|
| 873 |
+
"""
|
| 874 |
+
assert pretty(e3) == ascii_str
|
| 875 |
+
assert upretty(e3) == ucode_str
|
| 876 |
+
assert latex(e3) == \
|
| 877 |
+
r'\left(\begin{array}{ccc} 1 & 3 & 5 \\ 2 & 4 & 6 \end{array}\right) {\left[B^{\dagger} + A,C + D\right]}\otimes \left({- J^2 + J_z}\right) {\left|1,0\right\rangle }{\left\langle 1,1\right|} \left({{\left|1,0,j_{1}=1,j_{2}=1\right\rangle } + {\left|1,1,j_{1}=1,j_{2}=1\right\rangle }}\right)\otimes {{\left|1,-1,j_{1}=1,j_{2}=1\right\rangle }}'
|
| 878 |
+
sT(e3, "Mul(Wigner3j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6)), TensorProduct(Commutator(Add(Dagger(Operator(Symbol('B'))), Operator(Symbol('A'))),Add(Operator(Symbol('C')), Operator(Symbol('D')))), Add(Mul(Integer(-1), J2Op(Symbol('J'))), JzOp(Symbol('J')))), OuterProduct(JzKet(Integer(1),Integer(0)),JzBra(Integer(1),Integer(1))), TensorProduct(Add(JzKetCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))), JzKetCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))), JzKetCoupled(Integer(1),Integer(-1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))))")
|
| 879 |
+
assert str(e4) == '(C(1)*C(2)+F**2)*(L2(Interval(0, oo))+H)'
|
| 880 |
+
ascii_str = \
|
| 881 |
+
"""\
|
| 882 |
+
// 1 2\\ x2\\ / 2 \\\n\
|
| 883 |
+
\\\\C x C / + F / x \\L + H/\
|
| 884 |
+
"""
|
| 885 |
+
ucode_str = \
|
| 886 |
+
"""\
|
| 887 |
+
⎛⎛ 1 2⎞ ⨂2⎞ ⎛ 2 ⎞\n\
|
| 888 |
+
⎝⎝C ⨂ C ⎠ ⊕ F ⎠ ⨂ ⎝L ⊕ H⎠\
|
| 889 |
+
"""
|
| 890 |
+
assert pretty(e4) == ascii_str
|
| 891 |
+
assert upretty(e4) == ucode_str
|
| 892 |
+
assert latex(e4) == \
|
| 893 |
+
r'\left(\left(\mathcal{C}^{1}\otimes \mathcal{C}^{2}\right)\oplus {\mathcal{F}}^{\otimes 2}\right)\otimes \left({\mathcal{L}^2}\left( \left[0, \infty\right) \right)\oplus \mathcal{H}\right)'
|
| 894 |
+
sT(e4, "TensorProductHilbertSpace((DirectSumHilbertSpace(TensorProductHilbertSpace(ComplexSpace(Integer(1)),ComplexSpace(Integer(2))),TensorPowerHilbertSpace(FockSpace(),Integer(2)))),(DirectSumHilbertSpace(L2(Interval(Integer(0), oo, false, true)),HilbertSpace())))")
|
| 895 |
+
|
| 896 |
+
|
| 897 |
+
def _test_sho1d():
|
| 898 |
+
ad = RaisingOp('a')
|
| 899 |
+
assert pretty(ad) == ' \N{DAGGER}\na '
|
| 900 |
+
assert latex(ad) == 'a^{\\dagger}'
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_qapply.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.mul import Mul
|
| 2 |
+
from sympy.core.numbers import (I, Integer, Rational)
|
| 3 |
+
from sympy.core.singleton import S
|
| 4 |
+
from sympy.core.symbol import symbols
|
| 5 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 6 |
+
|
| 7 |
+
from sympy.physics.quantum.anticommutator import AntiCommutator
|
| 8 |
+
from sympy.physics.quantum.commutator import Commutator
|
| 9 |
+
from sympy.physics.quantum.constants import hbar
|
| 10 |
+
from sympy.physics.quantum.dagger import Dagger
|
| 11 |
+
from sympy.physics.quantum.gate import H, XGate, IdentityGate
|
| 12 |
+
from sympy.physics.quantum.operator import Operator, IdentityOperator
|
| 13 |
+
from sympy.physics.quantum.qapply import qapply
|
| 14 |
+
from sympy.physics.quantum.spin import Jx, Jy, Jz, Jplus, Jminus, J2, JzKet
|
| 15 |
+
from sympy.physics.quantum.tensorproduct import TensorProduct
|
| 16 |
+
from sympy.physics.quantum.state import Ket
|
| 17 |
+
from sympy.physics.quantum.density import Density
|
| 18 |
+
from sympy.physics.quantum.qubit import Qubit, QubitBra
|
| 19 |
+
from sympy.physics.quantum.boson import BosonOp, BosonFockKet, BosonFockBra
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
j, jp, m, mp = symbols("j j' m m'")
|
| 23 |
+
|
| 24 |
+
z = JzKet(1, 0)
|
| 25 |
+
po = JzKet(1, 1)
|
| 26 |
+
mo = JzKet(1, -1)
|
| 27 |
+
|
| 28 |
+
A = Operator('A')
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
class Foo(Operator):
|
| 32 |
+
def _apply_operator_JzKet(self, ket, **options):
|
| 33 |
+
return ket
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def test_basic():
|
| 37 |
+
assert qapply(Jz*po) == hbar*po
|
| 38 |
+
assert qapply(Jx*z) == hbar*po/sqrt(2) + hbar*mo/sqrt(2)
|
| 39 |
+
assert qapply((Jplus + Jminus)*z/sqrt(2)) == hbar*po + hbar*mo
|
| 40 |
+
assert qapply(Jz*(po + mo)) == hbar*po - hbar*mo
|
| 41 |
+
assert qapply(Jz*po + Jz*mo) == hbar*po - hbar*mo
|
| 42 |
+
assert qapply(Jminus*Jminus*po) == 2*hbar**2*mo
|
| 43 |
+
assert qapply(Jplus**2*mo) == 2*hbar**2*po
|
| 44 |
+
assert qapply(Jplus**2*Jminus**2*po) == 4*hbar**4*po
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def test_extra():
|
| 48 |
+
extra = z.dual*A*z
|
| 49 |
+
assert qapply(Jz*po*extra) == hbar*po*extra
|
| 50 |
+
assert qapply(Jx*z*extra) == (hbar*po/sqrt(2) + hbar*mo/sqrt(2))*extra
|
| 51 |
+
assert qapply(
|
| 52 |
+
(Jplus + Jminus)*z/sqrt(2)*extra) == hbar*po*extra + hbar*mo*extra
|
| 53 |
+
assert qapply(Jz*(po + mo)*extra) == hbar*po*extra - hbar*mo*extra
|
| 54 |
+
assert qapply(Jz*po*extra + Jz*mo*extra) == hbar*po*extra - hbar*mo*extra
|
| 55 |
+
assert qapply(Jminus*Jminus*po*extra) == 2*hbar**2*mo*extra
|
| 56 |
+
assert qapply(Jplus**2*mo*extra) == 2*hbar**2*po*extra
|
| 57 |
+
assert qapply(Jplus**2*Jminus**2*po*extra) == 4*hbar**4*po*extra
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def test_innerproduct():
|
| 61 |
+
assert qapply(po.dual*Jz*po, ip_doit=False) == hbar*(po.dual*po)
|
| 62 |
+
assert qapply(po.dual*Jz*po) == hbar
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def test_zero():
|
| 66 |
+
assert qapply(0) == 0
|
| 67 |
+
assert qapply(Integer(0)) == 0
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
def test_commutator():
|
| 71 |
+
assert qapply(Commutator(Jx, Jy)*Jz*po) == I*hbar**3*po
|
| 72 |
+
assert qapply(Commutator(J2, Jz)*Jz*po) == 0
|
| 73 |
+
assert qapply(Commutator(Jz, Foo('F'))*po) == 0
|
| 74 |
+
assert qapply(Commutator(Foo('F'), Jz)*po) == 0
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def test_anticommutator():
|
| 78 |
+
assert qapply(AntiCommutator(Jz, Foo('F'))*po) == 2*hbar*po
|
| 79 |
+
assert qapply(AntiCommutator(Foo('F'), Jz)*po) == 2*hbar*po
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def test_outerproduct():
|
| 83 |
+
e = Jz*(mo*po.dual)*Jz*po
|
| 84 |
+
assert qapply(e) == -hbar**2*mo
|
| 85 |
+
assert qapply(e, ip_doit=False) == -hbar**2*(po.dual*po)*mo
|
| 86 |
+
assert qapply(e).doit() == -hbar**2*mo
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
def test_tensorproduct():
|
| 90 |
+
a = BosonOp("a")
|
| 91 |
+
b = BosonOp("b")
|
| 92 |
+
ket1 = TensorProduct(BosonFockKet(1), BosonFockKet(2))
|
| 93 |
+
ket2 = TensorProduct(BosonFockKet(0), BosonFockKet(0))
|
| 94 |
+
ket3 = TensorProduct(BosonFockKet(0), BosonFockKet(2))
|
| 95 |
+
bra1 = TensorProduct(BosonFockBra(0), BosonFockBra(0))
|
| 96 |
+
bra2 = TensorProduct(BosonFockBra(1), BosonFockBra(2))
|
| 97 |
+
assert qapply(TensorProduct(a, b ** 2) * ket1) == sqrt(2) * ket2
|
| 98 |
+
assert qapply(TensorProduct(a, Dagger(b) * b) * ket1) == 2 * ket3
|
| 99 |
+
assert qapply(bra1 * TensorProduct(a, b * b),
|
| 100 |
+
dagger=True) == sqrt(2) * bra2
|
| 101 |
+
assert qapply(bra2 * ket1).doit() == TensorProduct(1, 1)
|
| 102 |
+
assert qapply(TensorProduct(a, b * b) * ket1) == sqrt(2) * ket2
|
| 103 |
+
assert qapply(Dagger(TensorProduct(a, b * b) * ket1),
|
| 104 |
+
dagger=True) == sqrt(2) * Dagger(ket2)
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def test_dagger():
|
| 108 |
+
lhs = Dagger(Qubit(0))*Dagger(H(0))
|
| 109 |
+
rhs = Dagger(Qubit(1))/sqrt(2) + Dagger(Qubit(0))/sqrt(2)
|
| 110 |
+
assert qapply(lhs, dagger=True) == rhs
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
def test_issue_6073():
|
| 114 |
+
x, y = symbols('x y', commutative=False)
|
| 115 |
+
A = Ket(x, y)
|
| 116 |
+
B = Operator('B')
|
| 117 |
+
assert qapply(A) == A
|
| 118 |
+
assert qapply(A.dual*B) == A.dual*B
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
def test_density():
|
| 122 |
+
d = Density([Jz*mo, 0.5], [Jz*po, 0.5])
|
| 123 |
+
assert qapply(d) == Density([-hbar*mo, 0.5], [hbar*po, 0.5])
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
def test_issue3044():
|
| 127 |
+
expr1 = TensorProduct(Jz*JzKet(S(2),S.NegativeOne)/sqrt(2), Jz*JzKet(S.Half,S.Half))
|
| 128 |
+
result = Mul(S.NegativeOne, Rational(1, 4), 2**S.Half, hbar**2)
|
| 129 |
+
result *= TensorProduct(JzKet(2,-1), JzKet(S.Half,S.Half))
|
| 130 |
+
assert qapply(expr1) == result
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
# Issue 24158: Tests whether qapply incorrectly evaluates some ket*op as op*ket
|
| 134 |
+
def test_issue24158_ket_times_op():
|
| 135 |
+
P = BosonFockKet(0) * BosonOp("a") # undefined term
|
| 136 |
+
# Does lhs._apply_operator_BosonOp(rhs) still evaluate ket*op as op*ket?
|
| 137 |
+
assert qapply(P) == P # qapply(P) -> BosonOp("a")*BosonFockKet(0) = 0 before fix
|
| 138 |
+
P = Qubit(1) * XGate(0) # undefined term
|
| 139 |
+
# Does rhs._apply_operator_Qubit(lhs) still evaluate ket*op as op*ket?
|
| 140 |
+
assert qapply(P) == P # qapply(P) -> Qubit(0) before fix
|
| 141 |
+
P1 = Mul(QubitBra(0), Mul(QubitBra(0), Qubit(0)), XGate(0)) # legal expr <0| * (<1|*|1>) * X
|
| 142 |
+
assert qapply(P1) == QubitBra(0) * XGate(0) # qapply(P1) -> 0 before fix
|
| 143 |
+
P1 = qapply(P1, dagger = True) # unsatisfactorily -> <0|*X(0), expect <1| since dagger=True
|
| 144 |
+
assert qapply(P1, dagger = True) == QubitBra(1) # qapply(P1, dagger=True) -> 0 before fix
|
| 145 |
+
P2 = QubitBra(0) * QubitBra(0) * Qubit(0) * XGate(0) # 'forgot' to set brackets
|
| 146 |
+
P2 = qapply(P2, dagger = True) # unsatisfactorily -> <0|*X(0), expect <1| since dagger=True
|
| 147 |
+
assert qapply(P2, dagger = True) == QubitBra(1) # qapply(P1) -> 0 before fix
|
| 148 |
+
# Pull Request 24237: IdentityOperator from the right without dagger=True option
|
| 149 |
+
assert qapply(QubitBra(1)*IdentityOperator()) == QubitBra(1)
|
| 150 |
+
assert qapply(IdentityGate(0)*(Qubit(0) + Qubit(1))) == Qubit(0) + Qubit(1)
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_qasm.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.physics.quantum.qasm import Qasm, flip_index, trim,\
|
| 2 |
+
get_index, nonblank, fullsplit, fixcommand, stripquotes, read_qasm
|
| 3 |
+
from sympy.physics.quantum.gate import X, Z, H, S, T
|
| 4 |
+
from sympy.physics.quantum.gate import CNOT, SWAP, CPHASE, CGate, CGateS
|
| 5 |
+
from sympy.physics.quantum.circuitplot import Mz
|
| 6 |
+
|
| 7 |
+
def test_qasm_readqasm():
|
| 8 |
+
qasm_lines = """\
|
| 9 |
+
qubit q_0
|
| 10 |
+
qubit q_1
|
| 11 |
+
h q_0
|
| 12 |
+
cnot q_0,q_1
|
| 13 |
+
"""
|
| 14 |
+
q = read_qasm(qasm_lines)
|
| 15 |
+
assert q.get_circuit() == CNOT(1,0)*H(1)
|
| 16 |
+
|
| 17 |
+
def test_qasm_ex1():
|
| 18 |
+
q = Qasm('qubit q0', 'qubit q1', 'h q0', 'cnot q0,q1')
|
| 19 |
+
assert q.get_circuit() == CNOT(1,0)*H(1)
|
| 20 |
+
|
| 21 |
+
def test_qasm_ex1_methodcalls():
|
| 22 |
+
q = Qasm()
|
| 23 |
+
q.qubit('q_0')
|
| 24 |
+
q.qubit('q_1')
|
| 25 |
+
q.h('q_0')
|
| 26 |
+
q.cnot('q_0', 'q_1')
|
| 27 |
+
assert q.get_circuit() == CNOT(1,0)*H(1)
|
| 28 |
+
|
| 29 |
+
def test_qasm_swap():
|
| 30 |
+
q = Qasm('qubit q0', 'qubit q1', 'cnot q0,q1', 'cnot q1,q0', 'cnot q0,q1')
|
| 31 |
+
assert q.get_circuit() == CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def test_qasm_ex2():
|
| 35 |
+
q = Qasm('qubit q_0', 'qubit q_1', 'qubit q_2', 'h q_1',
|
| 36 |
+
'cnot q_1,q_2', 'cnot q_0,q_1', 'h q_0',
|
| 37 |
+
'measure q_1', 'measure q_0',
|
| 38 |
+
'c-x q_1,q_2', 'c-z q_0,q_2')
|
| 39 |
+
assert q.get_circuit() == CGate(2,Z(0))*CGate(1,X(0))*Mz(2)*Mz(1)*H(2)*CNOT(2,1)*CNOT(1,0)*H(1)
|
| 40 |
+
|
| 41 |
+
def test_qasm_1q():
|
| 42 |
+
for symbol, gate in [('x', X), ('z', Z), ('h', H), ('s', S), ('t', T), ('measure', Mz)]:
|
| 43 |
+
q = Qasm('qubit q_0', '%s q_0' % symbol)
|
| 44 |
+
assert q.get_circuit() == gate(0)
|
| 45 |
+
|
| 46 |
+
def test_qasm_2q():
|
| 47 |
+
for symbol, gate in [('cnot', CNOT), ('swap', SWAP), ('cphase', CPHASE)]:
|
| 48 |
+
q = Qasm('qubit q_0', 'qubit q_1', '%s q_0,q_1' % symbol)
|
| 49 |
+
assert q.get_circuit() == gate(1,0)
|
| 50 |
+
|
| 51 |
+
def test_qasm_3q():
|
| 52 |
+
q = Qasm('qubit q0', 'qubit q1', 'qubit q2', 'toffoli q2,q1,q0')
|
| 53 |
+
assert q.get_circuit() == CGateS((0,1),X(2))
|
| 54 |
+
|
| 55 |
+
def test_qasm_flip_index():
|
| 56 |
+
assert flip_index(0, 2) == 1
|
| 57 |
+
assert flip_index(1, 2) == 0
|
| 58 |
+
|
| 59 |
+
def test_qasm_trim():
|
| 60 |
+
assert trim('nothing happens here') == 'nothing happens here'
|
| 61 |
+
assert trim("Something #happens here") == "Something "
|
| 62 |
+
|
| 63 |
+
def test_qasm_get_index():
|
| 64 |
+
assert get_index('q0', ['q0', 'q1']) == 1
|
| 65 |
+
assert get_index('q1', ['q0', 'q1']) == 0
|
| 66 |
+
|
| 67 |
+
def test_qasm_nonblank():
|
| 68 |
+
assert list(nonblank('abcd')) == list('abcd')
|
| 69 |
+
assert list(nonblank('abc ')) == list('abc')
|
| 70 |
+
|
| 71 |
+
def test_qasm_fullsplit():
|
| 72 |
+
assert fullsplit('g q0,q1,q2, q3') == ('g', ['q0', 'q1', 'q2', 'q3'])
|
| 73 |
+
|
| 74 |
+
def test_qasm_fixcommand():
|
| 75 |
+
assert fixcommand('foo') == 'foo'
|
| 76 |
+
assert fixcommand('def') == 'qdef'
|
| 77 |
+
|
| 78 |
+
def test_qasm_stripquotes():
|
| 79 |
+
assert stripquotes("'S'") == 'S'
|
| 80 |
+
assert stripquotes('"S"') == 'S'
|
| 81 |
+
assert stripquotes('S') == 'S'
|
| 82 |
+
|
| 83 |
+
def test_qasm_qdef():
|
| 84 |
+
# weaker test condition (str) since we don't have access to the actual class
|
| 85 |
+
q = Qasm("def Q,0,Q",'qubit q0','Q q0')
|
| 86 |
+
assert str(q.get_circuit()) == 'Q(0)'
|
| 87 |
+
|
| 88 |
+
q = Qasm("def CQ,1,Q", 'qubit q0', 'qubit q1', 'CQ q0,q1')
|
| 89 |
+
assert str(q.get_circuit()) == 'C((1),Q(0))'
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_qexpr.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.numbers import Integer
|
| 2 |
+
from sympy.core.symbol import Symbol
|
| 3 |
+
from sympy.physics.quantum.qexpr import QExpr, _qsympify_sequence
|
| 4 |
+
from sympy.physics.quantum.hilbert import HilbertSpace
|
| 5 |
+
from sympy.core.containers import Tuple
|
| 6 |
+
|
| 7 |
+
x = Symbol('x')
|
| 8 |
+
y = Symbol('y')
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def test_qexpr_new():
|
| 12 |
+
q = QExpr(0)
|
| 13 |
+
assert q.label == (0,)
|
| 14 |
+
assert q.hilbert_space == HilbertSpace()
|
| 15 |
+
assert q.is_commutative is False
|
| 16 |
+
|
| 17 |
+
q = QExpr(0, 1)
|
| 18 |
+
assert q.label == (Integer(0), Integer(1))
|
| 19 |
+
|
| 20 |
+
q = QExpr._new_rawargs(HilbertSpace(), Integer(0), Integer(1))
|
| 21 |
+
assert q.label == (Integer(0), Integer(1))
|
| 22 |
+
assert q.hilbert_space == HilbertSpace()
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def test_qexpr_commutative():
|
| 26 |
+
q1 = QExpr(x)
|
| 27 |
+
q2 = QExpr(y)
|
| 28 |
+
assert q1.is_commutative is False
|
| 29 |
+
assert q2.is_commutative is False
|
| 30 |
+
assert q1*q2 != q2*q1
|
| 31 |
+
|
| 32 |
+
q = QExpr._new_rawargs(Integer(0), Integer(1), HilbertSpace())
|
| 33 |
+
assert q.is_commutative is False
|
| 34 |
+
|
| 35 |
+
def test_qexpr_commutative_free_symbols():
|
| 36 |
+
q1 = QExpr(x)
|
| 37 |
+
assert q1.free_symbols.pop().is_commutative is False
|
| 38 |
+
|
| 39 |
+
q2 = QExpr('q2')
|
| 40 |
+
assert q2.free_symbols.pop().is_commutative is False
|
| 41 |
+
|
| 42 |
+
def test_qexpr_subs():
|
| 43 |
+
q1 = QExpr(x, y)
|
| 44 |
+
assert q1.subs(x, y) == QExpr(y, y)
|
| 45 |
+
assert q1.subs({x: 1, y: 2}) == QExpr(1, 2)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def test_qsympify():
|
| 49 |
+
assert _qsympify_sequence([[1, 2], [1, 3]]) == (Tuple(1, 2), Tuple(1, 3))
|
| 50 |
+
assert _qsympify_sequence(([1, 2, [3, 4, [2, ]], 1], 3)) == \
|
| 51 |
+
(Tuple(1, 2, Tuple(3, 4, Tuple(2,)), 1), 3)
|
| 52 |
+
assert _qsympify_sequence((1,)) == (1,)
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_qft.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.numbers import (I, pi)
|
| 2 |
+
from sympy.core.symbol import Symbol
|
| 3 |
+
from sympy.functions.elementary.exponential import exp
|
| 4 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 5 |
+
from sympy.matrices.dense import Matrix
|
| 6 |
+
|
| 7 |
+
from sympy.physics.quantum.qft import QFT, IQFT, RkGate
|
| 8 |
+
from sympy.physics.quantum.gate import (ZGate, SwapGate, HadamardGate, CGate,
|
| 9 |
+
PhaseGate, TGate)
|
| 10 |
+
from sympy.physics.quantum.qubit import Qubit
|
| 11 |
+
from sympy.physics.quantum.qapply import qapply
|
| 12 |
+
from sympy.physics.quantum.represent import represent
|
| 13 |
+
|
| 14 |
+
from sympy.functions.elementary.complexes import sign
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def test_RkGate():
|
| 18 |
+
x = Symbol('x')
|
| 19 |
+
assert RkGate(1, x).k == x
|
| 20 |
+
assert RkGate(1, x).targets == (1,)
|
| 21 |
+
assert RkGate(1, 1) == ZGate(1)
|
| 22 |
+
assert RkGate(2, 2) == PhaseGate(2)
|
| 23 |
+
assert RkGate(3, 3) == TGate(3)
|
| 24 |
+
|
| 25 |
+
assert represent(
|
| 26 |
+
RkGate(0, x), nqubits=1) == Matrix([[1, 0], [0, exp(sign(x)*2*pi*I/(2**abs(x)))]])
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def test_quantum_fourier():
|
| 30 |
+
assert QFT(0, 3).decompose() == \
|
| 31 |
+
SwapGate(0, 2)*HadamardGate(0)*CGate((0,), PhaseGate(1)) * \
|
| 32 |
+
HadamardGate(1)*CGate((0,), TGate(2))*CGate((1,), PhaseGate(2)) * \
|
| 33 |
+
HadamardGate(2)
|
| 34 |
+
|
| 35 |
+
assert IQFT(0, 3).decompose() == \
|
| 36 |
+
HadamardGate(2)*CGate((1,), RkGate(2, -2))*CGate((0,), RkGate(2, -3)) * \
|
| 37 |
+
HadamardGate(1)*CGate((0,), RkGate(1, -2))*HadamardGate(0)*SwapGate(0, 2)
|
| 38 |
+
|
| 39 |
+
assert represent(QFT(0, 3), nqubits=3) == \
|
| 40 |
+
Matrix([[exp(2*pi*I/8)**(i*j % 8)/sqrt(8) for i in range(8)] for j in range(8)])
|
| 41 |
+
|
| 42 |
+
assert QFT(0, 4).decompose() # non-trivial decomposition
|
| 43 |
+
assert qapply(QFT(0, 3).decompose()*Qubit(0, 0, 0)).expand() == qapply(
|
| 44 |
+
HadamardGate(0)*HadamardGate(1)*HadamardGate(2)*Qubit(0, 0, 0)
|
| 45 |
+
).expand()
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def test_qft_represent():
|
| 49 |
+
c = QFT(0, 3)
|
| 50 |
+
a = represent(c, nqubits=3)
|
| 51 |
+
b = represent(c.decompose(), nqubits=3)
|
| 52 |
+
assert a.evalf(n=10) == b.evalf(n=10)
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_state.py
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.add import Add
|
| 2 |
+
from sympy.core.function import diff
|
| 3 |
+
from sympy.core.mul import Mul
|
| 4 |
+
from sympy.core.numbers import (I, Integer, Rational, oo, pi)
|
| 5 |
+
from sympy.core.power import Pow
|
| 6 |
+
from sympy.core.singleton import S
|
| 7 |
+
from sympy.core.symbol import (Symbol, symbols)
|
| 8 |
+
from sympy.core.sympify import sympify
|
| 9 |
+
from sympy.functions.elementary.complexes import conjugate
|
| 10 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 11 |
+
from sympy.functions.elementary.trigonometric import sin
|
| 12 |
+
from sympy.testing.pytest import raises
|
| 13 |
+
|
| 14 |
+
from sympy.physics.quantum.dagger import Dagger
|
| 15 |
+
from sympy.physics.quantum.qexpr import QExpr
|
| 16 |
+
from sympy.physics.quantum.state import (
|
| 17 |
+
Ket, Bra, TimeDepKet, TimeDepBra,
|
| 18 |
+
KetBase, BraBase, StateBase, Wavefunction,
|
| 19 |
+
OrthogonalKet, OrthogonalBra
|
| 20 |
+
)
|
| 21 |
+
from sympy.physics.quantum.hilbert import HilbertSpace
|
| 22 |
+
|
| 23 |
+
x, y, t = symbols('x,y,t')
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
class CustomKet(Ket):
|
| 27 |
+
@classmethod
|
| 28 |
+
def default_args(self):
|
| 29 |
+
return ("test",)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class CustomKetMultipleLabels(Ket):
|
| 33 |
+
@classmethod
|
| 34 |
+
def default_args(self):
|
| 35 |
+
return ("r", "theta", "phi")
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
class CustomTimeDepKet(TimeDepKet):
|
| 39 |
+
@classmethod
|
| 40 |
+
def default_args(self):
|
| 41 |
+
return ("test", "t")
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class CustomTimeDepKetMultipleLabels(TimeDepKet):
|
| 45 |
+
@classmethod
|
| 46 |
+
def default_args(self):
|
| 47 |
+
return ("r", "theta", "phi", "t")
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def test_ket():
|
| 51 |
+
k = Ket('0')
|
| 52 |
+
|
| 53 |
+
assert isinstance(k, Ket)
|
| 54 |
+
assert isinstance(k, KetBase)
|
| 55 |
+
assert isinstance(k, StateBase)
|
| 56 |
+
assert isinstance(k, QExpr)
|
| 57 |
+
|
| 58 |
+
assert k.label == (Symbol('0'),)
|
| 59 |
+
assert k.hilbert_space == HilbertSpace()
|
| 60 |
+
assert k.is_commutative is False
|
| 61 |
+
|
| 62 |
+
# Make sure this doesn't get converted to the number pi.
|
| 63 |
+
k = Ket('pi')
|
| 64 |
+
assert k.label == (Symbol('pi'),)
|
| 65 |
+
|
| 66 |
+
k = Ket(x, y)
|
| 67 |
+
assert k.label == (x, y)
|
| 68 |
+
assert k.hilbert_space == HilbertSpace()
|
| 69 |
+
assert k.is_commutative is False
|
| 70 |
+
|
| 71 |
+
assert k.dual_class() == Bra
|
| 72 |
+
assert k.dual == Bra(x, y)
|
| 73 |
+
assert k.subs(x, y) == Ket(y, y)
|
| 74 |
+
|
| 75 |
+
k = CustomKet()
|
| 76 |
+
assert k == CustomKet("test")
|
| 77 |
+
|
| 78 |
+
k = CustomKetMultipleLabels()
|
| 79 |
+
assert k == CustomKetMultipleLabels("r", "theta", "phi")
|
| 80 |
+
|
| 81 |
+
assert Ket() == Ket('psi')
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def test_bra():
|
| 85 |
+
b = Bra('0')
|
| 86 |
+
|
| 87 |
+
assert isinstance(b, Bra)
|
| 88 |
+
assert isinstance(b, BraBase)
|
| 89 |
+
assert isinstance(b, StateBase)
|
| 90 |
+
assert isinstance(b, QExpr)
|
| 91 |
+
|
| 92 |
+
assert b.label == (Symbol('0'),)
|
| 93 |
+
assert b.hilbert_space == HilbertSpace()
|
| 94 |
+
assert b.is_commutative is False
|
| 95 |
+
|
| 96 |
+
# Make sure this doesn't get converted to the number pi.
|
| 97 |
+
b = Bra('pi')
|
| 98 |
+
assert b.label == (Symbol('pi'),)
|
| 99 |
+
|
| 100 |
+
b = Bra(x, y)
|
| 101 |
+
assert b.label == (x, y)
|
| 102 |
+
assert b.hilbert_space == HilbertSpace()
|
| 103 |
+
assert b.is_commutative is False
|
| 104 |
+
|
| 105 |
+
assert b.dual_class() == Ket
|
| 106 |
+
assert b.dual == Ket(x, y)
|
| 107 |
+
assert b.subs(x, y) == Bra(y, y)
|
| 108 |
+
|
| 109 |
+
assert Bra() == Bra('psi')
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
def test_ops():
|
| 113 |
+
k0 = Ket(0)
|
| 114 |
+
k1 = Ket(1)
|
| 115 |
+
k = 2*I*k0 - (x/sqrt(2))*k1
|
| 116 |
+
assert k == Add(Mul(2, I, k0),
|
| 117 |
+
Mul(Rational(-1, 2), x, Pow(2, S.Half), k1))
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
def test_time_dep_ket():
|
| 121 |
+
k = TimeDepKet(0, t)
|
| 122 |
+
|
| 123 |
+
assert isinstance(k, TimeDepKet)
|
| 124 |
+
assert isinstance(k, KetBase)
|
| 125 |
+
assert isinstance(k, StateBase)
|
| 126 |
+
assert isinstance(k, QExpr)
|
| 127 |
+
|
| 128 |
+
assert k.label == (Integer(0),)
|
| 129 |
+
assert k.args == (Integer(0), t)
|
| 130 |
+
assert k.time == t
|
| 131 |
+
|
| 132 |
+
assert k.dual_class() == TimeDepBra
|
| 133 |
+
assert k.dual == TimeDepBra(0, t)
|
| 134 |
+
|
| 135 |
+
assert k.subs(t, 2) == TimeDepKet(0, 2)
|
| 136 |
+
|
| 137 |
+
k = TimeDepKet(x, 0.5)
|
| 138 |
+
assert k.label == (x,)
|
| 139 |
+
assert k.args == (x, sympify(0.5))
|
| 140 |
+
|
| 141 |
+
k = CustomTimeDepKet()
|
| 142 |
+
assert k.label == (Symbol("test"),)
|
| 143 |
+
assert k.time == Symbol("t")
|
| 144 |
+
assert k == CustomTimeDepKet("test", "t")
|
| 145 |
+
|
| 146 |
+
k = CustomTimeDepKetMultipleLabels()
|
| 147 |
+
assert k.label == (Symbol("r"), Symbol("theta"), Symbol("phi"))
|
| 148 |
+
assert k.time == Symbol("t")
|
| 149 |
+
assert k == CustomTimeDepKetMultipleLabels("r", "theta", "phi", "t")
|
| 150 |
+
|
| 151 |
+
assert TimeDepKet() == TimeDepKet("psi", "t")
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def test_time_dep_bra():
|
| 155 |
+
b = TimeDepBra(0, t)
|
| 156 |
+
|
| 157 |
+
assert isinstance(b, TimeDepBra)
|
| 158 |
+
assert isinstance(b, BraBase)
|
| 159 |
+
assert isinstance(b, StateBase)
|
| 160 |
+
assert isinstance(b, QExpr)
|
| 161 |
+
|
| 162 |
+
assert b.label == (Integer(0),)
|
| 163 |
+
assert b.args == (Integer(0), t)
|
| 164 |
+
assert b.time == t
|
| 165 |
+
|
| 166 |
+
assert b.dual_class() == TimeDepKet
|
| 167 |
+
assert b.dual == TimeDepKet(0, t)
|
| 168 |
+
|
| 169 |
+
k = TimeDepBra(x, 0.5)
|
| 170 |
+
assert k.label == (x,)
|
| 171 |
+
assert k.args == (x, sympify(0.5))
|
| 172 |
+
|
| 173 |
+
assert TimeDepBra() == TimeDepBra("psi", "t")
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
def test_bra_ket_dagger():
|
| 177 |
+
x = symbols('x', complex=True)
|
| 178 |
+
k = Ket('k')
|
| 179 |
+
b = Bra('b')
|
| 180 |
+
assert Dagger(k) == Bra('k')
|
| 181 |
+
assert Dagger(b) == Ket('b')
|
| 182 |
+
assert Dagger(k).is_commutative is False
|
| 183 |
+
|
| 184 |
+
k2 = Ket('k2')
|
| 185 |
+
e = 2*I*k + x*k2
|
| 186 |
+
assert Dagger(e) == conjugate(x)*Dagger(k2) - 2*I*Dagger(k)
|
| 187 |
+
|
| 188 |
+
|
| 189 |
+
def test_wavefunction():
|
| 190 |
+
x, y = symbols('x y', real=True)
|
| 191 |
+
L = symbols('L', positive=True)
|
| 192 |
+
n = symbols('n', integer=True, positive=True)
|
| 193 |
+
|
| 194 |
+
f = Wavefunction(x**2, x)
|
| 195 |
+
p = f.prob()
|
| 196 |
+
lims = f.limits
|
| 197 |
+
|
| 198 |
+
assert f.is_normalized is False
|
| 199 |
+
assert f.norm is oo
|
| 200 |
+
assert f(10) == 100
|
| 201 |
+
assert p(10) == 10000
|
| 202 |
+
assert lims[x] == (-oo, oo)
|
| 203 |
+
assert diff(f, x) == Wavefunction(2*x, x)
|
| 204 |
+
raises(NotImplementedError, lambda: f.normalize())
|
| 205 |
+
assert conjugate(f) == Wavefunction(conjugate(f.expr), x)
|
| 206 |
+
assert conjugate(f) == Dagger(f)
|
| 207 |
+
|
| 208 |
+
g = Wavefunction(x**2*y + y**2*x, (x, 0, 1), (y, 0, 2))
|
| 209 |
+
lims_g = g.limits
|
| 210 |
+
|
| 211 |
+
assert lims_g[x] == (0, 1)
|
| 212 |
+
assert lims_g[y] == (0, 2)
|
| 213 |
+
assert g.is_normalized is False
|
| 214 |
+
assert g.norm == sqrt(42)/3
|
| 215 |
+
assert g(2, 4) == 0
|
| 216 |
+
assert g(1, 1) == 2
|
| 217 |
+
assert diff(diff(g, x), y) == Wavefunction(2*x + 2*y, (x, 0, 1), (y, 0, 2))
|
| 218 |
+
assert conjugate(g) == Wavefunction(conjugate(g.expr), *g.args[1:])
|
| 219 |
+
assert conjugate(g) == Dagger(g)
|
| 220 |
+
|
| 221 |
+
h = Wavefunction(sqrt(5)*x**2, (x, 0, 1))
|
| 222 |
+
assert h.is_normalized is True
|
| 223 |
+
assert h.normalize() == h
|
| 224 |
+
assert conjugate(h) == Wavefunction(conjugate(h.expr), (x, 0, 1))
|
| 225 |
+
assert conjugate(h) == Dagger(h)
|
| 226 |
+
|
| 227 |
+
piab = Wavefunction(sin(n*pi*x/L), (x, 0, L))
|
| 228 |
+
assert piab.norm == sqrt(L/2)
|
| 229 |
+
assert piab(L + 1) == 0
|
| 230 |
+
assert piab(0.5) == sin(0.5*n*pi/L)
|
| 231 |
+
assert piab(0.5, n=1, L=1) == sin(0.5*pi)
|
| 232 |
+
assert piab.normalize() == \
|
| 233 |
+
Wavefunction(sqrt(2)/sqrt(L)*sin(n*pi*x/L), (x, 0, L))
|
| 234 |
+
assert conjugate(piab) == Wavefunction(conjugate(piab.expr), (x, 0, L))
|
| 235 |
+
assert conjugate(piab) == Dagger(piab)
|
| 236 |
+
|
| 237 |
+
k = Wavefunction(x**2, 'x')
|
| 238 |
+
assert type(k.variables[0]) == Symbol
|
| 239 |
+
|
| 240 |
+
def test_orthogonal_states():
|
| 241 |
+
braket = OrthogonalBra(x) * OrthogonalKet(x)
|
| 242 |
+
assert braket.doit() == 1
|
| 243 |
+
|
| 244 |
+
braket = OrthogonalBra(x) * OrthogonalKet(x+1)
|
| 245 |
+
assert braket.doit() == 0
|
| 246 |
+
|
| 247 |
+
braket = OrthogonalBra(x) * OrthogonalKet(y)
|
| 248 |
+
assert braket.doit() == braket
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_tensorproduct.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.numbers import I
|
| 2 |
+
from sympy.core.symbol import symbols
|
| 3 |
+
from sympy.core.expr import unchanged
|
| 4 |
+
from sympy.matrices import Matrix, SparseMatrix, ImmutableMatrix
|
| 5 |
+
|
| 6 |
+
from sympy.physics.quantum.commutator import Commutator as Comm
|
| 7 |
+
from sympy.physics.quantum.tensorproduct import TensorProduct
|
| 8 |
+
from sympy.physics.quantum.tensorproduct import TensorProduct as TP
|
| 9 |
+
from sympy.physics.quantum.tensorproduct import tensor_product_simp
|
| 10 |
+
from sympy.physics.quantum.dagger import Dagger
|
| 11 |
+
from sympy.physics.quantum.qubit import Qubit, QubitBra
|
| 12 |
+
from sympy.physics.quantum.operator import OuterProduct
|
| 13 |
+
from sympy.physics.quantum.density import Density
|
| 14 |
+
from sympy.physics.quantum.trace import Tr
|
| 15 |
+
|
| 16 |
+
A, B, C, D = symbols('A,B,C,D', commutative=False)
|
| 17 |
+
x = symbols('x')
|
| 18 |
+
|
| 19 |
+
mat1 = Matrix([[1, 2*I], [1 + I, 3]])
|
| 20 |
+
mat2 = Matrix([[2*I, 3], [4*I, 2]])
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def test_sparse_matrices():
|
| 24 |
+
spm = SparseMatrix.diag(1, 0)
|
| 25 |
+
assert unchanged(TensorProduct, spm, spm)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def test_tensor_product_dagger():
|
| 29 |
+
assert Dagger(TensorProduct(I*A, B)) == \
|
| 30 |
+
-I*TensorProduct(Dagger(A), Dagger(B))
|
| 31 |
+
assert Dagger(TensorProduct(mat1, mat2)) == \
|
| 32 |
+
TensorProduct(Dagger(mat1), Dagger(mat2))
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def test_tensor_product_abstract():
|
| 36 |
+
|
| 37 |
+
assert TP(x*A, 2*B) == x*2*TP(A, B)
|
| 38 |
+
assert TP(A, B) != TP(B, A)
|
| 39 |
+
assert TP(A, B).is_commutative is False
|
| 40 |
+
assert isinstance(TP(A, B), TP)
|
| 41 |
+
assert TP(A, B).subs(A, C) == TP(C, B)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def test_tensor_product_expand():
|
| 45 |
+
assert TP(A + B, B + C).expand(tensorproduct=True) == \
|
| 46 |
+
TP(A, B) + TP(A, C) + TP(B, B) + TP(B, C)
|
| 47 |
+
#Tests for fix of issue #24142
|
| 48 |
+
assert TP(A-B, B-A).expand(tensorproduct=True) == \
|
| 49 |
+
TP(A, B) - TP(A, A) - TP(B, B) + TP(B, A)
|
| 50 |
+
assert TP(2*A + B, A + B).expand(tensorproduct=True) == \
|
| 51 |
+
2 * TP(A, A) + 2 * TP(A, B) + TP(B, A) + TP(B, B)
|
| 52 |
+
assert TP(2 * A * B + A, A + B).expand(tensorproduct=True) == \
|
| 53 |
+
2 * TP(A*B, A) + 2 * TP(A*B, B) + TP(A, A) + TP(A, B)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def test_tensor_product_commutator():
|
| 57 |
+
assert TP(Comm(A, B), C).doit().expand(tensorproduct=True) == \
|
| 58 |
+
TP(A*B, C) - TP(B*A, C)
|
| 59 |
+
assert Comm(TP(A, B), TP(B, C)).doit() == \
|
| 60 |
+
TP(A, B)*TP(B, C) - TP(B, C)*TP(A, B)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def test_tensor_product_simp():
|
| 64 |
+
assert tensor_product_simp(TP(A, B)*TP(B, C)) == TP(A*B, B*C)
|
| 65 |
+
# tests for Pow-expressions
|
| 66 |
+
assert tensor_product_simp(TP(A, B)**x) == TP(A**x, B**x)
|
| 67 |
+
assert tensor_product_simp(x*TP(A, B)**2) == x*TP(A**2,B**2)
|
| 68 |
+
assert tensor_product_simp(x*(TP(A, B)**2)*TP(C,D)) == x*TP(A**2*C,B**2*D)
|
| 69 |
+
assert tensor_product_simp(TP(A,B)-TP(C,D)**x) == TP(A,B)-TP(C**x,D**x)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def test_issue_5923():
|
| 73 |
+
# most of the issue regarding sympification of args has been handled
|
| 74 |
+
# and is tested internally by the use of args_cnc through the quantum
|
| 75 |
+
# module, but the following is a test from the issue that used to raise.
|
| 76 |
+
assert TensorProduct(1, Qubit('1')*Qubit('1').dual) == \
|
| 77 |
+
TensorProduct(1, OuterProduct(Qubit(1), QubitBra(1)))
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def test_eval_trace():
|
| 81 |
+
# This test includes tests with dependencies between TensorProducts
|
| 82 |
+
#and density operators. Since, the test is more to test the behavior of
|
| 83 |
+
#TensorProducts it remains here
|
| 84 |
+
|
| 85 |
+
A, B, C, D, E, F = symbols('A B C D E F', commutative=False)
|
| 86 |
+
|
| 87 |
+
# Density with simple tensor products as args
|
| 88 |
+
t = TensorProduct(A, B)
|
| 89 |
+
d = Density([t, 1.0])
|
| 90 |
+
tr = Tr(d)
|
| 91 |
+
assert tr.doit() == 1.0*Tr(A*Dagger(A))*Tr(B*Dagger(B))
|
| 92 |
+
|
| 93 |
+
## partial trace with simple tensor products as args
|
| 94 |
+
t = TensorProduct(A, B, C)
|
| 95 |
+
d = Density([t, 1.0])
|
| 96 |
+
tr = Tr(d, [1])
|
| 97 |
+
assert tr.doit() == 1.0*A*Dagger(A)*Tr(B*Dagger(B))*C*Dagger(C)
|
| 98 |
+
|
| 99 |
+
tr = Tr(d, [0, 2])
|
| 100 |
+
assert tr.doit() == 1.0*Tr(A*Dagger(A))*B*Dagger(B)*Tr(C*Dagger(C))
|
| 101 |
+
|
| 102 |
+
# Density with multiple Tensorproducts as states
|
| 103 |
+
t2 = TensorProduct(A, B)
|
| 104 |
+
t3 = TensorProduct(C, D)
|
| 105 |
+
|
| 106 |
+
d = Density([t2, 0.5], [t3, 0.5])
|
| 107 |
+
t = Tr(d)
|
| 108 |
+
assert t.doit() == (0.5*Tr(A*Dagger(A))*Tr(B*Dagger(B)) +
|
| 109 |
+
0.5*Tr(C*Dagger(C))*Tr(D*Dagger(D)))
|
| 110 |
+
|
| 111 |
+
t = Tr(d, [0])
|
| 112 |
+
assert t.doit() == (0.5*Tr(A*Dagger(A))*B*Dagger(B) +
|
| 113 |
+
0.5*Tr(C*Dagger(C))*D*Dagger(D))
|
| 114 |
+
|
| 115 |
+
#Density with mixed states
|
| 116 |
+
d = Density([t2 + t3, 1.0])
|
| 117 |
+
t = Tr(d)
|
| 118 |
+
assert t.doit() == ( 1.0*Tr(A*Dagger(A))*Tr(B*Dagger(B)) +
|
| 119 |
+
1.0*Tr(A*Dagger(C))*Tr(B*Dagger(D)) +
|
| 120 |
+
1.0*Tr(C*Dagger(A))*Tr(D*Dagger(B)) +
|
| 121 |
+
1.0*Tr(C*Dagger(C))*Tr(D*Dagger(D)))
|
| 122 |
+
|
| 123 |
+
t = Tr(d, [1] )
|
| 124 |
+
assert t.doit() == ( 1.0*A*Dagger(A)*Tr(B*Dagger(B)) +
|
| 125 |
+
1.0*A*Dagger(C)*Tr(B*Dagger(D)) +
|
| 126 |
+
1.0*C*Dagger(A)*Tr(D*Dagger(B)) +
|
| 127 |
+
1.0*C*Dagger(C)*Tr(D*Dagger(D)))
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
def test_pr24993():
|
| 131 |
+
from sympy.matrices.expressions.kronecker import matrix_kronecker_product
|
| 132 |
+
from sympy.physics.quantum.matrixutils import matrix_tensor_product
|
| 133 |
+
X = Matrix([[0, 1], [1, 0]])
|
| 134 |
+
Xi = ImmutableMatrix(X)
|
| 135 |
+
assert TensorProduct(Xi, Xi) == TensorProduct(X, X)
|
| 136 |
+
assert TensorProduct(Xi, Xi) == matrix_tensor_product(X, X)
|
| 137 |
+
assert TensorProduct(Xi, Xi) == matrix_kronecker_product(X, X)
|
.venv/Lib/site-packages/sympy/physics/quantum/tests/test_trace.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.containers import Tuple
|
| 2 |
+
from sympy.core.symbol import symbols
|
| 3 |
+
from sympy.matrices.dense import Matrix
|
| 4 |
+
from sympy.physics.quantum.trace import Tr
|
| 5 |
+
from sympy.testing.pytest import raises, warns_deprecated_sympy
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def test_trace_new():
|
| 9 |
+
a, b, c, d, Y = symbols('a b c d Y')
|
| 10 |
+
A, B, C, D = symbols('A B C D', commutative=False)
|
| 11 |
+
|
| 12 |
+
assert Tr(a + b) == a + b
|
| 13 |
+
assert Tr(A + B) == Tr(A) + Tr(B)
|
| 14 |
+
|
| 15 |
+
#check trace args not implicitly permuted
|
| 16 |
+
assert Tr(C*D*A*B).args[0].args == (C, D, A, B)
|
| 17 |
+
|
| 18 |
+
# check for mul and adds
|
| 19 |
+
assert Tr((a*b) + ( c*d)) == (a*b) + (c*d)
|
| 20 |
+
# Tr(scalar*A) = scalar*Tr(A)
|
| 21 |
+
assert Tr(a*A) == a*Tr(A)
|
| 22 |
+
assert Tr(a*A*B*b) == a*b*Tr(A*B)
|
| 23 |
+
|
| 24 |
+
# since A is symbol and not commutative
|
| 25 |
+
assert isinstance(Tr(A), Tr)
|
| 26 |
+
|
| 27 |
+
#POW
|
| 28 |
+
assert Tr(pow(a, b)) == a**b
|
| 29 |
+
assert isinstance(Tr(pow(A, a)), Tr)
|
| 30 |
+
|
| 31 |
+
#Matrix
|
| 32 |
+
M = Matrix([[1, 1], [2, 2]])
|
| 33 |
+
assert Tr(M) == 3
|
| 34 |
+
|
| 35 |
+
##test indices in different forms
|
| 36 |
+
#no index
|
| 37 |
+
t = Tr(A)
|
| 38 |
+
assert t.args[1] == Tuple()
|
| 39 |
+
|
| 40 |
+
#single index
|
| 41 |
+
t = Tr(A, 0)
|
| 42 |
+
assert t.args[1] == Tuple(0)
|
| 43 |
+
|
| 44 |
+
#index in a list
|
| 45 |
+
t = Tr(A, [0])
|
| 46 |
+
assert t.args[1] == Tuple(0)
|
| 47 |
+
|
| 48 |
+
t = Tr(A, [0, 1, 2])
|
| 49 |
+
assert t.args[1] == Tuple(0, 1, 2)
|
| 50 |
+
|
| 51 |
+
#index is tuple
|
| 52 |
+
t = Tr(A, (0))
|
| 53 |
+
assert t.args[1] == Tuple(0)
|
| 54 |
+
|
| 55 |
+
t = Tr(A, (1, 2))
|
| 56 |
+
assert t.args[1] == Tuple(1, 2)
|
| 57 |
+
|
| 58 |
+
#trace indices test
|
| 59 |
+
t = Tr((A + B), [2])
|
| 60 |
+
assert t.args[0].args[1] == Tuple(2) and t.args[1].args[1] == Tuple(2)
|
| 61 |
+
|
| 62 |
+
t = Tr(a*A, [2, 3])
|
| 63 |
+
assert t.args[1].args[1] == Tuple(2, 3)
|
| 64 |
+
|
| 65 |
+
#class with trace method defined
|
| 66 |
+
#to simulate numpy objects
|
| 67 |
+
class Foo:
|
| 68 |
+
def trace(self):
|
| 69 |
+
return 1
|
| 70 |
+
assert Tr(Foo()) == 1
|
| 71 |
+
|
| 72 |
+
#argument test
|
| 73 |
+
# check for value error, when either/both arguments are not provided
|
| 74 |
+
raises(ValueError, lambda: Tr())
|
| 75 |
+
raises(ValueError, lambda: Tr(A, 1, 2))
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
def test_trace_doit():
|
| 79 |
+
a, b, c, d = symbols('a b c d')
|
| 80 |
+
A, B, C, D = symbols('A B C D', commutative=False)
|
| 81 |
+
|
| 82 |
+
#TODO: needed while testing reduced density operations, etc.
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def test_permute():
|
| 86 |
+
A, B, C, D, E, F, G = symbols('A B C D E F G', commutative=False)
|
| 87 |
+
t = Tr(A*B*C*D*E*F*G)
|
| 88 |
+
|
| 89 |
+
assert t.permute(0).args[0].args == (A, B, C, D, E, F, G)
|
| 90 |
+
assert t.permute(2).args[0].args == (F, G, A, B, C, D, E)
|
| 91 |
+
assert t.permute(4).args[0].args == (D, E, F, G, A, B, C)
|
| 92 |
+
assert t.permute(6).args[0].args == (B, C, D, E, F, G, A)
|
| 93 |
+
assert t.permute(8).args[0].args == t.permute(1).args[0].args
|
| 94 |
+
|
| 95 |
+
assert t.permute(-1).args[0].args == (B, C, D, E, F, G, A)
|
| 96 |
+
assert t.permute(-3).args[0].args == (D, E, F, G, A, B, C)
|
| 97 |
+
assert t.permute(-5).args[0].args == (F, G, A, B, C, D, E)
|
| 98 |
+
assert t.permute(-8).args[0].args == t.permute(-1).args[0].args
|
| 99 |
+
|
| 100 |
+
t = Tr((A + B)*(B*B)*C*D)
|
| 101 |
+
assert t.permute(2).args[0].args == (C, D, (A + B), (B**2))
|
| 102 |
+
|
| 103 |
+
t1 = Tr(A*B)
|
| 104 |
+
t2 = t1.permute(1)
|
| 105 |
+
assert id(t1) != id(t2) and t1 == t2
|
| 106 |
+
|
| 107 |
+
def test_deprecated_core_trace():
|
| 108 |
+
with warns_deprecated_sympy():
|
| 109 |
+
from sympy.core.trace import Tr # noqa:F401
|
.venv/Lib/site-packages/sympy/physics/tests/__init__.py
ADDED
|
File without changes
|
.venv/Lib/site-packages/sympy/physics/tests/test_clebsch_gordan.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.numbers import (I, pi, Rational)
|
| 2 |
+
from sympy.core.singleton import S
|
| 3 |
+
from sympy.core.symbol import symbols
|
| 4 |
+
from sympy.functions.elementary.exponential import exp
|
| 5 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 6 |
+
from sympy.functions.elementary.trigonometric import (cos, sin)
|
| 7 |
+
from sympy.functions.special.spherical_harmonics import Ynm
|
| 8 |
+
from sympy.matrices.dense import Matrix
|
| 9 |
+
from sympy.physics.wigner import (clebsch_gordan, wigner_9j, wigner_6j, gaunt,
|
| 10 |
+
real_gaunt, racah, dot_rot_grad_Ynm, wigner_3j, wigner_d_small, wigner_d)
|
| 11 |
+
from sympy.testing.pytest import raises
|
| 12 |
+
|
| 13 |
+
# for test cases, refer : https://en.wikipedia.org/wiki/Table_of_Clebsch%E2%80%93Gordan_coefficients
|
| 14 |
+
|
| 15 |
+
def test_clebsch_gordan_docs():
|
| 16 |
+
assert clebsch_gordan(Rational(3, 2), S.Half, 2, Rational(3, 2), S.Half, 2) == 1
|
| 17 |
+
assert clebsch_gordan(Rational(3, 2), S.Half, 1, Rational(3, 2), Rational(-1, 2), 1) == sqrt(3)/2
|
| 18 |
+
assert clebsch_gordan(Rational(3, 2), S.Half, 1, Rational(-1, 2), S.Half, 0) == -sqrt(2)/2
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def test_clebsch_gordan():
|
| 22 |
+
# Argument order: (j_1, j_2, j, m_1, m_2, m)
|
| 23 |
+
|
| 24 |
+
h = S.One
|
| 25 |
+
k = S.Half
|
| 26 |
+
l = Rational(3, 2)
|
| 27 |
+
i = Rational(-1, 2)
|
| 28 |
+
n = Rational(7, 2)
|
| 29 |
+
p = Rational(5, 2)
|
| 30 |
+
assert clebsch_gordan(k, k, 1, k, k, 1) == 1
|
| 31 |
+
assert clebsch_gordan(k, k, 1, k, k, 0) == 0
|
| 32 |
+
assert clebsch_gordan(k, k, 1, i, i, -1) == 1
|
| 33 |
+
assert clebsch_gordan(k, k, 1, k, i, 0) == sqrt(2)/2
|
| 34 |
+
assert clebsch_gordan(k, k, 0, k, i, 0) == sqrt(2)/2
|
| 35 |
+
assert clebsch_gordan(k, k, 1, i, k, 0) == sqrt(2)/2
|
| 36 |
+
assert clebsch_gordan(k, k, 0, i, k, 0) == -sqrt(2)/2
|
| 37 |
+
assert clebsch_gordan(h, k, l, 1, k, l) == 1
|
| 38 |
+
assert clebsch_gordan(h, k, l, 1, i, k) == 1/sqrt(3)
|
| 39 |
+
assert clebsch_gordan(h, k, k, 1, i, k) == sqrt(2)/sqrt(3)
|
| 40 |
+
assert clebsch_gordan(h, k, k, 0, k, k) == -1/sqrt(3)
|
| 41 |
+
assert clebsch_gordan(h, k, l, 0, k, k) == sqrt(2)/sqrt(3)
|
| 42 |
+
assert clebsch_gordan(h, h, S(2), 1, 1, S(2)) == 1
|
| 43 |
+
assert clebsch_gordan(h, h, S(2), 1, 0, 1) == 1/sqrt(2)
|
| 44 |
+
assert clebsch_gordan(h, h, S(2), 0, 1, 1) == 1/sqrt(2)
|
| 45 |
+
assert clebsch_gordan(h, h, 1, 1, 0, 1) == 1/sqrt(2)
|
| 46 |
+
assert clebsch_gordan(h, h, 1, 0, 1, 1) == -1/sqrt(2)
|
| 47 |
+
assert clebsch_gordan(l, l, S(3), l, l, S(3)) == 1
|
| 48 |
+
assert clebsch_gordan(l, l, S(2), l, k, S(2)) == 1/sqrt(2)
|
| 49 |
+
assert clebsch_gordan(l, l, S(3), l, k, S(2)) == 1/sqrt(2)
|
| 50 |
+
assert clebsch_gordan(S(2), S(2), S(4), S(2), S(2), S(4)) == 1
|
| 51 |
+
assert clebsch_gordan(S(2), S(2), S(3), S(2), 1, S(3)) == 1/sqrt(2)
|
| 52 |
+
assert clebsch_gordan(S(2), S(2), S(3), 1, 1, S(2)) == 0
|
| 53 |
+
assert clebsch_gordan(p, h, n, p, 1, n) == 1
|
| 54 |
+
assert clebsch_gordan(p, h, p, p, 0, p) == sqrt(5)/sqrt(7)
|
| 55 |
+
assert clebsch_gordan(p, h, l, k, 1, l) == 1/sqrt(15)
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def test_wigner():
|
| 59 |
+
def tn(a, b):
|
| 60 |
+
return (a - b).n(64) < S('1e-64')
|
| 61 |
+
assert tn(wigner_9j(1, 1, 1, 1, 1, 1, 1, 1, 0, prec=64), Rational(1, 18))
|
| 62 |
+
assert wigner_9j(3, 3, 2, 3, 3, 2, 3, 3, 2) == 3221*sqrt(
|
| 63 |
+
70)/(246960*sqrt(105)) - 365/(3528*sqrt(70)*sqrt(105))
|
| 64 |
+
assert wigner_6j(5, 5, 5, 5, 5, 5) == Rational(1, 52)
|
| 65 |
+
assert tn(wigner_6j(8, 8, 8, 8, 8, 8, prec=64), Rational(-12219, 965770))
|
| 66 |
+
# regression test for #8747
|
| 67 |
+
half = S.Half
|
| 68 |
+
assert wigner_9j(0, 0, 0, 0, half, half, 0, half, half) == half
|
| 69 |
+
assert (wigner_9j(3, 5, 4,
|
| 70 |
+
7 * half, 5 * half, 4,
|
| 71 |
+
9 * half, 9 * half, 0)
|
| 72 |
+
== -sqrt(Rational(361, 205821000)))
|
| 73 |
+
assert (wigner_9j(1, 4, 3,
|
| 74 |
+
5 * half, 4, 5 * half,
|
| 75 |
+
5 * half, 2, 7 * half)
|
| 76 |
+
== -sqrt(Rational(3971, 373403520)))
|
| 77 |
+
assert (wigner_9j(4, 9 * half, 5 * half,
|
| 78 |
+
2, 4, 4,
|
| 79 |
+
5, 7 * half, 7 * half)
|
| 80 |
+
== -sqrt(Rational(3481, 5042614500)))
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def test_gaunt():
|
| 84 |
+
def tn(a, b):
|
| 85 |
+
return (a - b).n(64) < S('1e-64')
|
| 86 |
+
assert gaunt(1, 0, 1, 1, 0, -1) == -1/(2*sqrt(pi))
|
| 87 |
+
assert isinstance(gaunt(1, 1, 0, -1, 1, 0).args[0], Rational)
|
| 88 |
+
assert isinstance(gaunt(0, 1, 1, 0, -1, 1).args[0], Rational)
|
| 89 |
+
|
| 90 |
+
assert tn(gaunt(
|
| 91 |
+
10, 10, 12, 9, 3, -12, prec=64), (Rational(-98, 62031)) * sqrt(6279)/sqrt(pi))
|
| 92 |
+
def gaunt_ref(l1, l2, l3, m1, m2, m3):
|
| 93 |
+
return (
|
| 94 |
+
sqrt((2 * l1 + 1) * (2 * l2 + 1) * (2 * l3 + 1) / (4 * pi)) *
|
| 95 |
+
wigner_3j(l1, l2, l3, 0, 0, 0) *
|
| 96 |
+
wigner_3j(l1, l2, l3, m1, m2, m3)
|
| 97 |
+
)
|
| 98 |
+
threshold = 1e-10
|
| 99 |
+
l_max = 3
|
| 100 |
+
l3_max = 24
|
| 101 |
+
for l1 in range(l_max + 1):
|
| 102 |
+
for l2 in range(l_max + 1):
|
| 103 |
+
for l3 in range(l3_max + 1):
|
| 104 |
+
for m1 in range(-l1, l1 + 1):
|
| 105 |
+
for m2 in range(-l2, l2 + 1):
|
| 106 |
+
for m3 in range(-l3, l3 + 1):
|
| 107 |
+
args = l1, l2, l3, m1, m2, m3
|
| 108 |
+
g = gaunt(*args)
|
| 109 |
+
g0 = gaunt_ref(*args)
|
| 110 |
+
assert abs(g - g0) < threshold
|
| 111 |
+
if m1 + m2 + m3 != 0:
|
| 112 |
+
assert abs(g) < threshold
|
| 113 |
+
if (l1 + l2 + l3) % 2:
|
| 114 |
+
assert abs(g) < threshold
|
| 115 |
+
assert gaunt(1, 1, 0, 0, 2, -2) is S.Zero
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def test_realgaunt():
|
| 119 |
+
# All non-zero values corresponding to l values from 0 to 2
|
| 120 |
+
for l in range(3):
|
| 121 |
+
for m in range(-l, l+1):
|
| 122 |
+
assert real_gaunt(0, l, l, 0, m, m) == 1/(2*sqrt(pi))
|
| 123 |
+
assert real_gaunt(1, 1, 2, 0, 0, 0) == sqrt(5)/(5*sqrt(pi))
|
| 124 |
+
assert real_gaunt(1, 1, 2, 1, 1, 0) == -sqrt(5)/(10*sqrt(pi))
|
| 125 |
+
assert real_gaunt(2, 2, 2, 0, 0, 0) == sqrt(5)/(7*sqrt(pi))
|
| 126 |
+
assert real_gaunt(2, 2, 2, 0, 2, 2) == -sqrt(5)/(7*sqrt(pi))
|
| 127 |
+
assert real_gaunt(2, 2, 2, -2, -2, 0) == -sqrt(5)/(7*sqrt(pi))
|
| 128 |
+
assert real_gaunt(1, 1, 2, -1, 0, -1) == sqrt(15)/(10*sqrt(pi))
|
| 129 |
+
assert real_gaunt(1, 1, 2, 0, 1, 1) == sqrt(15)/(10*sqrt(pi))
|
| 130 |
+
assert real_gaunt(1, 1, 2, 1, 1, 2) == sqrt(15)/(10*sqrt(pi))
|
| 131 |
+
assert real_gaunt(1, 1, 2, -1, 1, -2) == -sqrt(15)/(10*sqrt(pi))
|
| 132 |
+
assert real_gaunt(1, 1, 2, -1, -1, 2) == -sqrt(15)/(10*sqrt(pi))
|
| 133 |
+
assert real_gaunt(2, 2, 2, 0, 1, 1) == sqrt(5)/(14*sqrt(pi))
|
| 134 |
+
assert real_gaunt(2, 2, 2, 1, 1, 2) == sqrt(15)/(14*sqrt(pi))
|
| 135 |
+
assert real_gaunt(2, 2, 2, -1, -1, 2) == -sqrt(15)/(14*sqrt(pi))
|
| 136 |
+
|
| 137 |
+
assert real_gaunt(-2, -2, -2, -2, -2, 0) is S.Zero # m test
|
| 138 |
+
assert real_gaunt(-2, 1, 0, 1, 1, 1) is S.Zero # l test
|
| 139 |
+
assert real_gaunt(-2, -1, -2, -1, -1, 0) is S.Zero # m and l test
|
| 140 |
+
assert real_gaunt(-2, -2, -2, -2, -2, -2) is S.Zero # m and k test
|
| 141 |
+
assert real_gaunt(-2, -1, -2, -1, -1, -1) is S.Zero # m, l and k test
|
| 142 |
+
|
| 143 |
+
x = symbols('x', integer=True)
|
| 144 |
+
v = [0]*6
|
| 145 |
+
for i in range(len(v)):
|
| 146 |
+
v[i] = x # non literal ints fail
|
| 147 |
+
raises(ValueError, lambda: real_gaunt(*v))
|
| 148 |
+
v[i] = 0
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
def test_racah():
|
| 152 |
+
assert racah(3,3,3,3,3,3) == Rational(-1,14)
|
| 153 |
+
assert racah(2,2,2,2,2,2) == Rational(-3,70)
|
| 154 |
+
assert racah(7,8,7,1,7,7, prec=4).is_Float
|
| 155 |
+
assert racah(5.5,7.5,9.5,6.5,8,9) == -719*sqrt(598)/1158924
|
| 156 |
+
assert abs(racah(5.5,7.5,9.5,6.5,8,9, prec=4) - (-0.01517)) < S('1e-4')
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def test_dot_rota_grad_SH():
|
| 160 |
+
theta, phi = symbols("theta phi")
|
| 161 |
+
assert dot_rot_grad_Ynm(1, 1, 1, 1, 1, 0) != \
|
| 162 |
+
sqrt(30)*Ynm(2, 2, 1, 0)/(10*sqrt(pi))
|
| 163 |
+
assert dot_rot_grad_Ynm(1, 1, 1, 1, 1, 0).doit() == \
|
| 164 |
+
sqrt(30)*Ynm(2, 2, 1, 0)/(10*sqrt(pi))
|
| 165 |
+
assert dot_rot_grad_Ynm(1, 5, 1, 1, 1, 2) != \
|
| 166 |
+
0
|
| 167 |
+
assert dot_rot_grad_Ynm(1, 5, 1, 1, 1, 2).doit() == \
|
| 168 |
+
0
|
| 169 |
+
assert dot_rot_grad_Ynm(3, 3, 3, 3, theta, phi).doit() == \
|
| 170 |
+
15*sqrt(3003)*Ynm(6, 6, theta, phi)/(143*sqrt(pi))
|
| 171 |
+
assert dot_rot_grad_Ynm(3, 3, 1, 1, theta, phi).doit() == \
|
| 172 |
+
sqrt(3)*Ynm(4, 4, theta, phi)/sqrt(pi)
|
| 173 |
+
assert dot_rot_grad_Ynm(3, 2, 2, 0, theta, phi).doit() == \
|
| 174 |
+
3*sqrt(55)*Ynm(5, 2, theta, phi)/(11*sqrt(pi))
|
| 175 |
+
assert dot_rot_grad_Ynm(3, 2, 3, 2, theta, phi).doit().expand() == \
|
| 176 |
+
-sqrt(70)*Ynm(4, 4, theta, phi)/(11*sqrt(pi)) + \
|
| 177 |
+
45*sqrt(182)*Ynm(6, 4, theta, phi)/(143*sqrt(pi))
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
def test_wigner_d():
|
| 181 |
+
half = S(1)/2
|
| 182 |
+
assert wigner_d_small(half, 0) == Matrix([[1, 0], [0, 1]])
|
| 183 |
+
assert wigner_d_small(half, pi/2) == Matrix([[1, 1], [-1, 1]])/sqrt(2)
|
| 184 |
+
assert wigner_d_small(half, pi) == Matrix([[0, 1], [-1, 0]])
|
| 185 |
+
|
| 186 |
+
alpha, beta, gamma = symbols("alpha, beta, gamma", real=True)
|
| 187 |
+
D = wigner_d(half, alpha, beta, gamma)
|
| 188 |
+
assert D[0, 0] == exp(I*alpha/2)*exp(I*gamma/2)*cos(beta/2)
|
| 189 |
+
assert D[0, 1] == exp(I*alpha/2)*exp(-I*gamma/2)*sin(beta/2)
|
| 190 |
+
assert D[1, 0] == -exp(-I*alpha/2)*exp(I*gamma/2)*sin(beta/2)
|
| 191 |
+
assert D[1, 1] == exp(-I*alpha/2)*exp(-I*gamma/2)*cos(beta/2)
|
| 192 |
+
|
| 193 |
+
# Test Y_{n mi}(g*x)=\sum_{mj}D^n_{mi mj}*Y_{n mj}(x)
|
| 194 |
+
theta, phi = symbols("theta phi", real=True)
|
| 195 |
+
v = Matrix([Ynm(1, mj, theta, phi) for mj in range(1, -2, -1)])
|
| 196 |
+
w = wigner_d(1, -pi/2, pi/2, -pi/2)@v.subs({theta: pi/4, phi: pi})
|
| 197 |
+
w_ = v.subs({theta: pi/2, phi: pi/4})
|
| 198 |
+
assert w.expand(func=True).as_real_imag() == w_.expand(func=True).as_real_imag()
|
.venv/Lib/site-packages/sympy/physics/tests/test_hydrogen.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.numbers import (I, Rational, oo, pi)
|
| 2 |
+
from sympy.core.singleton import S
|
| 3 |
+
from sympy.core.symbol import symbols
|
| 4 |
+
from sympy.functions.elementary.exponential import exp
|
| 5 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 6 |
+
from sympy.functions.elementary.trigonometric import (cos, sin)
|
| 7 |
+
from sympy.integrals.integrals import integrate
|
| 8 |
+
from sympy.simplify.simplify import simplify
|
| 9 |
+
from sympy.physics.hydrogen import R_nl, E_nl, E_nl_dirac, Psi_nlm
|
| 10 |
+
from sympy.testing.pytest import raises
|
| 11 |
+
|
| 12 |
+
n, r, Z = symbols('n r Z')
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def feq(a, b, max_relative_error=1e-12, max_absolute_error=1e-12):
|
| 16 |
+
a = float(a)
|
| 17 |
+
b = float(b)
|
| 18 |
+
# if the numbers are close enough (absolutely), then they are equal
|
| 19 |
+
if abs(a - b) < max_absolute_error:
|
| 20 |
+
return True
|
| 21 |
+
# if not, they can still be equal if their relative error is small
|
| 22 |
+
if abs(b) > abs(a):
|
| 23 |
+
relative_error = abs((a - b)/b)
|
| 24 |
+
else:
|
| 25 |
+
relative_error = abs((a - b)/a)
|
| 26 |
+
return relative_error <= max_relative_error
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def test_wavefunction():
|
| 30 |
+
a = 1/Z
|
| 31 |
+
R = {
|
| 32 |
+
(1, 0): 2*sqrt(1/a**3) * exp(-r/a),
|
| 33 |
+
(2, 0): sqrt(1/(2*a**3)) * exp(-r/(2*a)) * (1 - r/(2*a)),
|
| 34 |
+
(2, 1): S.Half * sqrt(1/(6*a**3)) * exp(-r/(2*a)) * r/a,
|
| 35 |
+
(3, 0): Rational(2, 3) * sqrt(1/(3*a**3)) * exp(-r/(3*a)) *
|
| 36 |
+
(1 - 2*r/(3*a) + Rational(2, 27) * (r/a)**2),
|
| 37 |
+
(3, 1): Rational(4, 27) * sqrt(2/(3*a**3)) * exp(-r/(3*a)) *
|
| 38 |
+
(1 - r/(6*a)) * r/a,
|
| 39 |
+
(3, 2): Rational(2, 81) * sqrt(2/(15*a**3)) * exp(-r/(3*a)) * (r/a)**2,
|
| 40 |
+
(4, 0): Rational(1, 4) * sqrt(1/a**3) * exp(-r/(4*a)) *
|
| 41 |
+
(1 - 3*r/(4*a) + Rational(1, 8) * (r/a)**2 - Rational(1, 192) * (r/a)**3),
|
| 42 |
+
(4, 1): Rational(1, 16) * sqrt(5/(3*a**3)) * exp(-r/(4*a)) *
|
| 43 |
+
(1 - r/(4*a) + Rational(1, 80) * (r/a)**2) * (r/a),
|
| 44 |
+
(4, 2): Rational(1, 64) * sqrt(1/(5*a**3)) * exp(-r/(4*a)) *
|
| 45 |
+
(1 - r/(12*a)) * (r/a)**2,
|
| 46 |
+
(4, 3): Rational(1, 768) * sqrt(1/(35*a**3)) * exp(-r/(4*a)) * (r/a)**3,
|
| 47 |
+
}
|
| 48 |
+
for n, l in R:
|
| 49 |
+
assert simplify(R_nl(n, l, r, Z) - R[(n, l)]) == 0
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def test_norm():
|
| 53 |
+
# Maximum "n" which is tested:
|
| 54 |
+
n_max = 2 # it works, but is slow, for n_max > 2
|
| 55 |
+
for n in range(n_max + 1):
|
| 56 |
+
for l in range(n):
|
| 57 |
+
assert integrate(R_nl(n, l, r)**2 * r**2, (r, 0, oo)) == 1
|
| 58 |
+
|
| 59 |
+
def test_psi_nlm():
|
| 60 |
+
r=S('r')
|
| 61 |
+
phi=S('phi')
|
| 62 |
+
theta=S('theta')
|
| 63 |
+
assert (Psi_nlm(1, 0, 0, r, phi, theta) == exp(-r) / sqrt(pi))
|
| 64 |
+
assert (Psi_nlm(2, 1, -1, r, phi, theta)) == S.Half * exp(-r / (2)) * r \
|
| 65 |
+
* (sin(theta) * exp(-I * phi) / (4 * sqrt(pi)))
|
| 66 |
+
assert (Psi_nlm(3, 2, 1, r, phi, theta, 2) == -sqrt(2) * sin(theta) \
|
| 67 |
+
* exp(I * phi) * cos(theta) / (4 * sqrt(pi)) * S(2) / 81 \
|
| 68 |
+
* sqrt(2 * 2 ** 3) * exp(-2 * r / (3)) * (r * 2) ** 2)
|
| 69 |
+
|
| 70 |
+
def test_hydrogen_energies():
|
| 71 |
+
assert E_nl(n, Z) == -Z**2/(2*n**2)
|
| 72 |
+
assert E_nl(n) == -1/(2*n**2)
|
| 73 |
+
|
| 74 |
+
assert E_nl(1, 47) == -S(47)**2/(2*1**2)
|
| 75 |
+
assert E_nl(2, 47) == -S(47)**2/(2*2**2)
|
| 76 |
+
|
| 77 |
+
assert E_nl(1) == -S.One/(2*1**2)
|
| 78 |
+
assert E_nl(2) == -S.One/(2*2**2)
|
| 79 |
+
assert E_nl(3) == -S.One/(2*3**2)
|
| 80 |
+
assert E_nl(4) == -S.One/(2*4**2)
|
| 81 |
+
assert E_nl(100) == -S.One/(2*100**2)
|
| 82 |
+
|
| 83 |
+
raises(ValueError, lambda: E_nl(0))
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def test_hydrogen_energies_relat():
|
| 87 |
+
# First test exact formulas for small "c" so that we get nice expressions:
|
| 88 |
+
assert E_nl_dirac(2, 0, Z=1, c=1) == 1/sqrt(2) - 1
|
| 89 |
+
assert simplify(E_nl_dirac(2, 0, Z=1, c=2) - ( (8*sqrt(3) + 16)
|
| 90 |
+
/ sqrt(16*sqrt(3) + 32) - 4)) == 0
|
| 91 |
+
assert simplify(E_nl_dirac(2, 0, Z=1, c=3) - ( (54*sqrt(2) + 81)
|
| 92 |
+
/ sqrt(108*sqrt(2) + 162) - 9)) == 0
|
| 93 |
+
|
| 94 |
+
# Now test for almost the correct speed of light, without floating point
|
| 95 |
+
# numbers:
|
| 96 |
+
assert simplify(E_nl_dirac(2, 0, Z=1, c=137) - ( (352275361 + 10285412 *
|
| 97 |
+
sqrt(1173)) / sqrt(704550722 + 20570824 * sqrt(1173)) - 18769)) == 0
|
| 98 |
+
assert simplify(E_nl_dirac(2, 0, Z=82, c=137) - ( (352275361 + 2571353 *
|
| 99 |
+
sqrt(12045)) / sqrt(704550722 + 5142706*sqrt(12045)) - 18769)) == 0
|
| 100 |
+
|
| 101 |
+
# Test using exact speed of light, and compare against the nonrelativistic
|
| 102 |
+
# energies:
|
| 103 |
+
for n in range(1, 5):
|
| 104 |
+
for l in range(n):
|
| 105 |
+
assert feq(E_nl_dirac(n, l), E_nl(n), 1e-5, 1e-5)
|
| 106 |
+
if l > 0:
|
| 107 |
+
assert feq(E_nl_dirac(n, l, False), E_nl(n), 1e-5, 1e-5)
|
| 108 |
+
|
| 109 |
+
Z = 2
|
| 110 |
+
for n in range(1, 5):
|
| 111 |
+
for l in range(n):
|
| 112 |
+
assert feq(E_nl_dirac(n, l, Z=Z), E_nl(n, Z), 1e-4, 1e-4)
|
| 113 |
+
if l > 0:
|
| 114 |
+
assert feq(E_nl_dirac(n, l, False, Z), E_nl(n, Z), 1e-4, 1e-4)
|
| 115 |
+
|
| 116 |
+
Z = 3
|
| 117 |
+
for n in range(1, 5):
|
| 118 |
+
for l in range(n):
|
| 119 |
+
assert feq(E_nl_dirac(n, l, Z=Z), E_nl(n, Z), 1e-3, 1e-3)
|
| 120 |
+
if l > 0:
|
| 121 |
+
assert feq(E_nl_dirac(n, l, False, Z), E_nl(n, Z), 1e-3, 1e-3)
|
| 122 |
+
|
| 123 |
+
# Test the exceptions:
|
| 124 |
+
raises(ValueError, lambda: E_nl_dirac(0, 0))
|
| 125 |
+
raises(ValueError, lambda: E_nl_dirac(1, -1))
|
| 126 |
+
raises(ValueError, lambda: E_nl_dirac(1, 0, False))
|
.venv/Lib/site-packages/sympy/physics/tests/test_paulialgebra.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.numbers import I
|
| 2 |
+
from sympy.core.symbol import symbols
|
| 3 |
+
from sympy.physics.paulialgebra import Pauli
|
| 4 |
+
from sympy.testing.pytest import XFAIL
|
| 5 |
+
from sympy.physics.quantum import TensorProduct
|
| 6 |
+
|
| 7 |
+
sigma1 = Pauli(1)
|
| 8 |
+
sigma2 = Pauli(2)
|
| 9 |
+
sigma3 = Pauli(3)
|
| 10 |
+
|
| 11 |
+
tau1 = symbols("tau1", commutative = False)
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def test_Pauli():
|
| 15 |
+
|
| 16 |
+
assert sigma1 == sigma1
|
| 17 |
+
assert sigma1 != sigma2
|
| 18 |
+
|
| 19 |
+
assert sigma1*sigma2 == I*sigma3
|
| 20 |
+
assert sigma3*sigma1 == I*sigma2
|
| 21 |
+
assert sigma2*sigma3 == I*sigma1
|
| 22 |
+
|
| 23 |
+
assert sigma1*sigma1 == 1
|
| 24 |
+
assert sigma2*sigma2 == 1
|
| 25 |
+
assert sigma3*sigma3 == 1
|
| 26 |
+
|
| 27 |
+
assert sigma1**0 == 1
|
| 28 |
+
assert sigma1**1 == sigma1
|
| 29 |
+
assert sigma1**2 == 1
|
| 30 |
+
assert sigma1**3 == sigma1
|
| 31 |
+
assert sigma1**4 == 1
|
| 32 |
+
|
| 33 |
+
assert sigma3**2 == 1
|
| 34 |
+
|
| 35 |
+
assert sigma1*2*sigma1 == 2
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def test_evaluate_pauli_product():
|
| 39 |
+
from sympy.physics.paulialgebra import evaluate_pauli_product
|
| 40 |
+
|
| 41 |
+
assert evaluate_pauli_product(I*sigma2*sigma3) == -sigma1
|
| 42 |
+
|
| 43 |
+
# Check issue 6471
|
| 44 |
+
assert evaluate_pauli_product(-I*4*sigma1*sigma2) == 4*sigma3
|
| 45 |
+
|
| 46 |
+
assert evaluate_pauli_product(
|
| 47 |
+
1 + I*sigma1*sigma2*sigma1*sigma2 + \
|
| 48 |
+
I*sigma1*sigma2*tau1*sigma1*sigma3 + \
|
| 49 |
+
((tau1**2).subs(tau1, I*sigma1)) + \
|
| 50 |
+
sigma3*((tau1**2).subs(tau1, I*sigma1)) + \
|
| 51 |
+
TensorProduct(I*sigma1*sigma2*sigma1*sigma2, 1)
|
| 52 |
+
) == 1 -I + I*sigma3*tau1*sigma2 - 1 - sigma3 - I*TensorProduct(1,1)
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
@XFAIL
|
| 56 |
+
def test_Pauli_should_work():
|
| 57 |
+
assert sigma1*sigma3*sigma1 == -sigma3
|
.venv/Lib/site-packages/sympy/physics/tests/test_physics_matrices.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.physics.matrices import msigma, mgamma, minkowski_tensor, pat_matrix, mdft
|
| 2 |
+
from sympy.core.numbers import (I, Rational)
|
| 3 |
+
from sympy.core.singleton import S
|
| 4 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 5 |
+
from sympy.matrices.dense import (Matrix, eye, zeros)
|
| 6 |
+
from sympy.testing.pytest import warns_deprecated_sympy
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def test_parallel_axis_theorem():
|
| 10 |
+
# This tests the parallel axis theorem matrix by comparing to test
|
| 11 |
+
# matrices.
|
| 12 |
+
|
| 13 |
+
# First case, 1 in all directions.
|
| 14 |
+
mat1 = Matrix(((2, -1, -1), (-1, 2, -1), (-1, -1, 2)))
|
| 15 |
+
assert pat_matrix(1, 1, 1, 1) == mat1
|
| 16 |
+
assert pat_matrix(2, 1, 1, 1) == 2*mat1
|
| 17 |
+
|
| 18 |
+
# Second case, 1 in x, 0 in all others
|
| 19 |
+
mat2 = Matrix(((0, 0, 0), (0, 1, 0), (0, 0, 1)))
|
| 20 |
+
assert pat_matrix(1, 1, 0, 0) == mat2
|
| 21 |
+
assert pat_matrix(2, 1, 0, 0) == 2*mat2
|
| 22 |
+
|
| 23 |
+
# Third case, 1 in y, 0 in all others
|
| 24 |
+
mat3 = Matrix(((1, 0, 0), (0, 0, 0), (0, 0, 1)))
|
| 25 |
+
assert pat_matrix(1, 0, 1, 0) == mat3
|
| 26 |
+
assert pat_matrix(2, 0, 1, 0) == 2*mat3
|
| 27 |
+
|
| 28 |
+
# Fourth case, 1 in z, 0 in all others
|
| 29 |
+
mat4 = Matrix(((1, 0, 0), (0, 1, 0), (0, 0, 0)))
|
| 30 |
+
assert pat_matrix(1, 0, 0, 1) == mat4
|
| 31 |
+
assert pat_matrix(2, 0, 0, 1) == 2*mat4
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def test_Pauli():
|
| 35 |
+
#this and the following test are testing both Pauli and Dirac matrices
|
| 36 |
+
#and also that the general Matrix class works correctly in a real world
|
| 37 |
+
#situation
|
| 38 |
+
sigma1 = msigma(1)
|
| 39 |
+
sigma2 = msigma(2)
|
| 40 |
+
sigma3 = msigma(3)
|
| 41 |
+
|
| 42 |
+
assert sigma1 == sigma1
|
| 43 |
+
assert sigma1 != sigma2
|
| 44 |
+
|
| 45 |
+
# sigma*I -> I*sigma (see #354)
|
| 46 |
+
assert sigma1*sigma2 == sigma3*I
|
| 47 |
+
assert sigma3*sigma1 == sigma2*I
|
| 48 |
+
assert sigma2*sigma3 == sigma1*I
|
| 49 |
+
|
| 50 |
+
assert sigma1*sigma1 == eye(2)
|
| 51 |
+
assert sigma2*sigma2 == eye(2)
|
| 52 |
+
assert sigma3*sigma3 == eye(2)
|
| 53 |
+
|
| 54 |
+
assert sigma1*2*sigma1 == 2*eye(2)
|
| 55 |
+
assert sigma1*sigma3*sigma1 == -sigma3
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def test_Dirac():
|
| 59 |
+
gamma0 = mgamma(0)
|
| 60 |
+
gamma1 = mgamma(1)
|
| 61 |
+
gamma2 = mgamma(2)
|
| 62 |
+
gamma3 = mgamma(3)
|
| 63 |
+
gamma5 = mgamma(5)
|
| 64 |
+
|
| 65 |
+
# gamma*I -> I*gamma (see #354)
|
| 66 |
+
assert gamma5 == gamma0 * gamma1 * gamma2 * gamma3 * I
|
| 67 |
+
assert gamma1 * gamma2 + gamma2 * gamma1 == zeros(4)
|
| 68 |
+
assert gamma0 * gamma0 == eye(4) * minkowski_tensor[0, 0]
|
| 69 |
+
assert gamma2 * gamma2 != eye(4) * minkowski_tensor[0, 0]
|
| 70 |
+
assert gamma2 * gamma2 == eye(4) * minkowski_tensor[2, 2]
|
| 71 |
+
|
| 72 |
+
assert mgamma(5, True) == \
|
| 73 |
+
mgamma(0, True)*mgamma(1, True)*mgamma(2, True)*mgamma(3, True)*I
|
| 74 |
+
|
| 75 |
+
def test_mdft():
|
| 76 |
+
with warns_deprecated_sympy():
|
| 77 |
+
assert mdft(1) == Matrix([[1]])
|
| 78 |
+
with warns_deprecated_sympy():
|
| 79 |
+
assert mdft(2) == 1/sqrt(2)*Matrix([[1,1],[1,-1]])
|
| 80 |
+
with warns_deprecated_sympy():
|
| 81 |
+
assert mdft(4) == Matrix([[S.Half, S.Half, S.Half, S.Half],
|
| 82 |
+
[S.Half, -I/2, Rational(-1,2), I/2],
|
| 83 |
+
[S.Half, Rational(-1,2), S.Half, Rational(-1,2)],
|
| 84 |
+
[S.Half, I/2, Rational(-1,2), -I/2]])
|
.venv/Lib/site-packages/sympy/physics/tests/test_pring.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.physics.pring import wavefunction, energy
|
| 2 |
+
from sympy.core.numbers import (I, pi)
|
| 3 |
+
from sympy.functions.elementary.exponential import exp
|
| 4 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 5 |
+
from sympy.integrals.integrals import integrate
|
| 6 |
+
from sympy.simplify.simplify import simplify
|
| 7 |
+
from sympy.abc import m, x, r
|
| 8 |
+
from sympy.physics.quantum.constants import hbar
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def test_wavefunction():
|
| 12 |
+
Psi = {
|
| 13 |
+
0: (1/sqrt(2 * pi)),
|
| 14 |
+
1: (1/sqrt(2 * pi)) * exp(I * x),
|
| 15 |
+
2: (1/sqrt(2 * pi)) * exp(2 * I * x),
|
| 16 |
+
3: (1/sqrt(2 * pi)) * exp(3 * I * x)
|
| 17 |
+
}
|
| 18 |
+
for n in Psi:
|
| 19 |
+
assert simplify(wavefunction(n, x) - Psi[n]) == 0
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def test_norm(n=1):
|
| 23 |
+
# Maximum "n" which is tested:
|
| 24 |
+
for i in range(n + 1):
|
| 25 |
+
assert integrate(
|
| 26 |
+
wavefunction(i, x) * wavefunction(-i, x), (x, 0, 2 * pi)) == 1
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def test_orthogonality(n=1):
|
| 30 |
+
# Maximum "n" which is tested:
|
| 31 |
+
for i in range(n + 1):
|
| 32 |
+
for j in range(i+1, n+1):
|
| 33 |
+
assert integrate(
|
| 34 |
+
wavefunction(i, x) * wavefunction(j, x), (x, 0, 2 * pi)) == 0
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def test_energy(n=1):
|
| 38 |
+
# Maximum "n" which is tested:
|
| 39 |
+
for i in range(n+1):
|
| 40 |
+
assert simplify(
|
| 41 |
+
energy(i, m, r) - ((i**2 * hbar**2) / (2 * m * r**2))) == 0
|
.venv/Lib/site-packages/sympy/physics/tests/test_qho_1d.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.numbers import (Rational, oo, pi)
|
| 2 |
+
from sympy.core.singleton import S
|
| 3 |
+
from sympy.core.symbol import Symbol
|
| 4 |
+
from sympy.functions.elementary.exponential import exp
|
| 5 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 6 |
+
from sympy.integrals.integrals import integrate
|
| 7 |
+
from sympy.simplify.simplify import simplify
|
| 8 |
+
from sympy.abc import omega, m, x
|
| 9 |
+
from sympy.physics.qho_1d import psi_n, E_n, coherent_state
|
| 10 |
+
from sympy.physics.quantum.constants import hbar
|
| 11 |
+
|
| 12 |
+
nu = m * omega / hbar
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def test_wavefunction():
|
| 16 |
+
Psi = {
|
| 17 |
+
0: (nu/pi)**Rational(1, 4) * exp(-nu * x**2 /2),
|
| 18 |
+
1: (nu/pi)**Rational(1, 4) * sqrt(2*nu) * x * exp(-nu * x**2 /2),
|
| 19 |
+
2: (nu/pi)**Rational(1, 4) * (2 * nu * x**2 - 1)/sqrt(2) * exp(-nu * x**2 /2),
|
| 20 |
+
3: (nu/pi)**Rational(1, 4) * sqrt(nu/3) * (2 * nu * x**3 - 3 * x) * exp(-nu * x**2 /2)
|
| 21 |
+
}
|
| 22 |
+
for n in Psi:
|
| 23 |
+
assert simplify(psi_n(n, x, m, omega) - Psi[n]) == 0
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def test_norm(n=1):
|
| 27 |
+
# Maximum "n" which is tested:
|
| 28 |
+
for i in range(n + 1):
|
| 29 |
+
assert integrate(psi_n(i, x, 1, 1)**2, (x, -oo, oo)) == 1
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def test_orthogonality(n=1):
|
| 33 |
+
# Maximum "n" which is tested:
|
| 34 |
+
for i in range(n + 1):
|
| 35 |
+
for j in range(i + 1, n + 1):
|
| 36 |
+
assert integrate(
|
| 37 |
+
psi_n(i, x, 1, 1)*psi_n(j, x, 1, 1), (x, -oo, oo)) == 0
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def test_energies(n=1):
|
| 41 |
+
# Maximum "n" which is tested:
|
| 42 |
+
for i in range(n + 1):
|
| 43 |
+
assert E_n(i, omega) == hbar * omega * (i + S.Half)
|
| 44 |
+
|
| 45 |
+
def test_coherent_state(n=10):
|
| 46 |
+
# Maximum "n" which is tested:
|
| 47 |
+
# test whether coherent state is the eigenstate of annihilation operator
|
| 48 |
+
alpha = Symbol("alpha")
|
| 49 |
+
for i in range(n + 1):
|
| 50 |
+
assert simplify(sqrt(n + 1) * coherent_state(n + 1, alpha)) == simplify(alpha * coherent_state(n, alpha))
|
.venv/Lib/site-packages/sympy/physics/tests/test_secondquant.py
ADDED
|
@@ -0,0 +1,1280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.physics.secondquant import (
|
| 2 |
+
Dagger, Bd, VarBosonicBasis, BBra, B, BKet, FixedBosonicBasis,
|
| 3 |
+
matrix_rep, apply_operators, InnerProduct, Commutator, KroneckerDelta,
|
| 4 |
+
AnnihilateBoson, CreateBoson, BosonicOperator,
|
| 5 |
+
F, Fd, FKet, BosonState, CreateFermion, AnnihilateFermion,
|
| 6 |
+
evaluate_deltas, AntiSymmetricTensor, contraction, NO, wicks,
|
| 7 |
+
PermutationOperator, simplify_index_permutations,
|
| 8 |
+
_sort_anticommuting_fermions, _get_ordered_dummies,
|
| 9 |
+
substitute_dummies, FockStateBosonKet,
|
| 10 |
+
ContractionAppliesOnlyToFermions
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
from sympy.concrete.summations import Sum
|
| 14 |
+
from sympy.core.function import (Function, expand)
|
| 15 |
+
from sympy.core.numbers import (I, Rational)
|
| 16 |
+
from sympy.core.singleton import S
|
| 17 |
+
from sympy.core.symbol import (Dummy, Symbol, symbols)
|
| 18 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 19 |
+
from sympy.printing.repr import srepr
|
| 20 |
+
from sympy.simplify.simplify import simplify
|
| 21 |
+
|
| 22 |
+
from sympy.testing.pytest import slow, raises
|
| 23 |
+
from sympy.printing.latex import latex
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def test_PermutationOperator():
|
| 27 |
+
p, q, r, s = symbols('p,q,r,s')
|
| 28 |
+
f, g, h, i = map(Function, 'fghi')
|
| 29 |
+
P = PermutationOperator
|
| 30 |
+
assert P(p, q).get_permuted(f(p)*g(q)) == -f(q)*g(p)
|
| 31 |
+
assert P(p, q).get_permuted(f(p, q)) == -f(q, p)
|
| 32 |
+
assert P(p, q).get_permuted(f(p)) == f(p)
|
| 33 |
+
expr = (f(p)*g(q)*h(r)*i(s)
|
| 34 |
+
- f(q)*g(p)*h(r)*i(s)
|
| 35 |
+
- f(p)*g(q)*h(s)*i(r)
|
| 36 |
+
+ f(q)*g(p)*h(s)*i(r))
|
| 37 |
+
perms = [P(p, q), P(r, s)]
|
| 38 |
+
assert (simplify_index_permutations(expr, perms) ==
|
| 39 |
+
P(p, q)*P(r, s)*f(p)*g(q)*h(r)*i(s))
|
| 40 |
+
assert latex(P(p, q)) == 'P(pq)'
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def test_index_permutations_with_dummies():
|
| 44 |
+
a, b, c, d = symbols('a b c d')
|
| 45 |
+
p, q, r, s = symbols('p q r s', cls=Dummy)
|
| 46 |
+
f, g = map(Function, 'fg')
|
| 47 |
+
P = PermutationOperator
|
| 48 |
+
|
| 49 |
+
# No dummy substitution necessary
|
| 50 |
+
expr = f(a, b, p, q) - f(b, a, p, q)
|
| 51 |
+
assert simplify_index_permutations(
|
| 52 |
+
expr, [P(a, b)]) == P(a, b)*f(a, b, p, q)
|
| 53 |
+
|
| 54 |
+
# Cases where dummy substitution is needed
|
| 55 |
+
expected = P(a, b)*substitute_dummies(f(a, b, p, q))
|
| 56 |
+
|
| 57 |
+
expr = f(a, b, p, q) - f(b, a, q, p)
|
| 58 |
+
result = simplify_index_permutations(expr, [P(a, b)])
|
| 59 |
+
assert expected == substitute_dummies(result)
|
| 60 |
+
|
| 61 |
+
expr = f(a, b, q, p) - f(b, a, p, q)
|
| 62 |
+
result = simplify_index_permutations(expr, [P(a, b)])
|
| 63 |
+
assert expected == substitute_dummies(result)
|
| 64 |
+
|
| 65 |
+
# A case where nothing can be done
|
| 66 |
+
expr = f(a, b, q, p) - g(b, a, p, q)
|
| 67 |
+
result = simplify_index_permutations(expr, [P(a, b)])
|
| 68 |
+
assert expr == result
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def test_dagger():
|
| 72 |
+
i, j, n, m = symbols('i,j,n,m')
|
| 73 |
+
assert Dagger(1) == 1
|
| 74 |
+
assert Dagger(1.0) == 1.0
|
| 75 |
+
assert Dagger(2*I) == -2*I
|
| 76 |
+
assert Dagger(S.Half*I/3.0) == I*Rational(-1, 2)/3.0
|
| 77 |
+
assert Dagger(BKet([n])) == BBra([n])
|
| 78 |
+
assert Dagger(B(0)) == Bd(0)
|
| 79 |
+
assert Dagger(Bd(0)) == B(0)
|
| 80 |
+
assert Dagger(B(n)) == Bd(n)
|
| 81 |
+
assert Dagger(Bd(n)) == B(n)
|
| 82 |
+
assert Dagger(B(0) + B(1)) == Bd(0) + Bd(1)
|
| 83 |
+
assert Dagger(n*m) == Dagger(n)*Dagger(m) # n, m commute
|
| 84 |
+
assert Dagger(B(n)*B(m)) == Bd(m)*Bd(n)
|
| 85 |
+
assert Dagger(B(n)**10) == Dagger(B(n))**10
|
| 86 |
+
assert Dagger('a') == Dagger(Symbol('a'))
|
| 87 |
+
assert Dagger(Dagger('a')) == Symbol('a')
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def test_operator():
|
| 91 |
+
i, j = symbols('i,j')
|
| 92 |
+
o = BosonicOperator(i)
|
| 93 |
+
assert o.state == i
|
| 94 |
+
assert o.is_symbolic
|
| 95 |
+
o = BosonicOperator(1)
|
| 96 |
+
assert o.state == 1
|
| 97 |
+
assert not o.is_symbolic
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def test_create():
|
| 101 |
+
i, j, n, m = symbols('i,j,n,m')
|
| 102 |
+
o = Bd(i)
|
| 103 |
+
assert latex(o) == "{b^\\dagger_{i}}"
|
| 104 |
+
assert isinstance(o, CreateBoson)
|
| 105 |
+
o = o.subs(i, j)
|
| 106 |
+
assert o.atoms(Symbol) == {j}
|
| 107 |
+
o = Bd(0)
|
| 108 |
+
assert o.apply_operator(BKet([n])) == sqrt(n + 1)*BKet([n + 1])
|
| 109 |
+
o = Bd(n)
|
| 110 |
+
assert o.apply_operator(BKet([n])) == o*BKet([n])
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
def test_annihilate():
|
| 114 |
+
i, j, n, m = symbols('i,j,n,m')
|
| 115 |
+
o = B(i)
|
| 116 |
+
assert latex(o) == "b_{i}"
|
| 117 |
+
assert isinstance(o, AnnihilateBoson)
|
| 118 |
+
o = o.subs(i, j)
|
| 119 |
+
assert o.atoms(Symbol) == {j}
|
| 120 |
+
o = B(0)
|
| 121 |
+
assert o.apply_operator(BKet([n])) == sqrt(n)*BKet([n - 1])
|
| 122 |
+
o = B(n)
|
| 123 |
+
assert o.apply_operator(BKet([n])) == o*BKet([n])
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
def test_basic_state():
|
| 127 |
+
i, j, n, m = symbols('i,j,n,m')
|
| 128 |
+
s = BosonState([0, 1, 2, 3, 4])
|
| 129 |
+
assert len(s) == 5
|
| 130 |
+
assert s.args[0] == tuple(range(5))
|
| 131 |
+
assert s.up(0) == BosonState([1, 1, 2, 3, 4])
|
| 132 |
+
assert s.down(4) == BosonState([0, 1, 2, 3, 3])
|
| 133 |
+
for i in range(5):
|
| 134 |
+
assert s.up(i).down(i) == s
|
| 135 |
+
assert s.down(0) == 0
|
| 136 |
+
for i in range(5):
|
| 137 |
+
assert s[i] == i
|
| 138 |
+
s = BosonState([n, m])
|
| 139 |
+
assert s.down(0) == BosonState([n - 1, m])
|
| 140 |
+
assert s.up(0) == BosonState([n + 1, m])
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
def test_basic_apply():
|
| 144 |
+
n = symbols("n")
|
| 145 |
+
e = B(0)*BKet([n])
|
| 146 |
+
assert apply_operators(e) == sqrt(n)*BKet([n - 1])
|
| 147 |
+
e = Bd(0)*BKet([n])
|
| 148 |
+
assert apply_operators(e) == sqrt(n + 1)*BKet([n + 1])
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
def test_complex_apply():
|
| 152 |
+
n, m = symbols("n,m")
|
| 153 |
+
o = Bd(0)*B(0)*Bd(1)*B(0)
|
| 154 |
+
e = apply_operators(o*BKet([n, m]))
|
| 155 |
+
answer = sqrt(n)*sqrt(m + 1)*(-1 + n)*BKet([-1 + n, 1 + m])
|
| 156 |
+
assert expand(e) == expand(answer)
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def test_number_operator():
|
| 160 |
+
n = symbols("n")
|
| 161 |
+
o = Bd(0)*B(0)
|
| 162 |
+
e = apply_operators(o*BKet([n]))
|
| 163 |
+
assert e == n*BKet([n])
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
def test_inner_product():
|
| 167 |
+
i, j, k, l = symbols('i,j,k,l')
|
| 168 |
+
s1 = BBra([0])
|
| 169 |
+
s2 = BKet([1])
|
| 170 |
+
assert InnerProduct(s1, Dagger(s1)) == 1
|
| 171 |
+
assert InnerProduct(s1, s2) == 0
|
| 172 |
+
s1 = BBra([i, j])
|
| 173 |
+
s2 = BKet([k, l])
|
| 174 |
+
r = InnerProduct(s1, s2)
|
| 175 |
+
assert r == KroneckerDelta(i, k)*KroneckerDelta(j, l)
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
def test_symbolic_matrix_elements():
|
| 179 |
+
n, m = symbols('n,m')
|
| 180 |
+
s1 = BBra([n])
|
| 181 |
+
s2 = BKet([m])
|
| 182 |
+
o = B(0)
|
| 183 |
+
e = apply_operators(s1*o*s2)
|
| 184 |
+
assert e == sqrt(m)*KroneckerDelta(n, m - 1)
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
def test_matrix_elements():
|
| 188 |
+
b = VarBosonicBasis(5)
|
| 189 |
+
o = B(0)
|
| 190 |
+
m = matrix_rep(o, b)
|
| 191 |
+
for i in range(4):
|
| 192 |
+
assert m[i, i + 1] == sqrt(i + 1)
|
| 193 |
+
o = Bd(0)
|
| 194 |
+
m = matrix_rep(o, b)
|
| 195 |
+
for i in range(4):
|
| 196 |
+
assert m[i + 1, i] == sqrt(i + 1)
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
def test_fixed_bosonic_basis():
|
| 200 |
+
b = FixedBosonicBasis(2, 2)
|
| 201 |
+
# assert b == [FockState((2, 0)), FockState((1, 1)), FockState((0, 2))]
|
| 202 |
+
state = b.state(1)
|
| 203 |
+
assert state == FockStateBosonKet((1, 1))
|
| 204 |
+
assert b.index(state) == 1
|
| 205 |
+
assert b.state(1) == b[1]
|
| 206 |
+
assert len(b) == 3
|
| 207 |
+
assert str(b) == '[FockState((2, 0)), FockState((1, 1)), FockState((0, 2))]'
|
| 208 |
+
assert repr(b) == '[FockState((2, 0)), FockState((1, 1)), FockState((0, 2))]'
|
| 209 |
+
assert srepr(b) == '[FockState((2, 0)), FockState((1, 1)), FockState((0, 2))]'
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
@slow
|
| 213 |
+
def test_sho():
|
| 214 |
+
n, m = symbols('n,m')
|
| 215 |
+
h_n = Bd(n)*B(n)*(n + S.Half)
|
| 216 |
+
H = Sum(h_n, (n, 0, 5))
|
| 217 |
+
o = H.doit(deep=False)
|
| 218 |
+
b = FixedBosonicBasis(2, 6)
|
| 219 |
+
m = matrix_rep(o, b)
|
| 220 |
+
# We need to double check these energy values to make sure that they
|
| 221 |
+
# are correct and have the proper degeneracies!
|
| 222 |
+
diag = [1, 2, 3, 3, 4, 5, 4, 5, 6, 7, 5, 6, 7, 8, 9, 6, 7, 8, 9, 10, 11]
|
| 223 |
+
for i in range(len(diag)):
|
| 224 |
+
assert diag[i] == m[i, i]
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
def test_commutation():
|
| 228 |
+
n, m = symbols("n,m", above_fermi=True)
|
| 229 |
+
c = Commutator(B(0), Bd(0))
|
| 230 |
+
assert c == 1
|
| 231 |
+
c = Commutator(Bd(0), B(0))
|
| 232 |
+
assert c == -1
|
| 233 |
+
c = Commutator(B(n), Bd(0))
|
| 234 |
+
assert c == KroneckerDelta(n, 0)
|
| 235 |
+
c = Commutator(B(0), B(0))
|
| 236 |
+
assert c == 0
|
| 237 |
+
c = Commutator(B(0), Bd(0))
|
| 238 |
+
e = simplify(apply_operators(c*BKet([n])))
|
| 239 |
+
assert e == BKet([n])
|
| 240 |
+
c = Commutator(B(0), B(1))
|
| 241 |
+
e = simplify(apply_operators(c*BKet([n, m])))
|
| 242 |
+
assert e == 0
|
| 243 |
+
|
| 244 |
+
c = Commutator(F(m), Fd(m))
|
| 245 |
+
assert c == +1 - 2*NO(Fd(m)*F(m))
|
| 246 |
+
c = Commutator(Fd(m), F(m))
|
| 247 |
+
assert c.expand() == -1 + 2*NO(Fd(m)*F(m))
|
| 248 |
+
|
| 249 |
+
C = Commutator
|
| 250 |
+
X, Y, Z = symbols('X,Y,Z', commutative=False)
|
| 251 |
+
assert C(C(X, Y), Z) != 0
|
| 252 |
+
assert C(C(X, Z), Y) != 0
|
| 253 |
+
assert C(Y, C(X, Z)) != 0
|
| 254 |
+
|
| 255 |
+
i, j, k, l = symbols('i,j,k,l', below_fermi=True)
|
| 256 |
+
a, b, c, d = symbols('a,b,c,d', above_fermi=True)
|
| 257 |
+
p, q, r, s = symbols('p,q,r,s')
|
| 258 |
+
D = KroneckerDelta
|
| 259 |
+
|
| 260 |
+
assert C(Fd(a), F(i)) == -2*NO(F(i)*Fd(a))
|
| 261 |
+
assert C(Fd(j), NO(Fd(a)*F(i))).doit(wicks=True) == -D(j, i)*Fd(a)
|
| 262 |
+
assert C(Fd(a)*F(i), Fd(b)*F(j)).doit(wicks=True) == 0
|
| 263 |
+
|
| 264 |
+
c1 = Commutator(F(a), Fd(a))
|
| 265 |
+
assert Commutator.eval(c1, c1) == 0
|
| 266 |
+
c = Commutator(Fd(a)*F(i),Fd(b)*F(j))
|
| 267 |
+
assert latex(c) == r'\left[{a^\dagger_{a}} a_{i},{a^\dagger_{b}} a_{j}\right]'
|
| 268 |
+
assert repr(c) == 'Commutator(CreateFermion(a)*AnnihilateFermion(i),CreateFermion(b)*AnnihilateFermion(j))'
|
| 269 |
+
assert str(c) == '[CreateFermion(a)*AnnihilateFermion(i),CreateFermion(b)*AnnihilateFermion(j)]'
|
| 270 |
+
|
| 271 |
+
|
| 272 |
+
def test_create_f():
|
| 273 |
+
i, j, n, m = symbols('i,j,n,m')
|
| 274 |
+
o = Fd(i)
|
| 275 |
+
assert isinstance(o, CreateFermion)
|
| 276 |
+
o = o.subs(i, j)
|
| 277 |
+
assert o.atoms(Symbol) == {j}
|
| 278 |
+
o = Fd(1)
|
| 279 |
+
assert o.apply_operator(FKet([n])) == FKet([1, n])
|
| 280 |
+
assert o.apply_operator(FKet([n])) == -FKet([n, 1])
|
| 281 |
+
o = Fd(n)
|
| 282 |
+
assert o.apply_operator(FKet([])) == FKet([n])
|
| 283 |
+
|
| 284 |
+
vacuum = FKet([], fermi_level=4)
|
| 285 |
+
assert vacuum == FKet([], fermi_level=4)
|
| 286 |
+
|
| 287 |
+
i, j, k, l = symbols('i,j,k,l', below_fermi=True)
|
| 288 |
+
a, b, c, d = symbols('a,b,c,d', above_fermi=True)
|
| 289 |
+
p, q, r, s = symbols('p,q,r,s')
|
| 290 |
+
|
| 291 |
+
assert Fd(i).apply_operator(FKet([i, j, k], 4)) == FKet([j, k], 4)
|
| 292 |
+
assert Fd(a).apply_operator(FKet([i, b, k], 4)) == FKet([a, i, b, k], 4)
|
| 293 |
+
|
| 294 |
+
assert Dagger(B(p)).apply_operator(q) == q*CreateBoson(p)
|
| 295 |
+
assert repr(Fd(p)) == 'CreateFermion(p)'
|
| 296 |
+
assert srepr(Fd(p)) == "CreateFermion(Symbol('p'))"
|
| 297 |
+
assert latex(Fd(p)) == r'{a^\dagger_{p}}'
|
| 298 |
+
|
| 299 |
+
|
| 300 |
+
def test_annihilate_f():
|
| 301 |
+
i, j, n, m = symbols('i,j,n,m')
|
| 302 |
+
o = F(i)
|
| 303 |
+
assert isinstance(o, AnnihilateFermion)
|
| 304 |
+
o = o.subs(i, j)
|
| 305 |
+
assert o.atoms(Symbol) == {j}
|
| 306 |
+
o = F(1)
|
| 307 |
+
assert o.apply_operator(FKet([1, n])) == FKet([n])
|
| 308 |
+
assert o.apply_operator(FKet([n, 1])) == -FKet([n])
|
| 309 |
+
o = F(n)
|
| 310 |
+
assert o.apply_operator(FKet([n])) == FKet([])
|
| 311 |
+
|
| 312 |
+
i, j, k, l = symbols('i,j,k,l', below_fermi=True)
|
| 313 |
+
a, b, c, d = symbols('a,b,c,d', above_fermi=True)
|
| 314 |
+
p, q, r, s = symbols('p,q,r,s')
|
| 315 |
+
assert F(i).apply_operator(FKet([i, j, k], 4)) == 0
|
| 316 |
+
assert F(a).apply_operator(FKet([i, b, k], 4)) == 0
|
| 317 |
+
assert F(l).apply_operator(FKet([i, j, k], 3)) == 0
|
| 318 |
+
assert F(l).apply_operator(FKet([i, j, k], 4)) == FKet([l, i, j, k], 4)
|
| 319 |
+
assert str(F(p)) == 'f(p)'
|
| 320 |
+
assert repr(F(p)) == 'AnnihilateFermion(p)'
|
| 321 |
+
assert srepr(F(p)) == "AnnihilateFermion(Symbol('p'))"
|
| 322 |
+
assert latex(F(p)) == 'a_{p}'
|
| 323 |
+
|
| 324 |
+
|
| 325 |
+
def test_create_b():
|
| 326 |
+
i, j, n, m = symbols('i,j,n,m')
|
| 327 |
+
o = Bd(i)
|
| 328 |
+
assert isinstance(o, CreateBoson)
|
| 329 |
+
o = o.subs(i, j)
|
| 330 |
+
assert o.atoms(Symbol) == {j}
|
| 331 |
+
o = Bd(0)
|
| 332 |
+
assert o.apply_operator(BKet([n])) == sqrt(n + 1)*BKet([n + 1])
|
| 333 |
+
o = Bd(n)
|
| 334 |
+
assert o.apply_operator(BKet([n])) == o*BKet([n])
|
| 335 |
+
|
| 336 |
+
|
| 337 |
+
def test_annihilate_b():
|
| 338 |
+
i, j, n, m = symbols('i,j,n,m')
|
| 339 |
+
o = B(i)
|
| 340 |
+
assert isinstance(o, AnnihilateBoson)
|
| 341 |
+
o = o.subs(i, j)
|
| 342 |
+
assert o.atoms(Symbol) == {j}
|
| 343 |
+
o = B(0)
|
| 344 |
+
|
| 345 |
+
|
| 346 |
+
def test_wicks():
|
| 347 |
+
p, q, r, s = symbols('p,q,r,s', above_fermi=True)
|
| 348 |
+
|
| 349 |
+
# Testing for particles only
|
| 350 |
+
|
| 351 |
+
str = F(p)*Fd(q)
|
| 352 |
+
assert wicks(str) == NO(F(p)*Fd(q)) + KroneckerDelta(p, q)
|
| 353 |
+
str = Fd(p)*F(q)
|
| 354 |
+
assert wicks(str) == NO(Fd(p)*F(q))
|
| 355 |
+
|
| 356 |
+
str = F(p)*Fd(q)*F(r)*Fd(s)
|
| 357 |
+
nstr = wicks(str)
|
| 358 |
+
fasit = NO(
|
| 359 |
+
KroneckerDelta(p, q)*KroneckerDelta(r, s)
|
| 360 |
+
+ KroneckerDelta(p, q)*AnnihilateFermion(r)*CreateFermion(s)
|
| 361 |
+
+ KroneckerDelta(r, s)*AnnihilateFermion(p)*CreateFermion(q)
|
| 362 |
+
- KroneckerDelta(p, s)*AnnihilateFermion(r)*CreateFermion(q)
|
| 363 |
+
- AnnihilateFermion(p)*AnnihilateFermion(r)*CreateFermion(q)*CreateFermion(s))
|
| 364 |
+
assert nstr == fasit
|
| 365 |
+
|
| 366 |
+
assert (p*q*nstr).expand() == wicks(p*q*str)
|
| 367 |
+
assert (nstr*p*q*2).expand() == wicks(str*p*q*2)
|
| 368 |
+
|
| 369 |
+
# Testing CC equations particles and holes
|
| 370 |
+
i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
|
| 371 |
+
a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
|
| 372 |
+
p, q, r, s = symbols('p q r s', cls=Dummy)
|
| 373 |
+
|
| 374 |
+
assert (wicks(F(a)*NO(F(i)*F(j))*Fd(b)) ==
|
| 375 |
+
NO(F(a)*F(i)*F(j)*Fd(b)) +
|
| 376 |
+
KroneckerDelta(a, b)*NO(F(i)*F(j)))
|
| 377 |
+
assert (wicks(F(a)*NO(F(i)*F(j)*F(k))*Fd(b)) ==
|
| 378 |
+
NO(F(a)*F(i)*F(j)*F(k)*Fd(b)) -
|
| 379 |
+
KroneckerDelta(a, b)*NO(F(i)*F(j)*F(k)))
|
| 380 |
+
|
| 381 |
+
expr = wicks(Fd(i)*NO(Fd(j)*F(k))*F(l))
|
| 382 |
+
assert (expr ==
|
| 383 |
+
-KroneckerDelta(i, k)*NO(Fd(j)*F(l)) -
|
| 384 |
+
KroneckerDelta(j, l)*NO(Fd(i)*F(k)) -
|
| 385 |
+
KroneckerDelta(i, k)*KroneckerDelta(j, l) +
|
| 386 |
+
KroneckerDelta(i, l)*NO(Fd(j)*F(k)) +
|
| 387 |
+
NO(Fd(i)*Fd(j)*F(k)*F(l)))
|
| 388 |
+
expr = wicks(F(a)*NO(F(b)*Fd(c))*Fd(d))
|
| 389 |
+
assert (expr ==
|
| 390 |
+
-KroneckerDelta(a, c)*NO(F(b)*Fd(d)) -
|
| 391 |
+
KroneckerDelta(b, d)*NO(F(a)*Fd(c)) -
|
| 392 |
+
KroneckerDelta(a, c)*KroneckerDelta(b, d) +
|
| 393 |
+
KroneckerDelta(a, d)*NO(F(b)*Fd(c)) +
|
| 394 |
+
NO(F(a)*F(b)*Fd(c)*Fd(d)))
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
def test_NO():
|
| 398 |
+
i, j, k, l = symbols('i j k l', below_fermi=True)
|
| 399 |
+
a, b, c, d = symbols('a b c d', above_fermi=True)
|
| 400 |
+
p, q, r, s = symbols('p q r s', cls=Dummy)
|
| 401 |
+
|
| 402 |
+
assert (NO(Fd(p)*F(q) + Fd(a)*F(b)) ==
|
| 403 |
+
NO(Fd(p)*F(q)) + NO(Fd(a)*F(b)))
|
| 404 |
+
assert (NO(Fd(i)*NO(F(j)*Fd(a))) ==
|
| 405 |
+
NO(Fd(i)*F(j)*Fd(a)))
|
| 406 |
+
assert NO(1) == 1
|
| 407 |
+
assert NO(i) == i
|
| 408 |
+
assert (NO(Fd(a)*Fd(b)*(F(c) + F(d))) ==
|
| 409 |
+
NO(Fd(a)*Fd(b)*F(c)) +
|
| 410 |
+
NO(Fd(a)*Fd(b)*F(d)))
|
| 411 |
+
|
| 412 |
+
assert NO(Fd(a)*F(b))._remove_brackets() == Fd(a)*F(b)
|
| 413 |
+
assert NO(F(j)*Fd(i))._remove_brackets() == F(j)*Fd(i)
|
| 414 |
+
|
| 415 |
+
assert (NO(Fd(p)*F(q)).subs(Fd(p), Fd(a) + Fd(i)) ==
|
| 416 |
+
NO(Fd(a)*F(q)) + NO(Fd(i)*F(q)))
|
| 417 |
+
assert (NO(Fd(p)*F(q)).subs(F(q), F(a) + F(i)) ==
|
| 418 |
+
NO(Fd(p)*F(a)) + NO(Fd(p)*F(i)))
|
| 419 |
+
|
| 420 |
+
expr = NO(Fd(p)*F(q))._remove_brackets()
|
| 421 |
+
assert wicks(expr) == NO(expr)
|
| 422 |
+
|
| 423 |
+
assert NO(Fd(a)*F(b)) == - NO(F(b)*Fd(a))
|
| 424 |
+
|
| 425 |
+
no = NO(Fd(a)*F(i)*F(b)*Fd(j))
|
| 426 |
+
l1 = list(no.iter_q_creators())
|
| 427 |
+
assert l1 == [0, 1]
|
| 428 |
+
l2 = list(no.iter_q_annihilators())
|
| 429 |
+
assert l2 == [3, 2]
|
| 430 |
+
no = NO(Fd(a)*Fd(i))
|
| 431 |
+
assert no.has_q_creators == 1
|
| 432 |
+
assert no.has_q_annihilators == -1
|
| 433 |
+
assert str(no) == ':CreateFermion(a)*CreateFermion(i):'
|
| 434 |
+
assert repr(no) == 'NO(CreateFermion(a)*CreateFermion(i))'
|
| 435 |
+
assert latex(no) == r'\left\{{a^\dagger_{a}} {a^\dagger_{i}}\right\}'
|
| 436 |
+
raises(NotImplementedError, lambda: NO(Bd(p)*F(q)))
|
| 437 |
+
|
| 438 |
+
|
| 439 |
+
def test_sorting():
|
| 440 |
+
i, j = symbols('i,j', below_fermi=True)
|
| 441 |
+
a, b = symbols('a,b', above_fermi=True)
|
| 442 |
+
p, q = symbols('p,q')
|
| 443 |
+
|
| 444 |
+
# p, q
|
| 445 |
+
assert _sort_anticommuting_fermions([Fd(p), F(q)]) == ([Fd(p), F(q)], 0)
|
| 446 |
+
assert _sort_anticommuting_fermions([F(p), Fd(q)]) == ([Fd(q), F(p)], 1)
|
| 447 |
+
|
| 448 |
+
# i, p
|
| 449 |
+
assert _sort_anticommuting_fermions([F(p), Fd(i)]) == ([F(p), Fd(i)], 0)
|
| 450 |
+
assert _sort_anticommuting_fermions([Fd(i), F(p)]) == ([F(p), Fd(i)], 1)
|
| 451 |
+
assert _sort_anticommuting_fermions([Fd(p), Fd(i)]) == ([Fd(p), Fd(i)], 0)
|
| 452 |
+
assert _sort_anticommuting_fermions([Fd(i), Fd(p)]) == ([Fd(p), Fd(i)], 1)
|
| 453 |
+
assert _sort_anticommuting_fermions([F(p), F(i)]) == ([F(i), F(p)], 1)
|
| 454 |
+
assert _sort_anticommuting_fermions([F(i), F(p)]) == ([F(i), F(p)], 0)
|
| 455 |
+
assert _sort_anticommuting_fermions([Fd(p), F(i)]) == ([F(i), Fd(p)], 1)
|
| 456 |
+
assert _sort_anticommuting_fermions([F(i), Fd(p)]) == ([F(i), Fd(p)], 0)
|
| 457 |
+
|
| 458 |
+
# a, p
|
| 459 |
+
assert _sort_anticommuting_fermions([F(p), Fd(a)]) == ([Fd(a), F(p)], 1)
|
| 460 |
+
assert _sort_anticommuting_fermions([Fd(a), F(p)]) == ([Fd(a), F(p)], 0)
|
| 461 |
+
assert _sort_anticommuting_fermions([Fd(p), Fd(a)]) == ([Fd(a), Fd(p)], 1)
|
| 462 |
+
assert _sort_anticommuting_fermions([Fd(a), Fd(p)]) == ([Fd(a), Fd(p)], 0)
|
| 463 |
+
assert _sort_anticommuting_fermions([F(p), F(a)]) == ([F(p), F(a)], 0)
|
| 464 |
+
assert _sort_anticommuting_fermions([F(a), F(p)]) == ([F(p), F(a)], 1)
|
| 465 |
+
assert _sort_anticommuting_fermions([Fd(p), F(a)]) == ([Fd(p), F(a)], 0)
|
| 466 |
+
assert _sort_anticommuting_fermions([F(a), Fd(p)]) == ([Fd(p), F(a)], 1)
|
| 467 |
+
|
| 468 |
+
# i, a
|
| 469 |
+
assert _sort_anticommuting_fermions([F(i), Fd(j)]) == ([F(i), Fd(j)], 0)
|
| 470 |
+
assert _sort_anticommuting_fermions([Fd(j), F(i)]) == ([F(i), Fd(j)], 1)
|
| 471 |
+
assert _sort_anticommuting_fermions([Fd(a), Fd(i)]) == ([Fd(a), Fd(i)], 0)
|
| 472 |
+
assert _sort_anticommuting_fermions([Fd(i), Fd(a)]) == ([Fd(a), Fd(i)], 1)
|
| 473 |
+
assert _sort_anticommuting_fermions([F(a), F(i)]) == ([F(i), F(a)], 1)
|
| 474 |
+
assert _sort_anticommuting_fermions([F(i), F(a)]) == ([F(i), F(a)], 0)
|
| 475 |
+
|
| 476 |
+
|
| 477 |
+
def test_contraction():
|
| 478 |
+
i, j, k, l = symbols('i,j,k,l', below_fermi=True)
|
| 479 |
+
a, b, c, d = symbols('a,b,c,d', above_fermi=True)
|
| 480 |
+
p, q, r, s = symbols('p,q,r,s')
|
| 481 |
+
assert contraction(Fd(i), F(j)) == KroneckerDelta(i, j)
|
| 482 |
+
assert contraction(F(a), Fd(b)) == KroneckerDelta(a, b)
|
| 483 |
+
assert contraction(F(a), Fd(i)) == 0
|
| 484 |
+
assert contraction(Fd(a), F(i)) == 0
|
| 485 |
+
assert contraction(F(i), Fd(a)) == 0
|
| 486 |
+
assert contraction(Fd(i), F(a)) == 0
|
| 487 |
+
assert contraction(Fd(i), F(p)) == KroneckerDelta(i, p)
|
| 488 |
+
restr = evaluate_deltas(contraction(Fd(p), F(q)))
|
| 489 |
+
assert restr.is_only_below_fermi
|
| 490 |
+
restr = evaluate_deltas(contraction(F(p), Fd(q)))
|
| 491 |
+
assert restr.is_only_above_fermi
|
| 492 |
+
raises(ContractionAppliesOnlyToFermions, lambda: contraction(B(a), Fd(b)))
|
| 493 |
+
|
| 494 |
+
|
| 495 |
+
def test_evaluate_deltas():
|
| 496 |
+
i, j, k = symbols('i,j,k')
|
| 497 |
+
|
| 498 |
+
r = KroneckerDelta(i, j) * KroneckerDelta(j, k)
|
| 499 |
+
assert evaluate_deltas(r) == KroneckerDelta(i, k)
|
| 500 |
+
|
| 501 |
+
r = KroneckerDelta(i, 0) * KroneckerDelta(j, k)
|
| 502 |
+
assert evaluate_deltas(r) == KroneckerDelta(i, 0) * KroneckerDelta(j, k)
|
| 503 |
+
|
| 504 |
+
r = KroneckerDelta(1, j) * KroneckerDelta(j, k)
|
| 505 |
+
assert evaluate_deltas(r) == KroneckerDelta(1, k)
|
| 506 |
+
|
| 507 |
+
r = KroneckerDelta(j, 2) * KroneckerDelta(k, j)
|
| 508 |
+
assert evaluate_deltas(r) == KroneckerDelta(2, k)
|
| 509 |
+
|
| 510 |
+
r = KroneckerDelta(i, 0) * KroneckerDelta(i, j) * KroneckerDelta(j, 1)
|
| 511 |
+
assert evaluate_deltas(r) == 0
|
| 512 |
+
|
| 513 |
+
r = (KroneckerDelta(0, i) * KroneckerDelta(0, j)
|
| 514 |
+
* KroneckerDelta(1, j) * KroneckerDelta(1, j))
|
| 515 |
+
assert evaluate_deltas(r) == 0
|
| 516 |
+
|
| 517 |
+
|
| 518 |
+
def test_Tensors():
|
| 519 |
+
i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
|
| 520 |
+
a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
|
| 521 |
+
p, q, r, s = symbols('p q r s')
|
| 522 |
+
|
| 523 |
+
AT = AntiSymmetricTensor
|
| 524 |
+
assert AT('t', (a, b), (i, j)) == -AT('t', (b, a), (i, j))
|
| 525 |
+
assert AT('t', (a, b), (i, j)) == AT('t', (b, a), (j, i))
|
| 526 |
+
assert AT('t', (a, b), (i, j)) == -AT('t', (a, b), (j, i))
|
| 527 |
+
assert AT('t', (a, a), (i, j)) == 0
|
| 528 |
+
assert AT('t', (a, b), (i, i)) == 0
|
| 529 |
+
assert AT('t', (a, b, c), (i, j)) == -AT('t', (b, a, c), (i, j))
|
| 530 |
+
assert AT('t', (a, b, c), (i, j, k)) == AT('t', (b, a, c), (i, k, j))
|
| 531 |
+
|
| 532 |
+
tabij = AT('t', (a, b), (i, j))
|
| 533 |
+
assert tabij.has(a)
|
| 534 |
+
assert tabij.has(b)
|
| 535 |
+
assert tabij.has(i)
|
| 536 |
+
assert tabij.has(j)
|
| 537 |
+
assert tabij.subs(b, c) == AT('t', (a, c), (i, j))
|
| 538 |
+
assert (2*tabij).subs(i, c) == 2*AT('t', (a, b), (c, j))
|
| 539 |
+
assert tabij.symbol == Symbol('t')
|
| 540 |
+
assert latex(tabij) == '{t^{ab}_{ij}}'
|
| 541 |
+
assert str(tabij) == 't((_a, _b),(_i, _j))'
|
| 542 |
+
|
| 543 |
+
assert AT('t', (a, a), (i, j)).subs(a, b) == AT('t', (b, b), (i, j))
|
| 544 |
+
assert AT('t', (a, i), (a, j)).subs(a, b) == AT('t', (b, i), (b, j))
|
| 545 |
+
|
| 546 |
+
|
| 547 |
+
def test_fully_contracted():
|
| 548 |
+
i, j, k, l = symbols('i j k l', below_fermi=True)
|
| 549 |
+
a, b, c, d = symbols('a b c d', above_fermi=True)
|
| 550 |
+
p, q, r, s = symbols('p q r s', cls=Dummy)
|
| 551 |
+
|
| 552 |
+
Fock = (AntiSymmetricTensor('f', (p,), (q,))*
|
| 553 |
+
NO(Fd(p)*F(q)))
|
| 554 |
+
V = (AntiSymmetricTensor('v', (p, q), (r, s))*
|
| 555 |
+
NO(Fd(p)*Fd(q)*F(s)*F(r)))/4
|
| 556 |
+
|
| 557 |
+
Fai = wicks(NO(Fd(i)*F(a))*Fock,
|
| 558 |
+
keep_only_fully_contracted=True,
|
| 559 |
+
simplify_kronecker_deltas=True)
|
| 560 |
+
assert Fai == AntiSymmetricTensor('f', (a,), (i,))
|
| 561 |
+
Vabij = wicks(NO(Fd(i)*Fd(j)*F(b)*F(a))*V,
|
| 562 |
+
keep_only_fully_contracted=True,
|
| 563 |
+
simplify_kronecker_deltas=True)
|
| 564 |
+
assert Vabij == AntiSymmetricTensor('v', (a, b), (i, j))
|
| 565 |
+
|
| 566 |
+
|
| 567 |
+
def test_substitute_dummies_without_dummies():
|
| 568 |
+
i, j = symbols('i,j')
|
| 569 |
+
assert substitute_dummies(att(i, j) + 2) == att(i, j) + 2
|
| 570 |
+
assert substitute_dummies(att(i, j) + 1) == att(i, j) + 1
|
| 571 |
+
|
| 572 |
+
|
| 573 |
+
def test_substitute_dummies_NO_operator():
|
| 574 |
+
i, j = symbols('i j', cls=Dummy)
|
| 575 |
+
assert substitute_dummies(att(i, j)*NO(Fd(i)*F(j))
|
| 576 |
+
- att(j, i)*NO(Fd(j)*F(i))) == 0
|
| 577 |
+
|
| 578 |
+
|
| 579 |
+
def test_substitute_dummies_SQ_operator():
|
| 580 |
+
i, j = symbols('i j', cls=Dummy)
|
| 581 |
+
assert substitute_dummies(att(i, j)*Fd(i)*F(j)
|
| 582 |
+
- att(j, i)*Fd(j)*F(i)) == 0
|
| 583 |
+
|
| 584 |
+
|
| 585 |
+
def test_substitute_dummies_new_indices():
|
| 586 |
+
i, j = symbols('i j', below_fermi=True, cls=Dummy)
|
| 587 |
+
a, b = symbols('a b', above_fermi=True, cls=Dummy)
|
| 588 |
+
p, q = symbols('p q', cls=Dummy)
|
| 589 |
+
f = Function('f')
|
| 590 |
+
assert substitute_dummies(f(i, a, p) - f(j, b, q), new_indices=True) == 0
|
| 591 |
+
|
| 592 |
+
|
| 593 |
+
def test_substitute_dummies_substitution_order():
|
| 594 |
+
i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
|
| 595 |
+
f = Function('f')
|
| 596 |
+
from sympy.utilities.iterables import variations
|
| 597 |
+
for permut in variations([i, j, k, l], 4):
|
| 598 |
+
assert substitute_dummies(f(*permut) - f(i, j, k, l)) == 0
|
| 599 |
+
|
| 600 |
+
|
| 601 |
+
def test_dummy_order_inner_outer_lines_VT1T1T1():
|
| 602 |
+
ii = symbols('i', below_fermi=True)
|
| 603 |
+
aa = symbols('a', above_fermi=True)
|
| 604 |
+
k, l = symbols('k l', below_fermi=True, cls=Dummy)
|
| 605 |
+
c, d = symbols('c d', above_fermi=True, cls=Dummy)
|
| 606 |
+
|
| 607 |
+
v = Function('v')
|
| 608 |
+
t = Function('t')
|
| 609 |
+
dums = _get_ordered_dummies
|
| 610 |
+
|
| 611 |
+
# Coupled-Cluster T1 terms with V*T1*T1*T1
|
| 612 |
+
# t^{a}_{k} t^{c}_{i} t^{d}_{l} v^{lk}_{dc}
|
| 613 |
+
exprs = [
|
| 614 |
+
# permut v and t <=> swapping internal lines, equivalent
|
| 615 |
+
# irrespective of symmetries in v
|
| 616 |
+
v(k, l, c, d)*t(c, ii)*t(d, l)*t(aa, k),
|
| 617 |
+
v(l, k, c, d)*t(c, ii)*t(d, k)*t(aa, l),
|
| 618 |
+
v(k, l, d, c)*t(d, ii)*t(c, l)*t(aa, k),
|
| 619 |
+
v(l, k, d, c)*t(d, ii)*t(c, k)*t(aa, l),
|
| 620 |
+
]
|
| 621 |
+
for permut in exprs[1:]:
|
| 622 |
+
assert dums(exprs[0]) != dums(permut)
|
| 623 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 624 |
+
|
| 625 |
+
|
| 626 |
+
def test_dummy_order_inner_outer_lines_VT1T1T1T1():
|
| 627 |
+
ii, jj = symbols('i j', below_fermi=True)
|
| 628 |
+
aa, bb = symbols('a b', above_fermi=True)
|
| 629 |
+
k, l = symbols('k l', below_fermi=True, cls=Dummy)
|
| 630 |
+
c, d = symbols('c d', above_fermi=True, cls=Dummy)
|
| 631 |
+
|
| 632 |
+
v = Function('v')
|
| 633 |
+
t = Function('t')
|
| 634 |
+
dums = _get_ordered_dummies
|
| 635 |
+
|
| 636 |
+
# Coupled-Cluster T2 terms with V*T1*T1*T1*T1
|
| 637 |
+
exprs = [
|
| 638 |
+
# permut t <=> swapping external lines, not equivalent
|
| 639 |
+
# except if v has certain symmetries.
|
| 640 |
+
v(k, l, c, d)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
|
| 641 |
+
v(k, l, c, d)*t(c, jj)*t(d, ii)*t(aa, k)*t(bb, l),
|
| 642 |
+
v(k, l, c, d)*t(c, ii)*t(d, jj)*t(bb, k)*t(aa, l),
|
| 643 |
+
v(k, l, c, d)*t(c, jj)*t(d, ii)*t(bb, k)*t(aa, l),
|
| 644 |
+
]
|
| 645 |
+
for permut in exprs[1:]:
|
| 646 |
+
assert dums(exprs[0]) != dums(permut)
|
| 647 |
+
assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
|
| 648 |
+
exprs = [
|
| 649 |
+
# permut v <=> swapping external lines, not equivalent
|
| 650 |
+
# except if v has certain symmetries.
|
| 651 |
+
#
|
| 652 |
+
# Note that in contrast to above, these permutations have identical
|
| 653 |
+
# dummy order. That is because the proximity to external indices
|
| 654 |
+
# has higher influence on the canonical dummy ordering than the
|
| 655 |
+
# position of a dummy on the factors. In fact, the terms here are
|
| 656 |
+
# similar in structure as the result of the dummy substitutions above.
|
| 657 |
+
v(k, l, c, d)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
|
| 658 |
+
v(l, k, c, d)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
|
| 659 |
+
v(k, l, d, c)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
|
| 660 |
+
v(l, k, d, c)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
|
| 661 |
+
]
|
| 662 |
+
for permut in exprs[1:]:
|
| 663 |
+
assert dums(exprs[0]) == dums(permut)
|
| 664 |
+
assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
|
| 665 |
+
exprs = [
|
| 666 |
+
# permut t and v <=> swapping internal lines, equivalent.
|
| 667 |
+
# Canonical dummy order is different, and a consistent
|
| 668 |
+
# substitution reveals the equivalence.
|
| 669 |
+
v(k, l, c, d)*t(c, ii)*t(d, jj)*t(aa, k)*t(bb, l),
|
| 670 |
+
v(k, l, d, c)*t(c, jj)*t(d, ii)*t(aa, k)*t(bb, l),
|
| 671 |
+
v(l, k, c, d)*t(c, ii)*t(d, jj)*t(bb, k)*t(aa, l),
|
| 672 |
+
v(l, k, d, c)*t(c, jj)*t(d, ii)*t(bb, k)*t(aa, l),
|
| 673 |
+
]
|
| 674 |
+
for permut in exprs[1:]:
|
| 675 |
+
assert dums(exprs[0]) != dums(permut)
|
| 676 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 677 |
+
|
| 678 |
+
|
| 679 |
+
def test_get_subNO():
|
| 680 |
+
p, q, r = symbols('p,q,r')
|
| 681 |
+
assert NO(F(p)*F(q)*F(r)).get_subNO(1) == NO(F(p)*F(r))
|
| 682 |
+
assert NO(F(p)*F(q)*F(r)).get_subNO(0) == NO(F(q)*F(r))
|
| 683 |
+
assert NO(F(p)*F(q)*F(r)).get_subNO(2) == NO(F(p)*F(q))
|
| 684 |
+
|
| 685 |
+
|
| 686 |
+
def test_equivalent_internal_lines_VT1T1():
|
| 687 |
+
i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
|
| 688 |
+
a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
|
| 689 |
+
|
| 690 |
+
v = Function('v')
|
| 691 |
+
t = Function('t')
|
| 692 |
+
dums = _get_ordered_dummies
|
| 693 |
+
|
| 694 |
+
exprs = [ # permute v. Different dummy order. Not equivalent.
|
| 695 |
+
v(i, j, a, b)*t(a, i)*t(b, j),
|
| 696 |
+
v(j, i, a, b)*t(a, i)*t(b, j),
|
| 697 |
+
v(i, j, b, a)*t(a, i)*t(b, j),
|
| 698 |
+
]
|
| 699 |
+
for permut in exprs[1:]:
|
| 700 |
+
assert dums(exprs[0]) != dums(permut)
|
| 701 |
+
assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
|
| 702 |
+
|
| 703 |
+
exprs = [ # permute v. Different dummy order. Equivalent
|
| 704 |
+
v(i, j, a, b)*t(a, i)*t(b, j),
|
| 705 |
+
v(j, i, b, a)*t(a, i)*t(b, j),
|
| 706 |
+
]
|
| 707 |
+
for permut in exprs[1:]:
|
| 708 |
+
assert dums(exprs[0]) != dums(permut)
|
| 709 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 710 |
+
|
| 711 |
+
exprs = [ # permute t. Same dummy order, not equivalent.
|
| 712 |
+
v(i, j, a, b)*t(a, i)*t(b, j),
|
| 713 |
+
v(i, j, a, b)*t(b, i)*t(a, j),
|
| 714 |
+
]
|
| 715 |
+
for permut in exprs[1:]:
|
| 716 |
+
assert dums(exprs[0]) == dums(permut)
|
| 717 |
+
assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
|
| 718 |
+
|
| 719 |
+
exprs = [ # permute v and t. Different dummy order, equivalent
|
| 720 |
+
v(i, j, a, b)*t(a, i)*t(b, j),
|
| 721 |
+
v(j, i, a, b)*t(a, j)*t(b, i),
|
| 722 |
+
v(i, j, b, a)*t(b, i)*t(a, j),
|
| 723 |
+
v(j, i, b, a)*t(b, j)*t(a, i),
|
| 724 |
+
]
|
| 725 |
+
for permut in exprs[1:]:
|
| 726 |
+
assert dums(exprs[0]) != dums(permut)
|
| 727 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 728 |
+
|
| 729 |
+
|
| 730 |
+
def test_equivalent_internal_lines_VT2conjT2():
|
| 731 |
+
# this diagram requires special handling in TCE
|
| 732 |
+
i, j, k, l, m, n = symbols('i j k l m n', below_fermi=True, cls=Dummy)
|
| 733 |
+
a, b, c, d, e, f = symbols('a b c d e f', above_fermi=True, cls=Dummy)
|
| 734 |
+
p1, p2, p3, p4 = symbols('p1 p2 p3 p4', above_fermi=True, cls=Dummy)
|
| 735 |
+
h1, h2, h3, h4 = symbols('h1 h2 h3 h4', below_fermi=True, cls=Dummy)
|
| 736 |
+
|
| 737 |
+
from sympy.utilities.iterables import variations
|
| 738 |
+
|
| 739 |
+
v = Function('v')
|
| 740 |
+
t = Function('t')
|
| 741 |
+
dums = _get_ordered_dummies
|
| 742 |
+
|
| 743 |
+
# v(abcd)t(abij)t(ijcd)
|
| 744 |
+
template = v(p1, p2, p3, p4)*t(p1, p2, i, j)*t(i, j, p3, p4)
|
| 745 |
+
permutator = variations([a, b, c, d], 4)
|
| 746 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 747 |
+
for permut in permutator:
|
| 748 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 749 |
+
expr = template.subs(subslist)
|
| 750 |
+
assert dums(base) != dums(expr)
|
| 751 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 752 |
+
template = v(p1, p2, p3, p4)*t(p1, p2, j, i)*t(j, i, p3, p4)
|
| 753 |
+
permutator = variations([a, b, c, d], 4)
|
| 754 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 755 |
+
for permut in permutator:
|
| 756 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 757 |
+
expr = template.subs(subslist)
|
| 758 |
+
assert dums(base) != dums(expr)
|
| 759 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 760 |
+
|
| 761 |
+
# v(abcd)t(abij)t(jicd)
|
| 762 |
+
template = v(p1, p2, p3, p4)*t(p1, p2, i, j)*t(j, i, p3, p4)
|
| 763 |
+
permutator = variations([a, b, c, d], 4)
|
| 764 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 765 |
+
for permut in permutator:
|
| 766 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 767 |
+
expr = template.subs(subslist)
|
| 768 |
+
assert dums(base) != dums(expr)
|
| 769 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 770 |
+
template = v(p1, p2, p3, p4)*t(p1, p2, j, i)*t(i, j, p3, p4)
|
| 771 |
+
permutator = variations([a, b, c, d], 4)
|
| 772 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 773 |
+
for permut in permutator:
|
| 774 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 775 |
+
expr = template.subs(subslist)
|
| 776 |
+
assert dums(base) != dums(expr)
|
| 777 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 778 |
+
|
| 779 |
+
|
| 780 |
+
def test_equivalent_internal_lines_VT2conjT2_ambiguous_order():
|
| 781 |
+
# These diagrams invokes _determine_ambiguous() because the
|
| 782 |
+
# dummies can not be ordered unambiguously by the key alone
|
| 783 |
+
i, j, k, l, m, n = symbols('i j k l m n', below_fermi=True, cls=Dummy)
|
| 784 |
+
a, b, c, d, e, f = symbols('a b c d e f', above_fermi=True, cls=Dummy)
|
| 785 |
+
p1, p2, p3, p4 = symbols('p1 p2 p3 p4', above_fermi=True, cls=Dummy)
|
| 786 |
+
h1, h2, h3, h4 = symbols('h1 h2 h3 h4', below_fermi=True, cls=Dummy)
|
| 787 |
+
|
| 788 |
+
from sympy.utilities.iterables import variations
|
| 789 |
+
|
| 790 |
+
v = Function('v')
|
| 791 |
+
t = Function('t')
|
| 792 |
+
dums = _get_ordered_dummies
|
| 793 |
+
|
| 794 |
+
# v(abcd)t(abij)t(cdij)
|
| 795 |
+
template = v(p1, p2, p3, p4)*t(p1, p2, i, j)*t(p3, p4, i, j)
|
| 796 |
+
permutator = variations([a, b, c, d], 4)
|
| 797 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 798 |
+
for permut in permutator:
|
| 799 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 800 |
+
expr = template.subs(subslist)
|
| 801 |
+
assert dums(base) != dums(expr)
|
| 802 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 803 |
+
template = v(p1, p2, p3, p4)*t(p1, p2, j, i)*t(p3, p4, i, j)
|
| 804 |
+
permutator = variations([a, b, c, d], 4)
|
| 805 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 806 |
+
for permut in permutator:
|
| 807 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 808 |
+
expr = template.subs(subslist)
|
| 809 |
+
assert dums(base) != dums(expr)
|
| 810 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 811 |
+
|
| 812 |
+
|
| 813 |
+
def test_equivalent_internal_lines_VT2():
|
| 814 |
+
i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
|
| 815 |
+
a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
|
| 816 |
+
|
| 817 |
+
v = Function('v')
|
| 818 |
+
t = Function('t')
|
| 819 |
+
dums = _get_ordered_dummies
|
| 820 |
+
exprs = [
|
| 821 |
+
# permute v. Same dummy order, not equivalent.
|
| 822 |
+
#
|
| 823 |
+
# This test show that the dummy order may not be sensitive to all
|
| 824 |
+
# index permutations. The following expressions have identical
|
| 825 |
+
# structure as the resulting terms from of the dummy substitutions
|
| 826 |
+
# in the test above. Here, all expressions have the same dummy
|
| 827 |
+
# order, so they cannot be simplified by means of dummy
|
| 828 |
+
# substitution. In order to simplify further, it is necessary to
|
| 829 |
+
# exploit symmetries in the objects, for instance if t or v is
|
| 830 |
+
# antisymmetric.
|
| 831 |
+
v(i, j, a, b)*t(a, b, i, j),
|
| 832 |
+
v(j, i, a, b)*t(a, b, i, j),
|
| 833 |
+
v(i, j, b, a)*t(a, b, i, j),
|
| 834 |
+
v(j, i, b, a)*t(a, b, i, j),
|
| 835 |
+
]
|
| 836 |
+
for permut in exprs[1:]:
|
| 837 |
+
assert dums(exprs[0]) == dums(permut)
|
| 838 |
+
assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
|
| 839 |
+
|
| 840 |
+
exprs = [
|
| 841 |
+
# permute t.
|
| 842 |
+
v(i, j, a, b)*t(a, b, i, j),
|
| 843 |
+
v(i, j, a, b)*t(b, a, i, j),
|
| 844 |
+
v(i, j, a, b)*t(a, b, j, i),
|
| 845 |
+
v(i, j, a, b)*t(b, a, j, i),
|
| 846 |
+
]
|
| 847 |
+
for permut in exprs[1:]:
|
| 848 |
+
assert dums(exprs[0]) != dums(permut)
|
| 849 |
+
assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
|
| 850 |
+
|
| 851 |
+
exprs = [ # permute v and t. Relabelling of dummies should be equivalent.
|
| 852 |
+
v(i, j, a, b)*t(a, b, i, j),
|
| 853 |
+
v(j, i, a, b)*t(a, b, j, i),
|
| 854 |
+
v(i, j, b, a)*t(b, a, i, j),
|
| 855 |
+
v(j, i, b, a)*t(b, a, j, i),
|
| 856 |
+
]
|
| 857 |
+
for permut in exprs[1:]:
|
| 858 |
+
assert dums(exprs[0]) != dums(permut)
|
| 859 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 860 |
+
|
| 861 |
+
|
| 862 |
+
def test_internal_external_VT2T2():
|
| 863 |
+
ii, jj = symbols('i j', below_fermi=True)
|
| 864 |
+
aa, bb = symbols('a b', above_fermi=True)
|
| 865 |
+
k, l = symbols('k l', below_fermi=True, cls=Dummy)
|
| 866 |
+
c, d = symbols('c d', above_fermi=True, cls=Dummy)
|
| 867 |
+
|
| 868 |
+
v = Function('v')
|
| 869 |
+
t = Function('t')
|
| 870 |
+
dums = _get_ordered_dummies
|
| 871 |
+
|
| 872 |
+
exprs = [
|
| 873 |
+
v(k, l, c, d)*t(aa, c, ii, k)*t(bb, d, jj, l),
|
| 874 |
+
v(l, k, c, d)*t(aa, c, ii, l)*t(bb, d, jj, k),
|
| 875 |
+
v(k, l, d, c)*t(aa, d, ii, k)*t(bb, c, jj, l),
|
| 876 |
+
v(l, k, d, c)*t(aa, d, ii, l)*t(bb, c, jj, k),
|
| 877 |
+
]
|
| 878 |
+
for permut in exprs[1:]:
|
| 879 |
+
assert dums(exprs[0]) != dums(permut)
|
| 880 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 881 |
+
exprs = [
|
| 882 |
+
v(k, l, c, d)*t(aa, c, ii, k)*t(d, bb, jj, l),
|
| 883 |
+
v(l, k, c, d)*t(aa, c, ii, l)*t(d, bb, jj, k),
|
| 884 |
+
v(k, l, d, c)*t(aa, d, ii, k)*t(c, bb, jj, l),
|
| 885 |
+
v(l, k, d, c)*t(aa, d, ii, l)*t(c, bb, jj, k),
|
| 886 |
+
]
|
| 887 |
+
for permut in exprs[1:]:
|
| 888 |
+
assert dums(exprs[0]) != dums(permut)
|
| 889 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 890 |
+
exprs = [
|
| 891 |
+
v(k, l, c, d)*t(c, aa, ii, k)*t(bb, d, jj, l),
|
| 892 |
+
v(l, k, c, d)*t(c, aa, ii, l)*t(bb, d, jj, k),
|
| 893 |
+
v(k, l, d, c)*t(d, aa, ii, k)*t(bb, c, jj, l),
|
| 894 |
+
v(l, k, d, c)*t(d, aa, ii, l)*t(bb, c, jj, k),
|
| 895 |
+
]
|
| 896 |
+
for permut in exprs[1:]:
|
| 897 |
+
assert dums(exprs[0]) != dums(permut)
|
| 898 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 899 |
+
|
| 900 |
+
|
| 901 |
+
def test_internal_external_pqrs():
|
| 902 |
+
ii, jj = symbols('i j')
|
| 903 |
+
aa, bb = symbols('a b')
|
| 904 |
+
k, l = symbols('k l', cls=Dummy)
|
| 905 |
+
c, d = symbols('c d', cls=Dummy)
|
| 906 |
+
|
| 907 |
+
v = Function('v')
|
| 908 |
+
t = Function('t')
|
| 909 |
+
dums = _get_ordered_dummies
|
| 910 |
+
|
| 911 |
+
exprs = [
|
| 912 |
+
v(k, l, c, d)*t(aa, c, ii, k)*t(bb, d, jj, l),
|
| 913 |
+
v(l, k, c, d)*t(aa, c, ii, l)*t(bb, d, jj, k),
|
| 914 |
+
v(k, l, d, c)*t(aa, d, ii, k)*t(bb, c, jj, l),
|
| 915 |
+
v(l, k, d, c)*t(aa, d, ii, l)*t(bb, c, jj, k),
|
| 916 |
+
]
|
| 917 |
+
for permut in exprs[1:]:
|
| 918 |
+
assert dums(exprs[0]) != dums(permut)
|
| 919 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 920 |
+
|
| 921 |
+
|
| 922 |
+
def test_dummy_order_well_defined():
|
| 923 |
+
aa, bb = symbols('a b', above_fermi=True)
|
| 924 |
+
k, l, m = symbols('k l m', below_fermi=True, cls=Dummy)
|
| 925 |
+
c, d = symbols('c d', above_fermi=True, cls=Dummy)
|
| 926 |
+
p, q = symbols('p q', cls=Dummy)
|
| 927 |
+
|
| 928 |
+
A = Function('A')
|
| 929 |
+
B = Function('B')
|
| 930 |
+
C = Function('C')
|
| 931 |
+
dums = _get_ordered_dummies
|
| 932 |
+
|
| 933 |
+
# We go through all key components in the order of increasing priority,
|
| 934 |
+
# and consider only fully orderable expressions. Non-orderable expressions
|
| 935 |
+
# are tested elsewhere.
|
| 936 |
+
|
| 937 |
+
# pos in first factor determines sort order
|
| 938 |
+
assert dums(A(k, l)*B(l, k)) == [k, l]
|
| 939 |
+
assert dums(A(l, k)*B(l, k)) == [l, k]
|
| 940 |
+
assert dums(A(k, l)*B(k, l)) == [k, l]
|
| 941 |
+
assert dums(A(l, k)*B(k, l)) == [l, k]
|
| 942 |
+
|
| 943 |
+
# factors involving the index
|
| 944 |
+
assert dums(A(k, l)*B(l, m)*C(k, m)) == [l, k, m]
|
| 945 |
+
assert dums(A(k, l)*B(l, m)*C(m, k)) == [l, k, m]
|
| 946 |
+
assert dums(A(l, k)*B(l, m)*C(k, m)) == [l, k, m]
|
| 947 |
+
assert dums(A(l, k)*B(l, m)*C(m, k)) == [l, k, m]
|
| 948 |
+
assert dums(A(k, l)*B(m, l)*C(k, m)) == [l, k, m]
|
| 949 |
+
assert dums(A(k, l)*B(m, l)*C(m, k)) == [l, k, m]
|
| 950 |
+
assert dums(A(l, k)*B(m, l)*C(k, m)) == [l, k, m]
|
| 951 |
+
assert dums(A(l, k)*B(m, l)*C(m, k)) == [l, k, m]
|
| 952 |
+
|
| 953 |
+
# same, but with factor order determined by non-dummies
|
| 954 |
+
assert dums(A(k, aa, l)*A(l, bb, m)*A(bb, k, m)) == [l, k, m]
|
| 955 |
+
assert dums(A(k, aa, l)*A(l, bb, m)*A(bb, m, k)) == [l, k, m]
|
| 956 |
+
assert dums(A(k, aa, l)*A(m, bb, l)*A(bb, k, m)) == [l, k, m]
|
| 957 |
+
assert dums(A(k, aa, l)*A(m, bb, l)*A(bb, m, k)) == [l, k, m]
|
| 958 |
+
assert dums(A(l, aa, k)*A(l, bb, m)*A(bb, k, m)) == [l, k, m]
|
| 959 |
+
assert dums(A(l, aa, k)*A(l, bb, m)*A(bb, m, k)) == [l, k, m]
|
| 960 |
+
assert dums(A(l, aa, k)*A(m, bb, l)*A(bb, k, m)) == [l, k, m]
|
| 961 |
+
assert dums(A(l, aa, k)*A(m, bb, l)*A(bb, m, k)) == [l, k, m]
|
| 962 |
+
|
| 963 |
+
# index range
|
| 964 |
+
assert dums(A(p, c, k)*B(p, c, k)) == [k, c, p]
|
| 965 |
+
assert dums(A(p, k, c)*B(p, c, k)) == [k, c, p]
|
| 966 |
+
assert dums(A(c, k, p)*B(p, c, k)) == [k, c, p]
|
| 967 |
+
assert dums(A(c, p, k)*B(p, c, k)) == [k, c, p]
|
| 968 |
+
assert dums(A(k, c, p)*B(p, c, k)) == [k, c, p]
|
| 969 |
+
assert dums(A(k, p, c)*B(p, c, k)) == [k, c, p]
|
| 970 |
+
assert dums(B(p, c, k)*A(p, c, k)) == [k, c, p]
|
| 971 |
+
assert dums(B(p, k, c)*A(p, c, k)) == [k, c, p]
|
| 972 |
+
assert dums(B(c, k, p)*A(p, c, k)) == [k, c, p]
|
| 973 |
+
assert dums(B(c, p, k)*A(p, c, k)) == [k, c, p]
|
| 974 |
+
assert dums(B(k, c, p)*A(p, c, k)) == [k, c, p]
|
| 975 |
+
assert dums(B(k, p, c)*A(p, c, k)) == [k, c, p]
|
| 976 |
+
|
| 977 |
+
|
| 978 |
+
def test_dummy_order_ambiguous():
|
| 979 |
+
aa, bb = symbols('a b', above_fermi=True)
|
| 980 |
+
i, j, k, l, m = symbols('i j k l m', below_fermi=True, cls=Dummy)
|
| 981 |
+
a, b, c, d, e = symbols('a b c d e', above_fermi=True, cls=Dummy)
|
| 982 |
+
p, q = symbols('p q', cls=Dummy)
|
| 983 |
+
p1, p2, p3, p4 = symbols('p1 p2 p3 p4', above_fermi=True, cls=Dummy)
|
| 984 |
+
p5, p6, p7, p8 = symbols('p5 p6 p7 p8', above_fermi=True, cls=Dummy)
|
| 985 |
+
h1, h2, h3, h4 = symbols('h1 h2 h3 h4', below_fermi=True, cls=Dummy)
|
| 986 |
+
h5, h6, h7, h8 = symbols('h5 h6 h7 h8', below_fermi=True, cls=Dummy)
|
| 987 |
+
|
| 988 |
+
A = Function('A')
|
| 989 |
+
B = Function('B')
|
| 990 |
+
|
| 991 |
+
from sympy.utilities.iterables import variations
|
| 992 |
+
|
| 993 |
+
# A*A*A*A*B -- ordering of p5 and p4 is used to figure out the rest
|
| 994 |
+
template = A(p1, p2)*A(p4, p1)*A(p2, p3)*A(p3, p5)*B(p5, p4)
|
| 995 |
+
permutator = variations([a, b, c, d, e], 5)
|
| 996 |
+
base = template.subs(zip([p1, p2, p3, p4, p5], next(permutator)))
|
| 997 |
+
for permut in permutator:
|
| 998 |
+
subslist = zip([p1, p2, p3, p4, p5], permut)
|
| 999 |
+
expr = template.subs(subslist)
|
| 1000 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 1001 |
+
|
| 1002 |
+
# A*A*A*A*A -- an arbitrary index is assigned and the rest are figured out
|
| 1003 |
+
template = A(p1, p2)*A(p4, p1)*A(p2, p3)*A(p3, p5)*A(p5, p4)
|
| 1004 |
+
permutator = variations([a, b, c, d, e], 5)
|
| 1005 |
+
base = template.subs(zip([p1, p2, p3, p4, p5], next(permutator)))
|
| 1006 |
+
for permut in permutator:
|
| 1007 |
+
subslist = zip([p1, p2, p3, p4, p5], permut)
|
| 1008 |
+
expr = template.subs(subslist)
|
| 1009 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 1010 |
+
|
| 1011 |
+
# A*A*A -- ordering of p5 and p4 is used to figure out the rest
|
| 1012 |
+
template = A(p1, p2, p4, p1)*A(p2, p3, p3, p5)*A(p5, p4)
|
| 1013 |
+
permutator = variations([a, b, c, d, e], 5)
|
| 1014 |
+
base = template.subs(zip([p1, p2, p3, p4, p5], next(permutator)))
|
| 1015 |
+
for permut in permutator:
|
| 1016 |
+
subslist = zip([p1, p2, p3, p4, p5], permut)
|
| 1017 |
+
expr = template.subs(subslist)
|
| 1018 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 1019 |
+
|
| 1020 |
+
|
| 1021 |
+
def atv(*args):
|
| 1022 |
+
return AntiSymmetricTensor('v', args[:2], args[2:] )
|
| 1023 |
+
|
| 1024 |
+
|
| 1025 |
+
def att(*args):
|
| 1026 |
+
if len(args) == 4:
|
| 1027 |
+
return AntiSymmetricTensor('t', args[:2], args[2:] )
|
| 1028 |
+
elif len(args) == 2:
|
| 1029 |
+
return AntiSymmetricTensor('t', (args[0],), (args[1],))
|
| 1030 |
+
|
| 1031 |
+
|
| 1032 |
+
def test_dummy_order_inner_outer_lines_VT1T1T1_AT():
|
| 1033 |
+
ii = symbols('i', below_fermi=True)
|
| 1034 |
+
aa = symbols('a', above_fermi=True)
|
| 1035 |
+
k, l = symbols('k l', below_fermi=True, cls=Dummy)
|
| 1036 |
+
c, d = symbols('c d', above_fermi=True, cls=Dummy)
|
| 1037 |
+
|
| 1038 |
+
# Coupled-Cluster T1 terms with V*T1*T1*T1
|
| 1039 |
+
# t^{a}_{k} t^{c}_{i} t^{d}_{l} v^{lk}_{dc}
|
| 1040 |
+
exprs = [
|
| 1041 |
+
# permut v and t <=> swapping internal lines, equivalent
|
| 1042 |
+
# irrespective of symmetries in v
|
| 1043 |
+
atv(k, l, c, d)*att(c, ii)*att(d, l)*att(aa, k),
|
| 1044 |
+
atv(l, k, c, d)*att(c, ii)*att(d, k)*att(aa, l),
|
| 1045 |
+
atv(k, l, d, c)*att(d, ii)*att(c, l)*att(aa, k),
|
| 1046 |
+
atv(l, k, d, c)*att(d, ii)*att(c, k)*att(aa, l),
|
| 1047 |
+
]
|
| 1048 |
+
for permut in exprs[1:]:
|
| 1049 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 1050 |
+
|
| 1051 |
+
|
| 1052 |
+
def test_dummy_order_inner_outer_lines_VT1T1T1T1_AT():
|
| 1053 |
+
ii, jj = symbols('i j', below_fermi=True)
|
| 1054 |
+
aa, bb = symbols('a b', above_fermi=True)
|
| 1055 |
+
k, l = symbols('k l', below_fermi=True, cls=Dummy)
|
| 1056 |
+
c, d = symbols('c d', above_fermi=True, cls=Dummy)
|
| 1057 |
+
|
| 1058 |
+
# Coupled-Cluster T2 terms with V*T1*T1*T1*T1
|
| 1059 |
+
# non-equivalent substitutions (change of sign)
|
| 1060 |
+
exprs = [
|
| 1061 |
+
# permut t <=> swapping external lines
|
| 1062 |
+
atv(k, l, c, d)*att(c, ii)*att(d, jj)*att(aa, k)*att(bb, l),
|
| 1063 |
+
atv(k, l, c, d)*att(c, jj)*att(d, ii)*att(aa, k)*att(bb, l),
|
| 1064 |
+
atv(k, l, c, d)*att(c, ii)*att(d, jj)*att(bb, k)*att(aa, l),
|
| 1065 |
+
]
|
| 1066 |
+
for permut in exprs[1:]:
|
| 1067 |
+
assert substitute_dummies(exprs[0]) == -substitute_dummies(permut)
|
| 1068 |
+
|
| 1069 |
+
# equivalent substitutions
|
| 1070 |
+
exprs = [
|
| 1071 |
+
atv(k, l, c, d)*att(c, ii)*att(d, jj)*att(aa, k)*att(bb, l),
|
| 1072 |
+
# permut t <=> swapping external lines
|
| 1073 |
+
atv(k, l, c, d)*att(c, jj)*att(d, ii)*att(bb, k)*att(aa, l),
|
| 1074 |
+
]
|
| 1075 |
+
for permut in exprs[1:]:
|
| 1076 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 1077 |
+
|
| 1078 |
+
|
| 1079 |
+
def test_equivalent_internal_lines_VT1T1_AT():
|
| 1080 |
+
i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
|
| 1081 |
+
a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
|
| 1082 |
+
|
| 1083 |
+
exprs = [ # permute v. Different dummy order. Not equivalent.
|
| 1084 |
+
atv(i, j, a, b)*att(a, i)*att(b, j),
|
| 1085 |
+
atv(j, i, a, b)*att(a, i)*att(b, j),
|
| 1086 |
+
atv(i, j, b, a)*att(a, i)*att(b, j),
|
| 1087 |
+
]
|
| 1088 |
+
for permut in exprs[1:]:
|
| 1089 |
+
assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
|
| 1090 |
+
|
| 1091 |
+
exprs = [ # permute v. Different dummy order. Equivalent
|
| 1092 |
+
atv(i, j, a, b)*att(a, i)*att(b, j),
|
| 1093 |
+
atv(j, i, b, a)*att(a, i)*att(b, j),
|
| 1094 |
+
]
|
| 1095 |
+
for permut in exprs[1:]:
|
| 1096 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 1097 |
+
|
| 1098 |
+
exprs = [ # permute t. Same dummy order, not equivalent.
|
| 1099 |
+
atv(i, j, a, b)*att(a, i)*att(b, j),
|
| 1100 |
+
atv(i, j, a, b)*att(b, i)*att(a, j),
|
| 1101 |
+
]
|
| 1102 |
+
for permut in exprs[1:]:
|
| 1103 |
+
assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
|
| 1104 |
+
|
| 1105 |
+
exprs = [ # permute v and t. Different dummy order, equivalent
|
| 1106 |
+
atv(i, j, a, b)*att(a, i)*att(b, j),
|
| 1107 |
+
atv(j, i, a, b)*att(a, j)*att(b, i),
|
| 1108 |
+
atv(i, j, b, a)*att(b, i)*att(a, j),
|
| 1109 |
+
atv(j, i, b, a)*att(b, j)*att(a, i),
|
| 1110 |
+
]
|
| 1111 |
+
for permut in exprs[1:]:
|
| 1112 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 1113 |
+
|
| 1114 |
+
|
| 1115 |
+
def test_equivalent_internal_lines_VT2conjT2_AT():
|
| 1116 |
+
# this diagram requires special handling in TCE
|
| 1117 |
+
i, j, k, l, m, n = symbols('i j k l m n', below_fermi=True, cls=Dummy)
|
| 1118 |
+
a, b, c, d, e, f = symbols('a b c d e f', above_fermi=True, cls=Dummy)
|
| 1119 |
+
p1, p2, p3, p4 = symbols('p1 p2 p3 p4', above_fermi=True, cls=Dummy)
|
| 1120 |
+
h1, h2, h3, h4 = symbols('h1 h2 h3 h4', below_fermi=True, cls=Dummy)
|
| 1121 |
+
|
| 1122 |
+
from sympy.utilities.iterables import variations
|
| 1123 |
+
|
| 1124 |
+
# atv(abcd)att(abij)att(ijcd)
|
| 1125 |
+
template = atv(p1, p2, p3, p4)*att(p1, p2, i, j)*att(i, j, p3, p4)
|
| 1126 |
+
permutator = variations([a, b, c, d], 4)
|
| 1127 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 1128 |
+
for permut in permutator:
|
| 1129 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 1130 |
+
expr = template.subs(subslist)
|
| 1131 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 1132 |
+
template = atv(p1, p2, p3, p4)*att(p1, p2, j, i)*att(j, i, p3, p4)
|
| 1133 |
+
permutator = variations([a, b, c, d], 4)
|
| 1134 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 1135 |
+
for permut in permutator:
|
| 1136 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 1137 |
+
expr = template.subs(subslist)
|
| 1138 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 1139 |
+
|
| 1140 |
+
# atv(abcd)att(abij)att(jicd)
|
| 1141 |
+
template = atv(p1, p2, p3, p4)*att(p1, p2, i, j)*att(j, i, p3, p4)
|
| 1142 |
+
permutator = variations([a, b, c, d], 4)
|
| 1143 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 1144 |
+
for permut in permutator:
|
| 1145 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 1146 |
+
expr = template.subs(subslist)
|
| 1147 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 1148 |
+
template = atv(p1, p2, p3, p4)*att(p1, p2, j, i)*att(i, j, p3, p4)
|
| 1149 |
+
permutator = variations([a, b, c, d], 4)
|
| 1150 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 1151 |
+
for permut in permutator:
|
| 1152 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 1153 |
+
expr = template.subs(subslist)
|
| 1154 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 1155 |
+
|
| 1156 |
+
|
| 1157 |
+
def test_equivalent_internal_lines_VT2conjT2_ambiguous_order_AT():
|
| 1158 |
+
# These diagrams invokes _determine_ambiguous() because the
|
| 1159 |
+
# dummies can not be ordered unambiguously by the key alone
|
| 1160 |
+
i, j, k, l, m, n = symbols('i j k l m n', below_fermi=True, cls=Dummy)
|
| 1161 |
+
a, b, c, d, e, f = symbols('a b c d e f', above_fermi=True, cls=Dummy)
|
| 1162 |
+
p1, p2, p3, p4 = symbols('p1 p2 p3 p4', above_fermi=True, cls=Dummy)
|
| 1163 |
+
h1, h2, h3, h4 = symbols('h1 h2 h3 h4', below_fermi=True, cls=Dummy)
|
| 1164 |
+
|
| 1165 |
+
from sympy.utilities.iterables import variations
|
| 1166 |
+
|
| 1167 |
+
# atv(abcd)att(abij)att(cdij)
|
| 1168 |
+
template = atv(p1, p2, p3, p4)*att(p1, p2, i, j)*att(p3, p4, i, j)
|
| 1169 |
+
permutator = variations([a, b, c, d], 4)
|
| 1170 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 1171 |
+
for permut in permutator:
|
| 1172 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 1173 |
+
expr = template.subs(subslist)
|
| 1174 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 1175 |
+
template = atv(p1, p2, p3, p4)*att(p1, p2, j, i)*att(p3, p4, i, j)
|
| 1176 |
+
permutator = variations([a, b, c, d], 4)
|
| 1177 |
+
base = template.subs(zip([p1, p2, p3, p4], next(permutator)))
|
| 1178 |
+
for permut in permutator:
|
| 1179 |
+
subslist = zip([p1, p2, p3, p4], permut)
|
| 1180 |
+
expr = template.subs(subslist)
|
| 1181 |
+
assert substitute_dummies(expr) == substitute_dummies(base)
|
| 1182 |
+
|
| 1183 |
+
|
| 1184 |
+
def test_equivalent_internal_lines_VT2_AT():
|
| 1185 |
+
i, j, k, l = symbols('i j k l', below_fermi=True, cls=Dummy)
|
| 1186 |
+
a, b, c, d = symbols('a b c d', above_fermi=True, cls=Dummy)
|
| 1187 |
+
|
| 1188 |
+
exprs = [
|
| 1189 |
+
# permute v. Same dummy order, not equivalent.
|
| 1190 |
+
atv(i, j, a, b)*att(a, b, i, j),
|
| 1191 |
+
atv(j, i, a, b)*att(a, b, i, j),
|
| 1192 |
+
atv(i, j, b, a)*att(a, b, i, j),
|
| 1193 |
+
]
|
| 1194 |
+
for permut in exprs[1:]:
|
| 1195 |
+
assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
|
| 1196 |
+
|
| 1197 |
+
exprs = [
|
| 1198 |
+
# permute t.
|
| 1199 |
+
atv(i, j, a, b)*att(a, b, i, j),
|
| 1200 |
+
atv(i, j, a, b)*att(b, a, i, j),
|
| 1201 |
+
atv(i, j, a, b)*att(a, b, j, i),
|
| 1202 |
+
]
|
| 1203 |
+
for permut in exprs[1:]:
|
| 1204 |
+
assert substitute_dummies(exprs[0]) != substitute_dummies(permut)
|
| 1205 |
+
|
| 1206 |
+
exprs = [ # permute v and t. Relabelling of dummies should be equivalent.
|
| 1207 |
+
atv(i, j, a, b)*att(a, b, i, j),
|
| 1208 |
+
atv(j, i, a, b)*att(a, b, j, i),
|
| 1209 |
+
atv(i, j, b, a)*att(b, a, i, j),
|
| 1210 |
+
atv(j, i, b, a)*att(b, a, j, i),
|
| 1211 |
+
]
|
| 1212 |
+
for permut in exprs[1:]:
|
| 1213 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 1214 |
+
|
| 1215 |
+
|
| 1216 |
+
def test_internal_external_VT2T2_AT():
|
| 1217 |
+
ii, jj = symbols('i j', below_fermi=True)
|
| 1218 |
+
aa, bb = symbols('a b', above_fermi=True)
|
| 1219 |
+
k, l = symbols('k l', below_fermi=True, cls=Dummy)
|
| 1220 |
+
c, d = symbols('c d', above_fermi=True, cls=Dummy)
|
| 1221 |
+
|
| 1222 |
+
exprs = [
|
| 1223 |
+
atv(k, l, c, d)*att(aa, c, ii, k)*att(bb, d, jj, l),
|
| 1224 |
+
atv(l, k, c, d)*att(aa, c, ii, l)*att(bb, d, jj, k),
|
| 1225 |
+
atv(k, l, d, c)*att(aa, d, ii, k)*att(bb, c, jj, l),
|
| 1226 |
+
atv(l, k, d, c)*att(aa, d, ii, l)*att(bb, c, jj, k),
|
| 1227 |
+
]
|
| 1228 |
+
for permut in exprs[1:]:
|
| 1229 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 1230 |
+
exprs = [
|
| 1231 |
+
atv(k, l, c, d)*att(aa, c, ii, k)*att(d, bb, jj, l),
|
| 1232 |
+
atv(l, k, c, d)*att(aa, c, ii, l)*att(d, bb, jj, k),
|
| 1233 |
+
atv(k, l, d, c)*att(aa, d, ii, k)*att(c, bb, jj, l),
|
| 1234 |
+
atv(l, k, d, c)*att(aa, d, ii, l)*att(c, bb, jj, k),
|
| 1235 |
+
]
|
| 1236 |
+
for permut in exprs[1:]:
|
| 1237 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 1238 |
+
exprs = [
|
| 1239 |
+
atv(k, l, c, d)*att(c, aa, ii, k)*att(bb, d, jj, l),
|
| 1240 |
+
atv(l, k, c, d)*att(c, aa, ii, l)*att(bb, d, jj, k),
|
| 1241 |
+
atv(k, l, d, c)*att(d, aa, ii, k)*att(bb, c, jj, l),
|
| 1242 |
+
atv(l, k, d, c)*att(d, aa, ii, l)*att(bb, c, jj, k),
|
| 1243 |
+
]
|
| 1244 |
+
for permut in exprs[1:]:
|
| 1245 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 1246 |
+
|
| 1247 |
+
|
| 1248 |
+
def test_internal_external_pqrs_AT():
|
| 1249 |
+
ii, jj = symbols('i j')
|
| 1250 |
+
aa, bb = symbols('a b')
|
| 1251 |
+
k, l = symbols('k l', cls=Dummy)
|
| 1252 |
+
c, d = symbols('c d', cls=Dummy)
|
| 1253 |
+
|
| 1254 |
+
exprs = [
|
| 1255 |
+
atv(k, l, c, d)*att(aa, c, ii, k)*att(bb, d, jj, l),
|
| 1256 |
+
atv(l, k, c, d)*att(aa, c, ii, l)*att(bb, d, jj, k),
|
| 1257 |
+
atv(k, l, d, c)*att(aa, d, ii, k)*att(bb, c, jj, l),
|
| 1258 |
+
atv(l, k, d, c)*att(aa, d, ii, l)*att(bb, c, jj, k),
|
| 1259 |
+
]
|
| 1260 |
+
for permut in exprs[1:]:
|
| 1261 |
+
assert substitute_dummies(exprs[0]) == substitute_dummies(permut)
|
| 1262 |
+
|
| 1263 |
+
|
| 1264 |
+
def test_issue_19661():
|
| 1265 |
+
a = Symbol('0')
|
| 1266 |
+
assert latex(Commutator(Bd(a)**2, B(a))
|
| 1267 |
+
) == '- \\left[b_{0},{b^\\dagger_{0}}^{2}\\right]'
|
| 1268 |
+
|
| 1269 |
+
|
| 1270 |
+
def test_canonical_ordering_AntiSymmetricTensor():
|
| 1271 |
+
v = symbols("v")
|
| 1272 |
+
|
| 1273 |
+
c, d = symbols(('c','d'), above_fermi=True,
|
| 1274 |
+
cls=Dummy)
|
| 1275 |
+
k, l = symbols(('k','l'), below_fermi=True,
|
| 1276 |
+
cls=Dummy)
|
| 1277 |
+
|
| 1278 |
+
# formerly, the left gave either the left or the right
|
| 1279 |
+
assert AntiSymmetricTensor(v, (k, l), (d, c)
|
| 1280 |
+
) == -AntiSymmetricTensor(v, (l, k), (d, c))
|
.venv/Lib/site-packages/sympy/physics/tests/test_sho.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core import symbols, Rational, Function, diff
|
| 2 |
+
from sympy.physics.sho import R_nl, E_nl
|
| 3 |
+
from sympy.simplify.simplify import simplify
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def test_sho_R_nl():
|
| 7 |
+
omega, r = symbols('omega r')
|
| 8 |
+
l = symbols('l', integer=True)
|
| 9 |
+
u = Function('u')
|
| 10 |
+
|
| 11 |
+
# check that it obeys the Schrodinger equation
|
| 12 |
+
for n in range(5):
|
| 13 |
+
schreq = ( -diff(u(r), r, 2)/2 + ((l*(l + 1))/(2*r**2)
|
| 14 |
+
+ omega**2*r**2/2 - E_nl(n, l, omega))*u(r) )
|
| 15 |
+
result = schreq.subs(u(r), r*R_nl(n, l, omega/2, r))
|
| 16 |
+
assert simplify(result.doit()) == 0
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def test_energy():
|
| 20 |
+
n, l, hw = symbols('n l hw')
|
| 21 |
+
assert simplify(E_nl(n, l, hw) - (2*n + l + Rational(3, 2))*hw) == 0
|
.venv/Lib/site-packages/sympy/physics/units/__init__.py
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# isort:skip_file
|
| 2 |
+
"""
|
| 3 |
+
Dimensional analysis and unit systems.
|
| 4 |
+
|
| 5 |
+
This module defines dimension/unit systems and physical quantities. It is
|
| 6 |
+
based on a group-theoretical construction where dimensions are represented as
|
| 7 |
+
vectors (coefficients being the exponents), and units are defined as a dimension
|
| 8 |
+
to which we added a scale.
|
| 9 |
+
|
| 10 |
+
Quantities are built from a factor and a unit, and are the basic objects that
|
| 11 |
+
one will use when doing computations.
|
| 12 |
+
|
| 13 |
+
All objects except systems and prefixes can be used in SymPy expressions.
|
| 14 |
+
Note that as part of a CAS, various objects do not combine automatically
|
| 15 |
+
under operations.
|
| 16 |
+
|
| 17 |
+
Details about the implementation can be found in the documentation, and we
|
| 18 |
+
will not repeat all the explanations we gave there concerning our approach.
|
| 19 |
+
Ideas about future developments can be found on the `Github wiki
|
| 20 |
+
<https://github.com/sympy/sympy/wiki/Unit-systems>`_, and you should consult
|
| 21 |
+
this page if you are willing to help.
|
| 22 |
+
|
| 23 |
+
Useful functions:
|
| 24 |
+
|
| 25 |
+
- ``find_unit``: easily lookup pre-defined units.
|
| 26 |
+
- ``convert_to(expr, newunit)``: converts an expression into the same
|
| 27 |
+
expression expressed in another unit.
|
| 28 |
+
|
| 29 |
+
"""
|
| 30 |
+
|
| 31 |
+
from .dimensions import Dimension, DimensionSystem
|
| 32 |
+
from .unitsystem import UnitSystem
|
| 33 |
+
from .util import convert_to
|
| 34 |
+
from .quantities import Quantity
|
| 35 |
+
|
| 36 |
+
from .definitions.dimension_definitions import (
|
| 37 |
+
amount_of_substance, acceleration, action, area,
|
| 38 |
+
capacitance, charge, conductance, current, energy,
|
| 39 |
+
force, frequency, impedance, inductance, length,
|
| 40 |
+
luminous_intensity, magnetic_density,
|
| 41 |
+
magnetic_flux, mass, momentum, power, pressure, temperature, time,
|
| 42 |
+
velocity, voltage, volume
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
Unit = Quantity
|
| 46 |
+
|
| 47 |
+
speed = velocity
|
| 48 |
+
luminosity = luminous_intensity
|
| 49 |
+
magnetic_flux_density = magnetic_density
|
| 50 |
+
amount = amount_of_substance
|
| 51 |
+
|
| 52 |
+
from .prefixes import (
|
| 53 |
+
# 10-power based:
|
| 54 |
+
yotta,
|
| 55 |
+
zetta,
|
| 56 |
+
exa,
|
| 57 |
+
peta,
|
| 58 |
+
tera,
|
| 59 |
+
giga,
|
| 60 |
+
mega,
|
| 61 |
+
kilo,
|
| 62 |
+
hecto,
|
| 63 |
+
deca,
|
| 64 |
+
deci,
|
| 65 |
+
centi,
|
| 66 |
+
milli,
|
| 67 |
+
micro,
|
| 68 |
+
nano,
|
| 69 |
+
pico,
|
| 70 |
+
femto,
|
| 71 |
+
atto,
|
| 72 |
+
zepto,
|
| 73 |
+
yocto,
|
| 74 |
+
# 2-power based:
|
| 75 |
+
kibi,
|
| 76 |
+
mebi,
|
| 77 |
+
gibi,
|
| 78 |
+
tebi,
|
| 79 |
+
pebi,
|
| 80 |
+
exbi,
|
| 81 |
+
)
|
| 82 |
+
|
| 83 |
+
from .definitions import (
|
| 84 |
+
percent, percents,
|
| 85 |
+
permille,
|
| 86 |
+
rad, radian, radians,
|
| 87 |
+
deg, degree, degrees,
|
| 88 |
+
sr, steradian, steradians,
|
| 89 |
+
mil, angular_mil, angular_mils,
|
| 90 |
+
m, meter, meters,
|
| 91 |
+
kg, kilogram, kilograms,
|
| 92 |
+
s, second, seconds,
|
| 93 |
+
A, ampere, amperes,
|
| 94 |
+
K, kelvin, kelvins,
|
| 95 |
+
mol, mole, moles,
|
| 96 |
+
cd, candela, candelas,
|
| 97 |
+
g, gram, grams,
|
| 98 |
+
mg, milligram, milligrams,
|
| 99 |
+
ug, microgram, micrograms,
|
| 100 |
+
t, tonne, metric_ton,
|
| 101 |
+
newton, newtons, N,
|
| 102 |
+
joule, joules, J,
|
| 103 |
+
watt, watts, W,
|
| 104 |
+
pascal, pascals, Pa, pa,
|
| 105 |
+
hertz, hz, Hz,
|
| 106 |
+
coulomb, coulombs, C,
|
| 107 |
+
volt, volts, v, V,
|
| 108 |
+
ohm, ohms,
|
| 109 |
+
siemens, S, mho, mhos,
|
| 110 |
+
farad, farads, F,
|
| 111 |
+
henry, henrys, H,
|
| 112 |
+
tesla, teslas, T,
|
| 113 |
+
weber, webers, Wb, wb,
|
| 114 |
+
optical_power, dioptre, D,
|
| 115 |
+
lux, lx,
|
| 116 |
+
katal, kat,
|
| 117 |
+
gray, Gy,
|
| 118 |
+
becquerel, Bq,
|
| 119 |
+
km, kilometer, kilometers,
|
| 120 |
+
dm, decimeter, decimeters,
|
| 121 |
+
cm, centimeter, centimeters,
|
| 122 |
+
mm, millimeter, millimeters,
|
| 123 |
+
um, micrometer, micrometers, micron, microns,
|
| 124 |
+
nm, nanometer, nanometers,
|
| 125 |
+
pm, picometer, picometers,
|
| 126 |
+
ft, foot, feet,
|
| 127 |
+
inch, inches,
|
| 128 |
+
yd, yard, yards,
|
| 129 |
+
mi, mile, miles,
|
| 130 |
+
nmi, nautical_mile, nautical_miles,
|
| 131 |
+
angstrom, angstroms,
|
| 132 |
+
ha, hectare,
|
| 133 |
+
l, L, liter, liters,
|
| 134 |
+
dl, dL, deciliter, deciliters,
|
| 135 |
+
cl, cL, centiliter, centiliters,
|
| 136 |
+
ml, mL, milliliter, milliliters,
|
| 137 |
+
ms, millisecond, milliseconds,
|
| 138 |
+
us, microsecond, microseconds,
|
| 139 |
+
ns, nanosecond, nanoseconds,
|
| 140 |
+
ps, picosecond, picoseconds,
|
| 141 |
+
minute, minutes,
|
| 142 |
+
h, hour, hours,
|
| 143 |
+
day, days,
|
| 144 |
+
anomalistic_year, anomalistic_years,
|
| 145 |
+
sidereal_year, sidereal_years,
|
| 146 |
+
tropical_year, tropical_years,
|
| 147 |
+
common_year, common_years,
|
| 148 |
+
julian_year, julian_years,
|
| 149 |
+
draconic_year, draconic_years,
|
| 150 |
+
gaussian_year, gaussian_years,
|
| 151 |
+
full_moon_cycle, full_moon_cycles,
|
| 152 |
+
year, years,
|
| 153 |
+
G, gravitational_constant,
|
| 154 |
+
c, speed_of_light,
|
| 155 |
+
elementary_charge,
|
| 156 |
+
hbar,
|
| 157 |
+
planck,
|
| 158 |
+
eV, electronvolt, electronvolts,
|
| 159 |
+
avogadro_number,
|
| 160 |
+
avogadro, avogadro_constant,
|
| 161 |
+
boltzmann, boltzmann_constant,
|
| 162 |
+
stefan, stefan_boltzmann_constant,
|
| 163 |
+
R, molar_gas_constant,
|
| 164 |
+
faraday_constant,
|
| 165 |
+
josephson_constant,
|
| 166 |
+
von_klitzing_constant,
|
| 167 |
+
Da, dalton, amu, amus, atomic_mass_unit, atomic_mass_constant,
|
| 168 |
+
me, electron_rest_mass,
|
| 169 |
+
gee, gees, acceleration_due_to_gravity,
|
| 170 |
+
u0, magnetic_constant, vacuum_permeability,
|
| 171 |
+
e0, electric_constant, vacuum_permittivity,
|
| 172 |
+
Z0, vacuum_impedance,
|
| 173 |
+
coulomb_constant, electric_force_constant,
|
| 174 |
+
atmosphere, atmospheres, atm,
|
| 175 |
+
kPa,
|
| 176 |
+
bar, bars,
|
| 177 |
+
pound, pounds,
|
| 178 |
+
psi,
|
| 179 |
+
dHg0,
|
| 180 |
+
mmHg, torr,
|
| 181 |
+
mmu, mmus, milli_mass_unit,
|
| 182 |
+
quart, quarts,
|
| 183 |
+
ly, lightyear, lightyears,
|
| 184 |
+
au, astronomical_unit, astronomical_units,
|
| 185 |
+
planck_mass,
|
| 186 |
+
planck_time,
|
| 187 |
+
planck_temperature,
|
| 188 |
+
planck_length,
|
| 189 |
+
planck_charge,
|
| 190 |
+
planck_area,
|
| 191 |
+
planck_volume,
|
| 192 |
+
planck_momentum,
|
| 193 |
+
planck_energy,
|
| 194 |
+
planck_force,
|
| 195 |
+
planck_power,
|
| 196 |
+
planck_density,
|
| 197 |
+
planck_energy_density,
|
| 198 |
+
planck_intensity,
|
| 199 |
+
planck_angular_frequency,
|
| 200 |
+
planck_pressure,
|
| 201 |
+
planck_current,
|
| 202 |
+
planck_voltage,
|
| 203 |
+
planck_impedance,
|
| 204 |
+
planck_acceleration,
|
| 205 |
+
bit, bits,
|
| 206 |
+
byte,
|
| 207 |
+
kibibyte, kibibytes,
|
| 208 |
+
mebibyte, mebibytes,
|
| 209 |
+
gibibyte, gibibytes,
|
| 210 |
+
tebibyte, tebibytes,
|
| 211 |
+
pebibyte, pebibytes,
|
| 212 |
+
exbibyte, exbibytes,
|
| 213 |
+
)
|
| 214 |
+
|
| 215 |
+
from .systems import (
|
| 216 |
+
mks, mksa, si
|
| 217 |
+
)
|
| 218 |
+
|
| 219 |
+
|
| 220 |
+
def find_unit(quantity, unit_system="SI"):
|
| 221 |
+
"""
|
| 222 |
+
Return a list of matching units or dimension names.
|
| 223 |
+
|
| 224 |
+
- If ``quantity`` is a string -- units/dimensions containing the string
|
| 225 |
+
`quantity`.
|
| 226 |
+
- If ``quantity`` is a unit or dimension -- units having matching base
|
| 227 |
+
units or dimensions.
|
| 228 |
+
|
| 229 |
+
Examples
|
| 230 |
+
========
|
| 231 |
+
|
| 232 |
+
>>> from sympy.physics import units as u
|
| 233 |
+
>>> u.find_unit('charge')
|
| 234 |
+
['C', 'coulomb', 'coulombs', 'planck_charge', 'elementary_charge']
|
| 235 |
+
>>> u.find_unit(u.charge)
|
| 236 |
+
['C', 'coulomb', 'coulombs', 'planck_charge', 'elementary_charge']
|
| 237 |
+
>>> u.find_unit("ampere")
|
| 238 |
+
['ampere', 'amperes']
|
| 239 |
+
>>> u.find_unit('angstrom')
|
| 240 |
+
['angstrom', 'angstroms']
|
| 241 |
+
>>> u.find_unit('volt')
|
| 242 |
+
['volt', 'volts', 'electronvolt', 'electronvolts', 'planck_voltage']
|
| 243 |
+
>>> u.find_unit(u.inch**3)[:9]
|
| 244 |
+
['L', 'l', 'cL', 'cl', 'dL', 'dl', 'mL', 'ml', 'liter']
|
| 245 |
+
"""
|
| 246 |
+
unit_system = UnitSystem.get_unit_system(unit_system)
|
| 247 |
+
|
| 248 |
+
import sympy.physics.units as u
|
| 249 |
+
rv = []
|
| 250 |
+
if isinstance(quantity, str):
|
| 251 |
+
rv = [i for i in dir(u) if quantity in i and isinstance(getattr(u, i), Quantity)]
|
| 252 |
+
dim = getattr(u, quantity)
|
| 253 |
+
if isinstance(dim, Dimension):
|
| 254 |
+
rv.extend(find_unit(dim))
|
| 255 |
+
else:
|
| 256 |
+
for i in sorted(dir(u)):
|
| 257 |
+
other = getattr(u, i)
|
| 258 |
+
if not isinstance(other, Quantity):
|
| 259 |
+
continue
|
| 260 |
+
if isinstance(quantity, Quantity):
|
| 261 |
+
if quantity.dimension == other.dimension:
|
| 262 |
+
rv.append(str(i))
|
| 263 |
+
elif isinstance(quantity, Dimension):
|
| 264 |
+
if other.dimension == quantity:
|
| 265 |
+
rv.append(str(i))
|
| 266 |
+
elif other.dimension == Dimension(unit_system.get_dimensional_expr(quantity)):
|
| 267 |
+
rv.append(str(i))
|
| 268 |
+
return sorted(set(rv), key=lambda x: (len(x), x))
|
| 269 |
+
|
| 270 |
+
# NOTE: the old units module had additional variables:
|
| 271 |
+
# 'density', 'illuminance', 'resistance'.
|
| 272 |
+
# They were not dimensions, but units (old Unit class).
|
| 273 |
+
|
| 274 |
+
__all__ = [
|
| 275 |
+
'Dimension', 'DimensionSystem',
|
| 276 |
+
'UnitSystem',
|
| 277 |
+
'convert_to',
|
| 278 |
+
'Quantity',
|
| 279 |
+
|
| 280 |
+
'amount_of_substance', 'acceleration', 'action', 'area',
|
| 281 |
+
'capacitance', 'charge', 'conductance', 'current', 'energy',
|
| 282 |
+
'force', 'frequency', 'impedance', 'inductance', 'length',
|
| 283 |
+
'luminous_intensity', 'magnetic_density',
|
| 284 |
+
'magnetic_flux', 'mass', 'momentum', 'power', 'pressure', 'temperature', 'time',
|
| 285 |
+
'velocity', 'voltage', 'volume',
|
| 286 |
+
|
| 287 |
+
'Unit',
|
| 288 |
+
|
| 289 |
+
'speed',
|
| 290 |
+
'luminosity',
|
| 291 |
+
'magnetic_flux_density',
|
| 292 |
+
'amount',
|
| 293 |
+
|
| 294 |
+
'yotta',
|
| 295 |
+
'zetta',
|
| 296 |
+
'exa',
|
| 297 |
+
'peta',
|
| 298 |
+
'tera',
|
| 299 |
+
'giga',
|
| 300 |
+
'mega',
|
| 301 |
+
'kilo',
|
| 302 |
+
'hecto',
|
| 303 |
+
'deca',
|
| 304 |
+
'deci',
|
| 305 |
+
'centi',
|
| 306 |
+
'milli',
|
| 307 |
+
'micro',
|
| 308 |
+
'nano',
|
| 309 |
+
'pico',
|
| 310 |
+
'femto',
|
| 311 |
+
'atto',
|
| 312 |
+
'zepto',
|
| 313 |
+
'yocto',
|
| 314 |
+
|
| 315 |
+
'kibi',
|
| 316 |
+
'mebi',
|
| 317 |
+
'gibi',
|
| 318 |
+
'tebi',
|
| 319 |
+
'pebi',
|
| 320 |
+
'exbi',
|
| 321 |
+
|
| 322 |
+
'percent', 'percents',
|
| 323 |
+
'permille',
|
| 324 |
+
'rad', 'radian', 'radians',
|
| 325 |
+
'deg', 'degree', 'degrees',
|
| 326 |
+
'sr', 'steradian', 'steradians',
|
| 327 |
+
'mil', 'angular_mil', 'angular_mils',
|
| 328 |
+
'm', 'meter', 'meters',
|
| 329 |
+
'kg', 'kilogram', 'kilograms',
|
| 330 |
+
's', 'second', 'seconds',
|
| 331 |
+
'A', 'ampere', 'amperes',
|
| 332 |
+
'K', 'kelvin', 'kelvins',
|
| 333 |
+
'mol', 'mole', 'moles',
|
| 334 |
+
'cd', 'candela', 'candelas',
|
| 335 |
+
'g', 'gram', 'grams',
|
| 336 |
+
'mg', 'milligram', 'milligrams',
|
| 337 |
+
'ug', 'microgram', 'micrograms',
|
| 338 |
+
't', 'tonne', 'metric_ton',
|
| 339 |
+
'newton', 'newtons', 'N',
|
| 340 |
+
'joule', 'joules', 'J',
|
| 341 |
+
'watt', 'watts', 'W',
|
| 342 |
+
'pascal', 'pascals', 'Pa', 'pa',
|
| 343 |
+
'hertz', 'hz', 'Hz',
|
| 344 |
+
'coulomb', 'coulombs', 'C',
|
| 345 |
+
'volt', 'volts', 'v', 'V',
|
| 346 |
+
'ohm', 'ohms',
|
| 347 |
+
'siemens', 'S', 'mho', 'mhos',
|
| 348 |
+
'farad', 'farads', 'F',
|
| 349 |
+
'henry', 'henrys', 'H',
|
| 350 |
+
'tesla', 'teslas', 'T',
|
| 351 |
+
'weber', 'webers', 'Wb', 'wb',
|
| 352 |
+
'optical_power', 'dioptre', 'D',
|
| 353 |
+
'lux', 'lx',
|
| 354 |
+
'katal', 'kat',
|
| 355 |
+
'gray', 'Gy',
|
| 356 |
+
'becquerel', 'Bq',
|
| 357 |
+
'km', 'kilometer', 'kilometers',
|
| 358 |
+
'dm', 'decimeter', 'decimeters',
|
| 359 |
+
'cm', 'centimeter', 'centimeters',
|
| 360 |
+
'mm', 'millimeter', 'millimeters',
|
| 361 |
+
'um', 'micrometer', 'micrometers', 'micron', 'microns',
|
| 362 |
+
'nm', 'nanometer', 'nanometers',
|
| 363 |
+
'pm', 'picometer', 'picometers',
|
| 364 |
+
'ft', 'foot', 'feet',
|
| 365 |
+
'inch', 'inches',
|
| 366 |
+
'yd', 'yard', 'yards',
|
| 367 |
+
'mi', 'mile', 'miles',
|
| 368 |
+
'nmi', 'nautical_mile', 'nautical_miles',
|
| 369 |
+
'angstrom', 'angstroms',
|
| 370 |
+
'ha', 'hectare',
|
| 371 |
+
'l', 'L', 'liter', 'liters',
|
| 372 |
+
'dl', 'dL', 'deciliter', 'deciliters',
|
| 373 |
+
'cl', 'cL', 'centiliter', 'centiliters',
|
| 374 |
+
'ml', 'mL', 'milliliter', 'milliliters',
|
| 375 |
+
'ms', 'millisecond', 'milliseconds',
|
| 376 |
+
'us', 'microsecond', 'microseconds',
|
| 377 |
+
'ns', 'nanosecond', 'nanoseconds',
|
| 378 |
+
'ps', 'picosecond', 'picoseconds',
|
| 379 |
+
'minute', 'minutes',
|
| 380 |
+
'h', 'hour', 'hours',
|
| 381 |
+
'day', 'days',
|
| 382 |
+
'anomalistic_year', 'anomalistic_years',
|
| 383 |
+
'sidereal_year', 'sidereal_years',
|
| 384 |
+
'tropical_year', 'tropical_years',
|
| 385 |
+
'common_year', 'common_years',
|
| 386 |
+
'julian_year', 'julian_years',
|
| 387 |
+
'draconic_year', 'draconic_years',
|
| 388 |
+
'gaussian_year', 'gaussian_years',
|
| 389 |
+
'full_moon_cycle', 'full_moon_cycles',
|
| 390 |
+
'year', 'years',
|
| 391 |
+
'G', 'gravitational_constant',
|
| 392 |
+
'c', 'speed_of_light',
|
| 393 |
+
'elementary_charge',
|
| 394 |
+
'hbar',
|
| 395 |
+
'planck',
|
| 396 |
+
'eV', 'electronvolt', 'electronvolts',
|
| 397 |
+
'avogadro_number',
|
| 398 |
+
'avogadro', 'avogadro_constant',
|
| 399 |
+
'boltzmann', 'boltzmann_constant',
|
| 400 |
+
'stefan', 'stefan_boltzmann_constant',
|
| 401 |
+
'R', 'molar_gas_constant',
|
| 402 |
+
'faraday_constant',
|
| 403 |
+
'josephson_constant',
|
| 404 |
+
'von_klitzing_constant',
|
| 405 |
+
'Da', 'dalton', 'amu', 'amus', 'atomic_mass_unit', 'atomic_mass_constant',
|
| 406 |
+
'me', 'electron_rest_mass',
|
| 407 |
+
'gee', 'gees', 'acceleration_due_to_gravity',
|
| 408 |
+
'u0', 'magnetic_constant', 'vacuum_permeability',
|
| 409 |
+
'e0', 'electric_constant', 'vacuum_permittivity',
|
| 410 |
+
'Z0', 'vacuum_impedance',
|
| 411 |
+
'coulomb_constant', 'electric_force_constant',
|
| 412 |
+
'atmosphere', 'atmospheres', 'atm',
|
| 413 |
+
'kPa',
|
| 414 |
+
'bar', 'bars',
|
| 415 |
+
'pound', 'pounds',
|
| 416 |
+
'psi',
|
| 417 |
+
'dHg0',
|
| 418 |
+
'mmHg', 'torr',
|
| 419 |
+
'mmu', 'mmus', 'milli_mass_unit',
|
| 420 |
+
'quart', 'quarts',
|
| 421 |
+
'ly', 'lightyear', 'lightyears',
|
| 422 |
+
'au', 'astronomical_unit', 'astronomical_units',
|
| 423 |
+
'planck_mass',
|
| 424 |
+
'planck_time',
|
| 425 |
+
'planck_temperature',
|
| 426 |
+
'planck_length',
|
| 427 |
+
'planck_charge',
|
| 428 |
+
'planck_area',
|
| 429 |
+
'planck_volume',
|
| 430 |
+
'planck_momentum',
|
| 431 |
+
'planck_energy',
|
| 432 |
+
'planck_force',
|
| 433 |
+
'planck_power',
|
| 434 |
+
'planck_density',
|
| 435 |
+
'planck_energy_density',
|
| 436 |
+
'planck_intensity',
|
| 437 |
+
'planck_angular_frequency',
|
| 438 |
+
'planck_pressure',
|
| 439 |
+
'planck_current',
|
| 440 |
+
'planck_voltage',
|
| 441 |
+
'planck_impedance',
|
| 442 |
+
'planck_acceleration',
|
| 443 |
+
'bit', 'bits',
|
| 444 |
+
'byte',
|
| 445 |
+
'kibibyte', 'kibibytes',
|
| 446 |
+
'mebibyte', 'mebibytes',
|
| 447 |
+
'gibibyte', 'gibibytes',
|
| 448 |
+
'tebibyte', 'tebibytes',
|
| 449 |
+
'pebibyte', 'pebibytes',
|
| 450 |
+
'exbibyte', 'exbibytes',
|
| 451 |
+
|
| 452 |
+
'mks', 'mksa', 'si',
|
| 453 |
+
]
|
.venv/Lib/site-packages/sympy/physics/units/definitions/__init__.py
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .unit_definitions import (
|
| 2 |
+
percent, percents,
|
| 3 |
+
permille,
|
| 4 |
+
rad, radian, radians,
|
| 5 |
+
deg, degree, degrees,
|
| 6 |
+
sr, steradian, steradians,
|
| 7 |
+
mil, angular_mil, angular_mils,
|
| 8 |
+
m, meter, meters,
|
| 9 |
+
kg, kilogram, kilograms,
|
| 10 |
+
s, second, seconds,
|
| 11 |
+
A, ampere, amperes,
|
| 12 |
+
K, kelvin, kelvins,
|
| 13 |
+
mol, mole, moles,
|
| 14 |
+
cd, candela, candelas,
|
| 15 |
+
g, gram, grams,
|
| 16 |
+
mg, milligram, milligrams,
|
| 17 |
+
ug, microgram, micrograms,
|
| 18 |
+
t, tonne, metric_ton,
|
| 19 |
+
newton, newtons, N,
|
| 20 |
+
joule, joules, J,
|
| 21 |
+
watt, watts, W,
|
| 22 |
+
pascal, pascals, Pa, pa,
|
| 23 |
+
hertz, hz, Hz,
|
| 24 |
+
coulomb, coulombs, C,
|
| 25 |
+
volt, volts, v, V,
|
| 26 |
+
ohm, ohms,
|
| 27 |
+
siemens, S, mho, mhos,
|
| 28 |
+
farad, farads, F,
|
| 29 |
+
henry, henrys, H,
|
| 30 |
+
tesla, teslas, T,
|
| 31 |
+
weber, webers, Wb, wb,
|
| 32 |
+
optical_power, dioptre, D,
|
| 33 |
+
lux, lx,
|
| 34 |
+
katal, kat,
|
| 35 |
+
gray, Gy,
|
| 36 |
+
becquerel, Bq,
|
| 37 |
+
km, kilometer, kilometers,
|
| 38 |
+
dm, decimeter, decimeters,
|
| 39 |
+
cm, centimeter, centimeters,
|
| 40 |
+
mm, millimeter, millimeters,
|
| 41 |
+
um, micrometer, micrometers, micron, microns,
|
| 42 |
+
nm, nanometer, nanometers,
|
| 43 |
+
pm, picometer, picometers,
|
| 44 |
+
ft, foot, feet,
|
| 45 |
+
inch, inches,
|
| 46 |
+
yd, yard, yards,
|
| 47 |
+
mi, mile, miles,
|
| 48 |
+
nmi, nautical_mile, nautical_miles,
|
| 49 |
+
ha, hectare,
|
| 50 |
+
l, L, liter, liters,
|
| 51 |
+
dl, dL, deciliter, deciliters,
|
| 52 |
+
cl, cL, centiliter, centiliters,
|
| 53 |
+
ml, mL, milliliter, milliliters,
|
| 54 |
+
ms, millisecond, milliseconds,
|
| 55 |
+
us, microsecond, microseconds,
|
| 56 |
+
ns, nanosecond, nanoseconds,
|
| 57 |
+
ps, picosecond, picoseconds,
|
| 58 |
+
minute, minutes,
|
| 59 |
+
h, hour, hours,
|
| 60 |
+
day, days,
|
| 61 |
+
anomalistic_year, anomalistic_years,
|
| 62 |
+
sidereal_year, sidereal_years,
|
| 63 |
+
tropical_year, tropical_years,
|
| 64 |
+
common_year, common_years,
|
| 65 |
+
julian_year, julian_years,
|
| 66 |
+
draconic_year, draconic_years,
|
| 67 |
+
gaussian_year, gaussian_years,
|
| 68 |
+
full_moon_cycle, full_moon_cycles,
|
| 69 |
+
year, years,
|
| 70 |
+
G, gravitational_constant,
|
| 71 |
+
c, speed_of_light,
|
| 72 |
+
elementary_charge,
|
| 73 |
+
hbar,
|
| 74 |
+
planck,
|
| 75 |
+
eV, electronvolt, electronvolts,
|
| 76 |
+
avogadro_number,
|
| 77 |
+
avogadro, avogadro_constant,
|
| 78 |
+
boltzmann, boltzmann_constant,
|
| 79 |
+
stefan, stefan_boltzmann_constant,
|
| 80 |
+
R, molar_gas_constant,
|
| 81 |
+
faraday_constant,
|
| 82 |
+
josephson_constant,
|
| 83 |
+
von_klitzing_constant,
|
| 84 |
+
Da, dalton, amu, amus, atomic_mass_unit, atomic_mass_constant,
|
| 85 |
+
me, electron_rest_mass,
|
| 86 |
+
gee, gees, acceleration_due_to_gravity,
|
| 87 |
+
u0, magnetic_constant, vacuum_permeability,
|
| 88 |
+
e0, electric_constant, vacuum_permittivity,
|
| 89 |
+
Z0, vacuum_impedance,
|
| 90 |
+
coulomb_constant, coulombs_constant, electric_force_constant,
|
| 91 |
+
atmosphere, atmospheres, atm,
|
| 92 |
+
kPa, kilopascal,
|
| 93 |
+
bar, bars,
|
| 94 |
+
pound, pounds,
|
| 95 |
+
psi,
|
| 96 |
+
dHg0,
|
| 97 |
+
mmHg, torr,
|
| 98 |
+
mmu, mmus, milli_mass_unit,
|
| 99 |
+
quart, quarts,
|
| 100 |
+
angstrom, angstroms,
|
| 101 |
+
ly, lightyear, lightyears,
|
| 102 |
+
au, astronomical_unit, astronomical_units,
|
| 103 |
+
planck_mass,
|
| 104 |
+
planck_time,
|
| 105 |
+
planck_temperature,
|
| 106 |
+
planck_length,
|
| 107 |
+
planck_charge,
|
| 108 |
+
planck_area,
|
| 109 |
+
planck_volume,
|
| 110 |
+
planck_momentum,
|
| 111 |
+
planck_energy,
|
| 112 |
+
planck_force,
|
| 113 |
+
planck_power,
|
| 114 |
+
planck_density,
|
| 115 |
+
planck_energy_density,
|
| 116 |
+
planck_intensity,
|
| 117 |
+
planck_angular_frequency,
|
| 118 |
+
planck_pressure,
|
| 119 |
+
planck_current,
|
| 120 |
+
planck_voltage,
|
| 121 |
+
planck_impedance,
|
| 122 |
+
planck_acceleration,
|
| 123 |
+
bit, bits,
|
| 124 |
+
byte,
|
| 125 |
+
kibibyte, kibibytes,
|
| 126 |
+
mebibyte, mebibytes,
|
| 127 |
+
gibibyte, gibibytes,
|
| 128 |
+
tebibyte, tebibytes,
|
| 129 |
+
pebibyte, pebibytes,
|
| 130 |
+
exbibyte, exbibytes,
|
| 131 |
+
curie, rutherford
|
| 132 |
+
)
|
| 133 |
+
|
| 134 |
+
__all__ = [
|
| 135 |
+
'percent', 'percents',
|
| 136 |
+
'permille',
|
| 137 |
+
'rad', 'radian', 'radians',
|
| 138 |
+
'deg', 'degree', 'degrees',
|
| 139 |
+
'sr', 'steradian', 'steradians',
|
| 140 |
+
'mil', 'angular_mil', 'angular_mils',
|
| 141 |
+
'm', 'meter', 'meters',
|
| 142 |
+
'kg', 'kilogram', 'kilograms',
|
| 143 |
+
's', 'second', 'seconds',
|
| 144 |
+
'A', 'ampere', 'amperes',
|
| 145 |
+
'K', 'kelvin', 'kelvins',
|
| 146 |
+
'mol', 'mole', 'moles',
|
| 147 |
+
'cd', 'candela', 'candelas',
|
| 148 |
+
'g', 'gram', 'grams',
|
| 149 |
+
'mg', 'milligram', 'milligrams',
|
| 150 |
+
'ug', 'microgram', 'micrograms',
|
| 151 |
+
't', 'tonne', 'metric_ton',
|
| 152 |
+
'newton', 'newtons', 'N',
|
| 153 |
+
'joule', 'joules', 'J',
|
| 154 |
+
'watt', 'watts', 'W',
|
| 155 |
+
'pascal', 'pascals', 'Pa', 'pa',
|
| 156 |
+
'hertz', 'hz', 'Hz',
|
| 157 |
+
'coulomb', 'coulombs', 'C',
|
| 158 |
+
'volt', 'volts', 'v', 'V',
|
| 159 |
+
'ohm', 'ohms',
|
| 160 |
+
'siemens', 'S', 'mho', 'mhos',
|
| 161 |
+
'farad', 'farads', 'F',
|
| 162 |
+
'henry', 'henrys', 'H',
|
| 163 |
+
'tesla', 'teslas', 'T',
|
| 164 |
+
'weber', 'webers', 'Wb', 'wb',
|
| 165 |
+
'optical_power', 'dioptre', 'D',
|
| 166 |
+
'lux', 'lx',
|
| 167 |
+
'katal', 'kat',
|
| 168 |
+
'gray', 'Gy',
|
| 169 |
+
'becquerel', 'Bq',
|
| 170 |
+
'km', 'kilometer', 'kilometers',
|
| 171 |
+
'dm', 'decimeter', 'decimeters',
|
| 172 |
+
'cm', 'centimeter', 'centimeters',
|
| 173 |
+
'mm', 'millimeter', 'millimeters',
|
| 174 |
+
'um', 'micrometer', 'micrometers', 'micron', 'microns',
|
| 175 |
+
'nm', 'nanometer', 'nanometers',
|
| 176 |
+
'pm', 'picometer', 'picometers',
|
| 177 |
+
'ft', 'foot', 'feet',
|
| 178 |
+
'inch', 'inches',
|
| 179 |
+
'yd', 'yard', 'yards',
|
| 180 |
+
'mi', 'mile', 'miles',
|
| 181 |
+
'nmi', 'nautical_mile', 'nautical_miles',
|
| 182 |
+
'ha', 'hectare',
|
| 183 |
+
'l', 'L', 'liter', 'liters',
|
| 184 |
+
'dl', 'dL', 'deciliter', 'deciliters',
|
| 185 |
+
'cl', 'cL', 'centiliter', 'centiliters',
|
| 186 |
+
'ml', 'mL', 'milliliter', 'milliliters',
|
| 187 |
+
'ms', 'millisecond', 'milliseconds',
|
| 188 |
+
'us', 'microsecond', 'microseconds',
|
| 189 |
+
'ns', 'nanosecond', 'nanoseconds',
|
| 190 |
+
'ps', 'picosecond', 'picoseconds',
|
| 191 |
+
'minute', 'minutes',
|
| 192 |
+
'h', 'hour', 'hours',
|
| 193 |
+
'day', 'days',
|
| 194 |
+
'anomalistic_year', 'anomalistic_years',
|
| 195 |
+
'sidereal_year', 'sidereal_years',
|
| 196 |
+
'tropical_year', 'tropical_years',
|
| 197 |
+
'common_year', 'common_years',
|
| 198 |
+
'julian_year', 'julian_years',
|
| 199 |
+
'draconic_year', 'draconic_years',
|
| 200 |
+
'gaussian_year', 'gaussian_years',
|
| 201 |
+
'full_moon_cycle', 'full_moon_cycles',
|
| 202 |
+
'year', 'years',
|
| 203 |
+
'G', 'gravitational_constant',
|
| 204 |
+
'c', 'speed_of_light',
|
| 205 |
+
'elementary_charge',
|
| 206 |
+
'hbar',
|
| 207 |
+
'planck',
|
| 208 |
+
'eV', 'electronvolt', 'electronvolts',
|
| 209 |
+
'avogadro_number',
|
| 210 |
+
'avogadro', 'avogadro_constant',
|
| 211 |
+
'boltzmann', 'boltzmann_constant',
|
| 212 |
+
'stefan', 'stefan_boltzmann_constant',
|
| 213 |
+
'R', 'molar_gas_constant',
|
| 214 |
+
'faraday_constant',
|
| 215 |
+
'josephson_constant',
|
| 216 |
+
'von_klitzing_constant',
|
| 217 |
+
'Da', 'dalton', 'amu', 'amus', 'atomic_mass_unit', 'atomic_mass_constant',
|
| 218 |
+
'me', 'electron_rest_mass',
|
| 219 |
+
'gee', 'gees', 'acceleration_due_to_gravity',
|
| 220 |
+
'u0', 'magnetic_constant', 'vacuum_permeability',
|
| 221 |
+
'e0', 'electric_constant', 'vacuum_permittivity',
|
| 222 |
+
'Z0', 'vacuum_impedance',
|
| 223 |
+
'coulomb_constant', 'coulombs_constant', 'electric_force_constant',
|
| 224 |
+
'atmosphere', 'atmospheres', 'atm',
|
| 225 |
+
'kPa', 'kilopascal',
|
| 226 |
+
'bar', 'bars',
|
| 227 |
+
'pound', 'pounds',
|
| 228 |
+
'psi',
|
| 229 |
+
'dHg0',
|
| 230 |
+
'mmHg', 'torr',
|
| 231 |
+
'mmu', 'mmus', 'milli_mass_unit',
|
| 232 |
+
'quart', 'quarts',
|
| 233 |
+
'angstrom', 'angstroms',
|
| 234 |
+
'ly', 'lightyear', 'lightyears',
|
| 235 |
+
'au', 'astronomical_unit', 'astronomical_units',
|
| 236 |
+
'planck_mass',
|
| 237 |
+
'planck_time',
|
| 238 |
+
'planck_temperature',
|
| 239 |
+
'planck_length',
|
| 240 |
+
'planck_charge',
|
| 241 |
+
'planck_area',
|
| 242 |
+
'planck_volume',
|
| 243 |
+
'planck_momentum',
|
| 244 |
+
'planck_energy',
|
| 245 |
+
'planck_force',
|
| 246 |
+
'planck_power',
|
| 247 |
+
'planck_density',
|
| 248 |
+
'planck_energy_density',
|
| 249 |
+
'planck_intensity',
|
| 250 |
+
'planck_angular_frequency',
|
| 251 |
+
'planck_pressure',
|
| 252 |
+
'planck_current',
|
| 253 |
+
'planck_voltage',
|
| 254 |
+
'planck_impedance',
|
| 255 |
+
'planck_acceleration',
|
| 256 |
+
'bit', 'bits',
|
| 257 |
+
'byte',
|
| 258 |
+
'kibibyte', 'kibibytes',
|
| 259 |
+
'mebibyte', 'mebibytes',
|
| 260 |
+
'gibibyte', 'gibibytes',
|
| 261 |
+
'tebibyte', 'tebibytes',
|
| 262 |
+
'pebibyte', 'pebibytes',
|
| 263 |
+
'exbibyte', 'exbibytes',
|
| 264 |
+
'curie', 'rutherford',
|
| 265 |
+
]
|
.venv/Lib/site-packages/sympy/physics/units/definitions/dimension_definitions.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.physics.units import Dimension
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
angle = Dimension(name="angle") # type: Dimension
|
| 5 |
+
|
| 6 |
+
# base dimensions (MKS)
|
| 7 |
+
length = Dimension(name="length", symbol="L")
|
| 8 |
+
mass = Dimension(name="mass", symbol="M")
|
| 9 |
+
time = Dimension(name="time", symbol="T")
|
| 10 |
+
|
| 11 |
+
# base dimensions (MKSA not in MKS)
|
| 12 |
+
current = Dimension(name='current', symbol='I') # type: Dimension
|
| 13 |
+
|
| 14 |
+
# other base dimensions:
|
| 15 |
+
temperature = Dimension("temperature", "T") # type: Dimension
|
| 16 |
+
amount_of_substance = Dimension("amount_of_substance") # type: Dimension
|
| 17 |
+
luminous_intensity = Dimension("luminous_intensity") # type: Dimension
|
| 18 |
+
|
| 19 |
+
# derived dimensions (MKS)
|
| 20 |
+
velocity = Dimension(name="velocity")
|
| 21 |
+
acceleration = Dimension(name="acceleration")
|
| 22 |
+
momentum = Dimension(name="momentum")
|
| 23 |
+
force = Dimension(name="force", symbol="F")
|
| 24 |
+
energy = Dimension(name="energy", symbol="E")
|
| 25 |
+
power = Dimension(name="power")
|
| 26 |
+
pressure = Dimension(name="pressure")
|
| 27 |
+
frequency = Dimension(name="frequency", symbol="f")
|
| 28 |
+
action = Dimension(name="action", symbol="A")
|
| 29 |
+
area = Dimension("area")
|
| 30 |
+
volume = Dimension("volume")
|
| 31 |
+
|
| 32 |
+
# derived dimensions (MKSA not in MKS)
|
| 33 |
+
voltage = Dimension(name='voltage', symbol='U') # type: Dimension
|
| 34 |
+
impedance = Dimension(name='impedance', symbol='Z') # type: Dimension
|
| 35 |
+
conductance = Dimension(name='conductance', symbol='G') # type: Dimension
|
| 36 |
+
capacitance = Dimension(name='capacitance') # type: Dimension
|
| 37 |
+
inductance = Dimension(name='inductance') # type: Dimension
|
| 38 |
+
charge = Dimension(name='charge', symbol='Q') # type: Dimension
|
| 39 |
+
magnetic_density = Dimension(name='magnetic_density', symbol='B') # type: Dimension
|
| 40 |
+
magnetic_flux = Dimension(name='magnetic_flux') # type: Dimension
|
| 41 |
+
|
| 42 |
+
# Dimensions in information theory:
|
| 43 |
+
information = Dimension(name='information') # type: Dimension
|
.venv/Lib/site-packages/sympy/physics/units/definitions/unit_definitions.py
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.physics.units.definitions.dimension_definitions import current, temperature, amount_of_substance, \
|
| 2 |
+
luminous_intensity, angle, charge, voltage, impedance, conductance, capacitance, inductance, magnetic_density, \
|
| 3 |
+
magnetic_flux, information
|
| 4 |
+
|
| 5 |
+
from sympy.core.numbers import (Rational, pi)
|
| 6 |
+
from sympy.core.singleton import S as S_singleton
|
| 7 |
+
from sympy.physics.units.prefixes import kilo, mega, milli, micro, deci, centi, nano, pico, kibi, mebi, gibi, tebi, pebi, exbi
|
| 8 |
+
from sympy.physics.units.quantities import PhysicalConstant, Quantity
|
| 9 |
+
|
| 10 |
+
One = S_singleton.One
|
| 11 |
+
|
| 12 |
+
#### UNITS ####
|
| 13 |
+
|
| 14 |
+
# Dimensionless:
|
| 15 |
+
percent = percents = Quantity("percent", latex_repr=r"\%")
|
| 16 |
+
percent.set_global_relative_scale_factor(Rational(1, 100), One)
|
| 17 |
+
|
| 18 |
+
permille = Quantity("permille")
|
| 19 |
+
permille.set_global_relative_scale_factor(Rational(1, 1000), One)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
# Angular units (dimensionless)
|
| 23 |
+
rad = radian = radians = Quantity("radian", abbrev="rad")
|
| 24 |
+
radian.set_global_dimension(angle)
|
| 25 |
+
deg = degree = degrees = Quantity("degree", abbrev="deg", latex_repr=r"^\circ")
|
| 26 |
+
degree.set_global_relative_scale_factor(pi/180, radian)
|
| 27 |
+
sr = steradian = steradians = Quantity("steradian", abbrev="sr")
|
| 28 |
+
mil = angular_mil = angular_mils = Quantity("angular_mil", abbrev="mil")
|
| 29 |
+
|
| 30 |
+
# Base units:
|
| 31 |
+
m = meter = meters = Quantity("meter", abbrev="m")
|
| 32 |
+
|
| 33 |
+
# gram; used to define its prefixed units
|
| 34 |
+
g = gram = grams = Quantity("gram", abbrev="g")
|
| 35 |
+
|
| 36 |
+
# NOTE: the `kilogram` has scale factor 1000. In SI, kg is a base unit, but
|
| 37 |
+
# nonetheless we are trying to be compatible with the `kilo` prefix. In a
|
| 38 |
+
# similar manner, people using CGS or gaussian units could argue that the
|
| 39 |
+
# `centimeter` rather than `meter` is the fundamental unit for length, but the
|
| 40 |
+
# scale factor of `centimeter` will be kept as 1/100 to be compatible with the
|
| 41 |
+
# `centi` prefix. The current state of the code assumes SI unit dimensions, in
|
| 42 |
+
# the future this module will be modified in order to be unit system-neutral
|
| 43 |
+
# (that is, support all kinds of unit systems).
|
| 44 |
+
kg = kilogram = kilograms = Quantity("kilogram", abbrev="kg")
|
| 45 |
+
kg.set_global_relative_scale_factor(kilo, gram)
|
| 46 |
+
|
| 47 |
+
s = second = seconds = Quantity("second", abbrev="s")
|
| 48 |
+
A = ampere = amperes = Quantity("ampere", abbrev='A')
|
| 49 |
+
ampere.set_global_dimension(current)
|
| 50 |
+
K = kelvin = kelvins = Quantity("kelvin", abbrev='K')
|
| 51 |
+
kelvin.set_global_dimension(temperature)
|
| 52 |
+
mol = mole = moles = Quantity("mole", abbrev="mol")
|
| 53 |
+
mole.set_global_dimension(amount_of_substance)
|
| 54 |
+
cd = candela = candelas = Quantity("candela", abbrev="cd")
|
| 55 |
+
candela.set_global_dimension(luminous_intensity)
|
| 56 |
+
|
| 57 |
+
# derived units
|
| 58 |
+
newton = newtons = N = Quantity("newton", abbrev="N")
|
| 59 |
+
|
| 60 |
+
kilonewton = kilonewtons = kN = Quantity("kilonewton", abbrev="kN")
|
| 61 |
+
kilonewton.set_global_relative_scale_factor(kilo, newton)
|
| 62 |
+
|
| 63 |
+
meganewton = meganewtons = MN = Quantity("meganewton", abbrev="MN")
|
| 64 |
+
meganewton.set_global_relative_scale_factor(mega, newton)
|
| 65 |
+
|
| 66 |
+
joule = joules = J = Quantity("joule", abbrev="J")
|
| 67 |
+
watt = watts = W = Quantity("watt", abbrev="W")
|
| 68 |
+
pascal = pascals = Pa = pa = Quantity("pascal", abbrev="Pa")
|
| 69 |
+
hertz = hz = Hz = Quantity("hertz", abbrev="Hz")
|
| 70 |
+
|
| 71 |
+
# CGS derived units:
|
| 72 |
+
dyne = Quantity("dyne")
|
| 73 |
+
dyne.set_global_relative_scale_factor(One/10**5, newton)
|
| 74 |
+
erg = Quantity("erg")
|
| 75 |
+
erg.set_global_relative_scale_factor(One/10**7, joule)
|
| 76 |
+
|
| 77 |
+
# MKSA extension to MKS: derived units
|
| 78 |
+
coulomb = coulombs = C = Quantity("coulomb", abbrev='C')
|
| 79 |
+
coulomb.set_global_dimension(charge)
|
| 80 |
+
volt = volts = v = V = Quantity("volt", abbrev='V')
|
| 81 |
+
volt.set_global_dimension(voltage)
|
| 82 |
+
ohm = ohms = Quantity("ohm", abbrev='ohm', latex_repr=r"\Omega")
|
| 83 |
+
ohm.set_global_dimension(impedance)
|
| 84 |
+
siemens = S = mho = mhos = Quantity("siemens", abbrev='S')
|
| 85 |
+
siemens.set_global_dimension(conductance)
|
| 86 |
+
farad = farads = F = Quantity("farad", abbrev='F')
|
| 87 |
+
farad.set_global_dimension(capacitance)
|
| 88 |
+
henry = henrys = H = Quantity("henry", abbrev='H')
|
| 89 |
+
henry.set_global_dimension(inductance)
|
| 90 |
+
tesla = teslas = T = Quantity("tesla", abbrev='T')
|
| 91 |
+
tesla.set_global_dimension(magnetic_density)
|
| 92 |
+
weber = webers = Wb = wb = Quantity("weber", abbrev='Wb')
|
| 93 |
+
weber.set_global_dimension(magnetic_flux)
|
| 94 |
+
|
| 95 |
+
# CGS units for electromagnetic quantities:
|
| 96 |
+
statampere = Quantity("statampere")
|
| 97 |
+
statcoulomb = statC = franklin = Quantity("statcoulomb", abbrev="statC")
|
| 98 |
+
statvolt = Quantity("statvolt")
|
| 99 |
+
gauss = Quantity("gauss")
|
| 100 |
+
maxwell = Quantity("maxwell")
|
| 101 |
+
debye = Quantity("debye")
|
| 102 |
+
oersted = Quantity("oersted")
|
| 103 |
+
|
| 104 |
+
# Other derived units:
|
| 105 |
+
optical_power = dioptre = diopter = D = Quantity("dioptre")
|
| 106 |
+
lux = lx = Quantity("lux", abbrev="lx")
|
| 107 |
+
|
| 108 |
+
# katal is the SI unit of catalytic activity
|
| 109 |
+
katal = kat = Quantity("katal", abbrev="kat")
|
| 110 |
+
|
| 111 |
+
# gray is the SI unit of absorbed dose
|
| 112 |
+
gray = Gy = Quantity("gray")
|
| 113 |
+
|
| 114 |
+
# becquerel is the SI unit of radioactivity
|
| 115 |
+
becquerel = Bq = Quantity("becquerel", abbrev="Bq")
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
# Common mass units
|
| 119 |
+
|
| 120 |
+
mg = milligram = milligrams = Quantity("milligram", abbrev="mg")
|
| 121 |
+
mg.set_global_relative_scale_factor(milli, gram)
|
| 122 |
+
|
| 123 |
+
ug = microgram = micrograms = Quantity("microgram", abbrev="ug", latex_repr=r"\mu\text{g}")
|
| 124 |
+
ug.set_global_relative_scale_factor(micro, gram)
|
| 125 |
+
|
| 126 |
+
# Atomic mass constant
|
| 127 |
+
Da = dalton = amu = amus = atomic_mass_unit = atomic_mass_constant = PhysicalConstant("atomic_mass_constant")
|
| 128 |
+
|
| 129 |
+
t = metric_ton = tonne = Quantity("tonne", abbrev="t")
|
| 130 |
+
tonne.set_global_relative_scale_factor(mega, gram)
|
| 131 |
+
|
| 132 |
+
# Electron rest mass
|
| 133 |
+
me = electron_rest_mass = Quantity("electron_rest_mass", abbrev="me")
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
# Common length units
|
| 137 |
+
|
| 138 |
+
km = kilometer = kilometers = Quantity("kilometer", abbrev="km")
|
| 139 |
+
km.set_global_relative_scale_factor(kilo, meter)
|
| 140 |
+
|
| 141 |
+
dm = decimeter = decimeters = Quantity("decimeter", abbrev="dm")
|
| 142 |
+
dm.set_global_relative_scale_factor(deci, meter)
|
| 143 |
+
|
| 144 |
+
cm = centimeter = centimeters = Quantity("centimeter", abbrev="cm")
|
| 145 |
+
cm.set_global_relative_scale_factor(centi, meter)
|
| 146 |
+
|
| 147 |
+
mm = millimeter = millimeters = Quantity("millimeter", abbrev="mm")
|
| 148 |
+
mm.set_global_relative_scale_factor(milli, meter)
|
| 149 |
+
|
| 150 |
+
um = micrometer = micrometers = micron = microns = \
|
| 151 |
+
Quantity("micrometer", abbrev="um", latex_repr=r'\mu\text{m}')
|
| 152 |
+
um.set_global_relative_scale_factor(micro, meter)
|
| 153 |
+
|
| 154 |
+
nm = nanometer = nanometers = Quantity("nanometer", abbrev="nm")
|
| 155 |
+
nm.set_global_relative_scale_factor(nano, meter)
|
| 156 |
+
|
| 157 |
+
pm = picometer = picometers = Quantity("picometer", abbrev="pm")
|
| 158 |
+
pm.set_global_relative_scale_factor(pico, meter)
|
| 159 |
+
|
| 160 |
+
ft = foot = feet = Quantity("foot", abbrev="ft")
|
| 161 |
+
ft.set_global_relative_scale_factor(Rational(3048, 10000), meter)
|
| 162 |
+
|
| 163 |
+
inch = inches = Quantity("inch")
|
| 164 |
+
inch.set_global_relative_scale_factor(Rational(1, 12), foot)
|
| 165 |
+
|
| 166 |
+
yd = yard = yards = Quantity("yard", abbrev="yd")
|
| 167 |
+
yd.set_global_relative_scale_factor(3, feet)
|
| 168 |
+
|
| 169 |
+
mi = mile = miles = Quantity("mile")
|
| 170 |
+
mi.set_global_relative_scale_factor(5280, feet)
|
| 171 |
+
|
| 172 |
+
nmi = nautical_mile = nautical_miles = Quantity("nautical_mile")
|
| 173 |
+
nmi.set_global_relative_scale_factor(6076, feet)
|
| 174 |
+
|
| 175 |
+
angstrom = angstroms = Quantity("angstrom", latex_repr=r'\r{A}')
|
| 176 |
+
angstrom.set_global_relative_scale_factor(Rational(1, 10**10), meter)
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
# Common volume and area units
|
| 180 |
+
|
| 181 |
+
ha = hectare = Quantity("hectare", abbrev="ha")
|
| 182 |
+
|
| 183 |
+
l = L = liter = liters = Quantity("liter", abbrev="l")
|
| 184 |
+
|
| 185 |
+
dl = dL = deciliter = deciliters = Quantity("deciliter", abbrev="dl")
|
| 186 |
+
dl.set_global_relative_scale_factor(Rational(1, 10), liter)
|
| 187 |
+
|
| 188 |
+
cl = cL = centiliter = centiliters = Quantity("centiliter", abbrev="cl")
|
| 189 |
+
cl.set_global_relative_scale_factor(Rational(1, 100), liter)
|
| 190 |
+
|
| 191 |
+
ml = mL = milliliter = milliliters = Quantity("milliliter", abbrev="ml")
|
| 192 |
+
ml.set_global_relative_scale_factor(Rational(1, 1000), liter)
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
# Common time units
|
| 196 |
+
|
| 197 |
+
ms = millisecond = milliseconds = Quantity("millisecond", abbrev="ms")
|
| 198 |
+
millisecond.set_global_relative_scale_factor(milli, second)
|
| 199 |
+
|
| 200 |
+
us = microsecond = microseconds = Quantity("microsecond", abbrev="us", latex_repr=r'\mu\text{s}')
|
| 201 |
+
microsecond.set_global_relative_scale_factor(micro, second)
|
| 202 |
+
|
| 203 |
+
ns = nanosecond = nanoseconds = Quantity("nanosecond", abbrev="ns")
|
| 204 |
+
nanosecond.set_global_relative_scale_factor(nano, second)
|
| 205 |
+
|
| 206 |
+
ps = picosecond = picoseconds = Quantity("picosecond", abbrev="ps")
|
| 207 |
+
picosecond.set_global_relative_scale_factor(pico, second)
|
| 208 |
+
|
| 209 |
+
minute = minutes = Quantity("minute")
|
| 210 |
+
minute.set_global_relative_scale_factor(60, second)
|
| 211 |
+
|
| 212 |
+
h = hour = hours = Quantity("hour")
|
| 213 |
+
hour.set_global_relative_scale_factor(60, minute)
|
| 214 |
+
|
| 215 |
+
day = days = Quantity("day")
|
| 216 |
+
day.set_global_relative_scale_factor(24, hour)
|
| 217 |
+
|
| 218 |
+
anomalistic_year = anomalistic_years = Quantity("anomalistic_year")
|
| 219 |
+
anomalistic_year.set_global_relative_scale_factor(365.259636, day)
|
| 220 |
+
|
| 221 |
+
sidereal_year = sidereal_years = Quantity("sidereal_year")
|
| 222 |
+
sidereal_year.set_global_relative_scale_factor(31558149.540, seconds)
|
| 223 |
+
|
| 224 |
+
tropical_year = tropical_years = Quantity("tropical_year")
|
| 225 |
+
tropical_year.set_global_relative_scale_factor(365.24219, day)
|
| 226 |
+
|
| 227 |
+
common_year = common_years = Quantity("common_year")
|
| 228 |
+
common_year.set_global_relative_scale_factor(365, day)
|
| 229 |
+
|
| 230 |
+
julian_year = julian_years = Quantity("julian_year")
|
| 231 |
+
julian_year.set_global_relative_scale_factor((365 + One/4), day)
|
| 232 |
+
|
| 233 |
+
draconic_year = draconic_years = Quantity("draconic_year")
|
| 234 |
+
draconic_year.set_global_relative_scale_factor(346.62, day)
|
| 235 |
+
|
| 236 |
+
gaussian_year = gaussian_years = Quantity("gaussian_year")
|
| 237 |
+
gaussian_year.set_global_relative_scale_factor(365.2568983, day)
|
| 238 |
+
|
| 239 |
+
full_moon_cycle = full_moon_cycles = Quantity("full_moon_cycle")
|
| 240 |
+
full_moon_cycle.set_global_relative_scale_factor(411.78443029, day)
|
| 241 |
+
|
| 242 |
+
year = years = tropical_year
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
#### CONSTANTS ####
|
| 246 |
+
|
| 247 |
+
# Newton constant
|
| 248 |
+
G = gravitational_constant = PhysicalConstant("gravitational_constant", abbrev="G")
|
| 249 |
+
|
| 250 |
+
# speed of light
|
| 251 |
+
c = speed_of_light = PhysicalConstant("speed_of_light", abbrev="c")
|
| 252 |
+
|
| 253 |
+
# elementary charge
|
| 254 |
+
elementary_charge = PhysicalConstant("elementary_charge", abbrev="e")
|
| 255 |
+
|
| 256 |
+
# Planck constant
|
| 257 |
+
planck = PhysicalConstant("planck", abbrev="h")
|
| 258 |
+
|
| 259 |
+
# Reduced Planck constant
|
| 260 |
+
hbar = PhysicalConstant("hbar", abbrev="hbar")
|
| 261 |
+
|
| 262 |
+
# Electronvolt
|
| 263 |
+
eV = electronvolt = electronvolts = PhysicalConstant("electronvolt", abbrev="eV")
|
| 264 |
+
|
| 265 |
+
# Avogadro number
|
| 266 |
+
avogadro_number = PhysicalConstant("avogadro_number")
|
| 267 |
+
|
| 268 |
+
# Avogadro constant
|
| 269 |
+
avogadro = avogadro_constant = PhysicalConstant("avogadro_constant")
|
| 270 |
+
|
| 271 |
+
# Boltzmann constant
|
| 272 |
+
boltzmann = boltzmann_constant = PhysicalConstant("boltzmann_constant")
|
| 273 |
+
|
| 274 |
+
# Stefan-Boltzmann constant
|
| 275 |
+
stefan = stefan_boltzmann_constant = PhysicalConstant("stefan_boltzmann_constant")
|
| 276 |
+
|
| 277 |
+
# Molar gas constant
|
| 278 |
+
R = molar_gas_constant = PhysicalConstant("molar_gas_constant", abbrev="R")
|
| 279 |
+
|
| 280 |
+
# Faraday constant
|
| 281 |
+
faraday_constant = PhysicalConstant("faraday_constant")
|
| 282 |
+
|
| 283 |
+
# Josephson constant
|
| 284 |
+
josephson_constant = PhysicalConstant("josephson_constant", abbrev="K_j")
|
| 285 |
+
|
| 286 |
+
# Von Klitzing constant
|
| 287 |
+
von_klitzing_constant = PhysicalConstant("von_klitzing_constant", abbrev="R_k")
|
| 288 |
+
|
| 289 |
+
# Acceleration due to gravity (on the Earth surface)
|
| 290 |
+
gee = gees = acceleration_due_to_gravity = PhysicalConstant("acceleration_due_to_gravity", abbrev="g")
|
| 291 |
+
|
| 292 |
+
# magnetic constant:
|
| 293 |
+
u0 = magnetic_constant = vacuum_permeability = PhysicalConstant("magnetic_constant")
|
| 294 |
+
|
| 295 |
+
# electric constat:
|
| 296 |
+
e0 = electric_constant = vacuum_permittivity = PhysicalConstant("vacuum_permittivity")
|
| 297 |
+
|
| 298 |
+
# vacuum impedance:
|
| 299 |
+
Z0 = vacuum_impedance = PhysicalConstant("vacuum_impedance", abbrev='Z_0', latex_repr=r'Z_{0}')
|
| 300 |
+
|
| 301 |
+
# Coulomb's constant:
|
| 302 |
+
coulomb_constant = coulombs_constant = electric_force_constant = \
|
| 303 |
+
PhysicalConstant("coulomb_constant", abbrev="k_e")
|
| 304 |
+
|
| 305 |
+
|
| 306 |
+
atmosphere = atmospheres = atm = Quantity("atmosphere", abbrev="atm")
|
| 307 |
+
|
| 308 |
+
kPa = kilopascal = Quantity("kilopascal", abbrev="kPa")
|
| 309 |
+
kilopascal.set_global_relative_scale_factor(kilo, Pa)
|
| 310 |
+
|
| 311 |
+
bar = bars = Quantity("bar", abbrev="bar")
|
| 312 |
+
|
| 313 |
+
pound = pounds = Quantity("pound") # exact
|
| 314 |
+
|
| 315 |
+
psi = Quantity("psi")
|
| 316 |
+
|
| 317 |
+
dHg0 = 13.5951 # approx value at 0 C
|
| 318 |
+
mmHg = torr = Quantity("mmHg")
|
| 319 |
+
|
| 320 |
+
atmosphere.set_global_relative_scale_factor(101325, pascal)
|
| 321 |
+
bar.set_global_relative_scale_factor(100, kPa)
|
| 322 |
+
pound.set_global_relative_scale_factor(Rational(45359237, 100000000), kg)
|
| 323 |
+
|
| 324 |
+
mmu = mmus = milli_mass_unit = Quantity("milli_mass_unit")
|
| 325 |
+
|
| 326 |
+
quart = quarts = Quantity("quart")
|
| 327 |
+
|
| 328 |
+
|
| 329 |
+
# Other convenient units and magnitudes
|
| 330 |
+
|
| 331 |
+
ly = lightyear = lightyears = Quantity("lightyear", abbrev="ly")
|
| 332 |
+
|
| 333 |
+
au = astronomical_unit = astronomical_units = Quantity("astronomical_unit", abbrev="AU")
|
| 334 |
+
|
| 335 |
+
|
| 336 |
+
# Fundamental Planck units:
|
| 337 |
+
planck_mass = Quantity("planck_mass", abbrev="m_P", latex_repr=r'm_\text{P}')
|
| 338 |
+
|
| 339 |
+
planck_time = Quantity("planck_time", abbrev="t_P", latex_repr=r't_\text{P}')
|
| 340 |
+
|
| 341 |
+
planck_temperature = Quantity("planck_temperature", abbrev="T_P",
|
| 342 |
+
latex_repr=r'T_\text{P}')
|
| 343 |
+
|
| 344 |
+
planck_length = Quantity("planck_length", abbrev="l_P", latex_repr=r'l_\text{P}')
|
| 345 |
+
|
| 346 |
+
planck_charge = Quantity("planck_charge", abbrev="q_P", latex_repr=r'q_\text{P}')
|
| 347 |
+
|
| 348 |
+
|
| 349 |
+
# Derived Planck units:
|
| 350 |
+
planck_area = Quantity("planck_area")
|
| 351 |
+
|
| 352 |
+
planck_volume = Quantity("planck_volume")
|
| 353 |
+
|
| 354 |
+
planck_momentum = Quantity("planck_momentum")
|
| 355 |
+
|
| 356 |
+
planck_energy = Quantity("planck_energy", abbrev="E_P", latex_repr=r'E_\text{P}')
|
| 357 |
+
|
| 358 |
+
planck_force = Quantity("planck_force", abbrev="F_P", latex_repr=r'F_\text{P}')
|
| 359 |
+
|
| 360 |
+
planck_power = Quantity("planck_power", abbrev="P_P", latex_repr=r'P_\text{P}')
|
| 361 |
+
|
| 362 |
+
planck_density = Quantity("planck_density", abbrev="rho_P", latex_repr=r'\rho_\text{P}')
|
| 363 |
+
|
| 364 |
+
planck_energy_density = Quantity("planck_energy_density", abbrev="rho^E_P")
|
| 365 |
+
|
| 366 |
+
planck_intensity = Quantity("planck_intensity", abbrev="I_P", latex_repr=r'I_\text{P}')
|
| 367 |
+
|
| 368 |
+
planck_angular_frequency = Quantity("planck_angular_frequency", abbrev="omega_P",
|
| 369 |
+
latex_repr=r'\omega_\text{P}')
|
| 370 |
+
|
| 371 |
+
planck_pressure = Quantity("planck_pressure", abbrev="p_P", latex_repr=r'p_\text{P}')
|
| 372 |
+
|
| 373 |
+
planck_current = Quantity("planck_current", abbrev="I_P", latex_repr=r'I_\text{P}')
|
| 374 |
+
|
| 375 |
+
planck_voltage = Quantity("planck_voltage", abbrev="V_P", latex_repr=r'V_\text{P}')
|
| 376 |
+
|
| 377 |
+
planck_impedance = Quantity("planck_impedance", abbrev="Z_P", latex_repr=r'Z_\text{P}')
|
| 378 |
+
|
| 379 |
+
planck_acceleration = Quantity("planck_acceleration", abbrev="a_P",
|
| 380 |
+
latex_repr=r'a_\text{P}')
|
| 381 |
+
|
| 382 |
+
|
| 383 |
+
# Information theory units:
|
| 384 |
+
bit = bits = Quantity("bit")
|
| 385 |
+
bit.set_global_dimension(information)
|
| 386 |
+
|
| 387 |
+
byte = bytes = Quantity("byte")
|
| 388 |
+
|
| 389 |
+
kibibyte = kibibytes = Quantity("kibibyte")
|
| 390 |
+
mebibyte = mebibytes = Quantity("mebibyte")
|
| 391 |
+
gibibyte = gibibytes = Quantity("gibibyte")
|
| 392 |
+
tebibyte = tebibytes = Quantity("tebibyte")
|
| 393 |
+
pebibyte = pebibytes = Quantity("pebibyte")
|
| 394 |
+
exbibyte = exbibytes = Quantity("exbibyte")
|
| 395 |
+
|
| 396 |
+
byte.set_global_relative_scale_factor(8, bit)
|
| 397 |
+
kibibyte.set_global_relative_scale_factor(kibi, byte)
|
| 398 |
+
mebibyte.set_global_relative_scale_factor(mebi, byte)
|
| 399 |
+
gibibyte.set_global_relative_scale_factor(gibi, byte)
|
| 400 |
+
tebibyte.set_global_relative_scale_factor(tebi, byte)
|
| 401 |
+
pebibyte.set_global_relative_scale_factor(pebi, byte)
|
| 402 |
+
exbibyte.set_global_relative_scale_factor(exbi, byte)
|
| 403 |
+
|
| 404 |
+
# Older units for radioactivity
|
| 405 |
+
curie = Ci = Quantity("curie", abbrev="Ci")
|
| 406 |
+
|
| 407 |
+
rutherford = Rd = Quantity("rutherford", abbrev="Rd")
|
.venv/Lib/site-packages/sympy/physics/units/dimensions.py
ADDED
|
@@ -0,0 +1,590 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Definition of physical dimensions.
|
| 3 |
+
|
| 4 |
+
Unit systems will be constructed on top of these dimensions.
|
| 5 |
+
|
| 6 |
+
Most of the examples in the doc use MKS system and are presented from the
|
| 7 |
+
computer point of view: from a human point, adding length to time is not legal
|
| 8 |
+
in MKS but it is in natural system; for a computer in natural system there is
|
| 9 |
+
no time dimension (but a velocity dimension instead) - in the basis - so the
|
| 10 |
+
question of adding time to length has no meaning.
|
| 11 |
+
"""
|
| 12 |
+
|
| 13 |
+
from __future__ import annotations
|
| 14 |
+
|
| 15 |
+
import collections
|
| 16 |
+
from functools import reduce
|
| 17 |
+
|
| 18 |
+
from sympy.core.basic import Basic
|
| 19 |
+
from sympy.core.containers import (Dict, Tuple)
|
| 20 |
+
from sympy.core.singleton import S
|
| 21 |
+
from sympy.core.sorting import default_sort_key
|
| 22 |
+
from sympy.core.symbol import Symbol
|
| 23 |
+
from sympy.core.sympify import sympify
|
| 24 |
+
from sympy.matrices.dense import Matrix
|
| 25 |
+
from sympy.functions.elementary.trigonometric import TrigonometricFunction
|
| 26 |
+
from sympy.core.expr import Expr
|
| 27 |
+
from sympy.core.power import Pow
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
class _QuantityMapper:
|
| 31 |
+
|
| 32 |
+
_quantity_scale_factors_global: dict[Expr, Expr] = {}
|
| 33 |
+
_quantity_dimensional_equivalence_map_global: dict[Expr, Expr] = {}
|
| 34 |
+
_quantity_dimension_global: dict[Expr, Expr] = {}
|
| 35 |
+
|
| 36 |
+
def __init__(self, *args, **kwargs):
|
| 37 |
+
self._quantity_dimension_map = {}
|
| 38 |
+
self._quantity_scale_factors = {}
|
| 39 |
+
|
| 40 |
+
def set_quantity_dimension(self, quantity, dimension):
|
| 41 |
+
"""
|
| 42 |
+
Set the dimension for the quantity in a unit system.
|
| 43 |
+
|
| 44 |
+
If this relation is valid in every unit system, use
|
| 45 |
+
``quantity.set_global_dimension(dimension)`` instead.
|
| 46 |
+
"""
|
| 47 |
+
from sympy.physics.units import Quantity
|
| 48 |
+
dimension = sympify(dimension)
|
| 49 |
+
if not isinstance(dimension, Dimension):
|
| 50 |
+
if dimension == 1:
|
| 51 |
+
dimension = Dimension(1)
|
| 52 |
+
else:
|
| 53 |
+
raise ValueError("expected dimension or 1")
|
| 54 |
+
elif isinstance(dimension, Quantity):
|
| 55 |
+
dimension = self.get_quantity_dimension(dimension)
|
| 56 |
+
self._quantity_dimension_map[quantity] = dimension
|
| 57 |
+
|
| 58 |
+
def set_quantity_scale_factor(self, quantity, scale_factor):
|
| 59 |
+
"""
|
| 60 |
+
Set the scale factor of a quantity relative to another quantity.
|
| 61 |
+
|
| 62 |
+
It should be used only once per quantity to just one other quantity,
|
| 63 |
+
the algorithm will then be able to compute the scale factors to all
|
| 64 |
+
other quantities.
|
| 65 |
+
|
| 66 |
+
In case the scale factor is valid in every unit system, please use
|
| 67 |
+
``quantity.set_global_relative_scale_factor(scale_factor)`` instead.
|
| 68 |
+
"""
|
| 69 |
+
from sympy.physics.units import Quantity
|
| 70 |
+
from sympy.physics.units.prefixes import Prefix
|
| 71 |
+
scale_factor = sympify(scale_factor)
|
| 72 |
+
# replace all prefixes by their ratio to canonical units:
|
| 73 |
+
scale_factor = scale_factor.replace(
|
| 74 |
+
lambda x: isinstance(x, Prefix),
|
| 75 |
+
lambda x: x.scale_factor
|
| 76 |
+
)
|
| 77 |
+
# replace all quantities by their ratio to canonical units:
|
| 78 |
+
scale_factor = scale_factor.replace(
|
| 79 |
+
lambda x: isinstance(x, Quantity),
|
| 80 |
+
lambda x: self.get_quantity_scale_factor(x)
|
| 81 |
+
)
|
| 82 |
+
self._quantity_scale_factors[quantity] = scale_factor
|
| 83 |
+
|
| 84 |
+
def get_quantity_dimension(self, unit):
|
| 85 |
+
from sympy.physics.units import Quantity
|
| 86 |
+
# First look-up the local dimension map, then the global one:
|
| 87 |
+
if unit in self._quantity_dimension_map:
|
| 88 |
+
return self._quantity_dimension_map[unit]
|
| 89 |
+
if unit in self._quantity_dimension_global:
|
| 90 |
+
return self._quantity_dimension_global[unit]
|
| 91 |
+
if unit in self._quantity_dimensional_equivalence_map_global:
|
| 92 |
+
dep_unit = self._quantity_dimensional_equivalence_map_global[unit]
|
| 93 |
+
if isinstance(dep_unit, Quantity):
|
| 94 |
+
return self.get_quantity_dimension(dep_unit)
|
| 95 |
+
else:
|
| 96 |
+
return Dimension(self.get_dimensional_expr(dep_unit))
|
| 97 |
+
if isinstance(unit, Quantity):
|
| 98 |
+
return Dimension(unit.name)
|
| 99 |
+
else:
|
| 100 |
+
return Dimension(1)
|
| 101 |
+
|
| 102 |
+
def get_quantity_scale_factor(self, unit):
|
| 103 |
+
if unit in self._quantity_scale_factors:
|
| 104 |
+
return self._quantity_scale_factors[unit]
|
| 105 |
+
if unit in self._quantity_scale_factors_global:
|
| 106 |
+
mul_factor, other_unit = self._quantity_scale_factors_global[unit]
|
| 107 |
+
return mul_factor*self.get_quantity_scale_factor(other_unit)
|
| 108 |
+
return S.One
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
class Dimension(Expr):
|
| 112 |
+
"""
|
| 113 |
+
This class represent the dimension of a physical quantities.
|
| 114 |
+
|
| 115 |
+
The ``Dimension`` constructor takes as parameters a name and an optional
|
| 116 |
+
symbol.
|
| 117 |
+
|
| 118 |
+
For example, in classical mechanics we know that time is different from
|
| 119 |
+
temperature and dimensions make this difference (but they do not provide
|
| 120 |
+
any measure of these quantites.
|
| 121 |
+
|
| 122 |
+
>>> from sympy.physics.units import Dimension
|
| 123 |
+
>>> length = Dimension('length')
|
| 124 |
+
>>> length
|
| 125 |
+
Dimension(length)
|
| 126 |
+
>>> time = Dimension('time')
|
| 127 |
+
>>> time
|
| 128 |
+
Dimension(time)
|
| 129 |
+
|
| 130 |
+
Dimensions can be composed using multiplication, division and
|
| 131 |
+
exponentiation (by a number) to give new dimensions. Addition and
|
| 132 |
+
subtraction is defined only when the two objects are the same dimension.
|
| 133 |
+
|
| 134 |
+
>>> velocity = length / time
|
| 135 |
+
>>> velocity
|
| 136 |
+
Dimension(length/time)
|
| 137 |
+
|
| 138 |
+
It is possible to use a dimension system object to get the dimensionsal
|
| 139 |
+
dependencies of a dimension, for example the dimension system used by the
|
| 140 |
+
SI units convention can be used:
|
| 141 |
+
|
| 142 |
+
>>> from sympy.physics.units.systems.si import dimsys_SI
|
| 143 |
+
>>> dimsys_SI.get_dimensional_dependencies(velocity)
|
| 144 |
+
{Dimension(length, L): 1, Dimension(time, T): -1}
|
| 145 |
+
>>> length + length
|
| 146 |
+
Dimension(length)
|
| 147 |
+
>>> l2 = length**2
|
| 148 |
+
>>> l2
|
| 149 |
+
Dimension(length**2)
|
| 150 |
+
>>> dimsys_SI.get_dimensional_dependencies(l2)
|
| 151 |
+
{Dimension(length, L): 2}
|
| 152 |
+
|
| 153 |
+
"""
|
| 154 |
+
|
| 155 |
+
_op_priority = 13.0
|
| 156 |
+
|
| 157 |
+
# XXX: This doesn't seem to be used anywhere...
|
| 158 |
+
_dimensional_dependencies = {} # type: ignore
|
| 159 |
+
|
| 160 |
+
is_commutative = True
|
| 161 |
+
is_number = False
|
| 162 |
+
# make sqrt(M**2) --> M
|
| 163 |
+
is_positive = True
|
| 164 |
+
is_real = True
|
| 165 |
+
|
| 166 |
+
def __new__(cls, name, symbol=None):
|
| 167 |
+
|
| 168 |
+
if isinstance(name, str):
|
| 169 |
+
name = Symbol(name)
|
| 170 |
+
else:
|
| 171 |
+
name = sympify(name)
|
| 172 |
+
|
| 173 |
+
if not isinstance(name, Expr):
|
| 174 |
+
raise TypeError("Dimension name needs to be a valid math expression")
|
| 175 |
+
|
| 176 |
+
if isinstance(symbol, str):
|
| 177 |
+
symbol = Symbol(symbol)
|
| 178 |
+
elif symbol is not None:
|
| 179 |
+
assert isinstance(symbol, Symbol)
|
| 180 |
+
|
| 181 |
+
obj = Expr.__new__(cls, name)
|
| 182 |
+
|
| 183 |
+
obj._name = name
|
| 184 |
+
obj._symbol = symbol
|
| 185 |
+
return obj
|
| 186 |
+
|
| 187 |
+
@property
|
| 188 |
+
def name(self):
|
| 189 |
+
return self._name
|
| 190 |
+
|
| 191 |
+
@property
|
| 192 |
+
def symbol(self):
|
| 193 |
+
return self._symbol
|
| 194 |
+
|
| 195 |
+
def __str__(self):
|
| 196 |
+
"""
|
| 197 |
+
Display the string representation of the dimension.
|
| 198 |
+
"""
|
| 199 |
+
if self.symbol is None:
|
| 200 |
+
return "Dimension(%s)" % (self.name)
|
| 201 |
+
else:
|
| 202 |
+
return "Dimension(%s, %s)" % (self.name, self.symbol)
|
| 203 |
+
|
| 204 |
+
def __repr__(self):
|
| 205 |
+
return self.__str__()
|
| 206 |
+
|
| 207 |
+
def __neg__(self):
|
| 208 |
+
return self
|
| 209 |
+
|
| 210 |
+
def __add__(self, other):
|
| 211 |
+
from sympy.physics.units.quantities import Quantity
|
| 212 |
+
other = sympify(other)
|
| 213 |
+
if isinstance(other, Basic):
|
| 214 |
+
if other.has(Quantity):
|
| 215 |
+
raise TypeError("cannot sum dimension and quantity")
|
| 216 |
+
if isinstance(other, Dimension) and self == other:
|
| 217 |
+
return self
|
| 218 |
+
return super().__add__(other)
|
| 219 |
+
return self
|
| 220 |
+
|
| 221 |
+
def __radd__(self, other):
|
| 222 |
+
return self.__add__(other)
|
| 223 |
+
|
| 224 |
+
def __sub__(self, other):
|
| 225 |
+
# there is no notion of ordering (or magnitude) among dimension,
|
| 226 |
+
# subtraction is equivalent to addition when the operation is legal
|
| 227 |
+
return self + other
|
| 228 |
+
|
| 229 |
+
def __rsub__(self, other):
|
| 230 |
+
# there is no notion of ordering (or magnitude) among dimension,
|
| 231 |
+
# subtraction is equivalent to addition when the operation is legal
|
| 232 |
+
return self + other
|
| 233 |
+
|
| 234 |
+
def __pow__(self, other):
|
| 235 |
+
return self._eval_power(other)
|
| 236 |
+
|
| 237 |
+
def _eval_power(self, other):
|
| 238 |
+
other = sympify(other)
|
| 239 |
+
return Dimension(self.name**other)
|
| 240 |
+
|
| 241 |
+
def __mul__(self, other):
|
| 242 |
+
from sympy.physics.units.quantities import Quantity
|
| 243 |
+
if isinstance(other, Basic):
|
| 244 |
+
if other.has(Quantity):
|
| 245 |
+
raise TypeError("cannot sum dimension and quantity")
|
| 246 |
+
if isinstance(other, Dimension):
|
| 247 |
+
return Dimension(self.name*other.name)
|
| 248 |
+
if not other.free_symbols: # other.is_number cannot be used
|
| 249 |
+
return self
|
| 250 |
+
return super().__mul__(other)
|
| 251 |
+
return self
|
| 252 |
+
|
| 253 |
+
def __rmul__(self, other):
|
| 254 |
+
return self.__mul__(other)
|
| 255 |
+
|
| 256 |
+
def __truediv__(self, other):
|
| 257 |
+
return self*Pow(other, -1)
|
| 258 |
+
|
| 259 |
+
def __rtruediv__(self, other):
|
| 260 |
+
return other * pow(self, -1)
|
| 261 |
+
|
| 262 |
+
@classmethod
|
| 263 |
+
def _from_dimensional_dependencies(cls, dependencies):
|
| 264 |
+
return reduce(lambda x, y: x * y, (
|
| 265 |
+
d**e for d, e in dependencies.items()
|
| 266 |
+
), 1)
|
| 267 |
+
|
| 268 |
+
def has_integer_powers(self, dim_sys):
|
| 269 |
+
"""
|
| 270 |
+
Check if the dimension object has only integer powers.
|
| 271 |
+
|
| 272 |
+
All the dimension powers should be integers, but rational powers may
|
| 273 |
+
appear in intermediate steps. This method may be used to check that the
|
| 274 |
+
final result is well-defined.
|
| 275 |
+
"""
|
| 276 |
+
|
| 277 |
+
return all(dpow.is_Integer for dpow in dim_sys.get_dimensional_dependencies(self).values())
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
# Create dimensions according to the base units in MKSA.
|
| 281 |
+
# For other unit systems, they can be derived by transforming the base
|
| 282 |
+
# dimensional dependency dictionary.
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
class DimensionSystem(Basic, _QuantityMapper):
|
| 286 |
+
r"""
|
| 287 |
+
DimensionSystem represents a coherent set of dimensions.
|
| 288 |
+
|
| 289 |
+
The constructor takes three parameters:
|
| 290 |
+
|
| 291 |
+
- base dimensions;
|
| 292 |
+
- derived dimensions: these are defined in terms of the base dimensions
|
| 293 |
+
(for example velocity is defined from the division of length by time);
|
| 294 |
+
- dependency of dimensions: how the derived dimensions depend
|
| 295 |
+
on the base dimensions.
|
| 296 |
+
|
| 297 |
+
Optionally either the ``derived_dims`` or the ``dimensional_dependencies``
|
| 298 |
+
may be omitted.
|
| 299 |
+
"""
|
| 300 |
+
|
| 301 |
+
def __new__(cls, base_dims, derived_dims=(), dimensional_dependencies={}):
|
| 302 |
+
dimensional_dependencies = dict(dimensional_dependencies)
|
| 303 |
+
|
| 304 |
+
def parse_dim(dim):
|
| 305 |
+
if isinstance(dim, str):
|
| 306 |
+
dim = Dimension(Symbol(dim))
|
| 307 |
+
elif isinstance(dim, Dimension):
|
| 308 |
+
pass
|
| 309 |
+
elif isinstance(dim, Symbol):
|
| 310 |
+
dim = Dimension(dim)
|
| 311 |
+
else:
|
| 312 |
+
raise TypeError("%s wrong type" % dim)
|
| 313 |
+
return dim
|
| 314 |
+
|
| 315 |
+
base_dims = [parse_dim(i) for i in base_dims]
|
| 316 |
+
derived_dims = [parse_dim(i) for i in derived_dims]
|
| 317 |
+
|
| 318 |
+
for dim in base_dims:
|
| 319 |
+
if (dim in dimensional_dependencies
|
| 320 |
+
and (len(dimensional_dependencies[dim]) != 1 or
|
| 321 |
+
dimensional_dependencies[dim].get(dim, None) != 1)):
|
| 322 |
+
raise IndexError("Repeated value in base dimensions")
|
| 323 |
+
dimensional_dependencies[dim] = Dict({dim: 1})
|
| 324 |
+
|
| 325 |
+
def parse_dim_name(dim):
|
| 326 |
+
if isinstance(dim, Dimension):
|
| 327 |
+
return dim
|
| 328 |
+
elif isinstance(dim, str):
|
| 329 |
+
return Dimension(Symbol(dim))
|
| 330 |
+
elif isinstance(dim, Symbol):
|
| 331 |
+
return Dimension(dim)
|
| 332 |
+
else:
|
| 333 |
+
raise TypeError("unrecognized type %s for %s" % (type(dim), dim))
|
| 334 |
+
|
| 335 |
+
for dim in dimensional_dependencies.keys():
|
| 336 |
+
dim = parse_dim(dim)
|
| 337 |
+
if (dim not in derived_dims) and (dim not in base_dims):
|
| 338 |
+
derived_dims.append(dim)
|
| 339 |
+
|
| 340 |
+
def parse_dict(d):
|
| 341 |
+
return Dict({parse_dim_name(i): j for i, j in d.items()})
|
| 342 |
+
|
| 343 |
+
# Make sure everything is a SymPy type:
|
| 344 |
+
dimensional_dependencies = {parse_dim_name(i): parse_dict(j) for i, j in
|
| 345 |
+
dimensional_dependencies.items()}
|
| 346 |
+
|
| 347 |
+
for dim in derived_dims:
|
| 348 |
+
if dim in base_dims:
|
| 349 |
+
raise ValueError("Dimension %s both in base and derived" % dim)
|
| 350 |
+
if dim not in dimensional_dependencies:
|
| 351 |
+
# TODO: should this raise a warning?
|
| 352 |
+
dimensional_dependencies[dim] = Dict({dim: 1})
|
| 353 |
+
|
| 354 |
+
base_dims.sort(key=default_sort_key)
|
| 355 |
+
derived_dims.sort(key=default_sort_key)
|
| 356 |
+
|
| 357 |
+
base_dims = Tuple(*base_dims)
|
| 358 |
+
derived_dims = Tuple(*derived_dims)
|
| 359 |
+
dimensional_dependencies = Dict({i: Dict(j) for i, j in dimensional_dependencies.items()})
|
| 360 |
+
obj = Basic.__new__(cls, base_dims, derived_dims, dimensional_dependencies)
|
| 361 |
+
return obj
|
| 362 |
+
|
| 363 |
+
@property
|
| 364 |
+
def base_dims(self):
|
| 365 |
+
return self.args[0]
|
| 366 |
+
|
| 367 |
+
@property
|
| 368 |
+
def derived_dims(self):
|
| 369 |
+
return self.args[1]
|
| 370 |
+
|
| 371 |
+
@property
|
| 372 |
+
def dimensional_dependencies(self):
|
| 373 |
+
return self.args[2]
|
| 374 |
+
|
| 375 |
+
def _get_dimensional_dependencies_for_name(self, dimension):
|
| 376 |
+
if isinstance(dimension, str):
|
| 377 |
+
dimension = Dimension(Symbol(dimension))
|
| 378 |
+
elif not isinstance(dimension, Dimension):
|
| 379 |
+
dimension = Dimension(dimension)
|
| 380 |
+
|
| 381 |
+
if dimension.name.is_Symbol:
|
| 382 |
+
# Dimensions not included in the dependencies are considered
|
| 383 |
+
# as base dimensions:
|
| 384 |
+
return dict(self.dimensional_dependencies.get(dimension, {dimension: 1}))
|
| 385 |
+
|
| 386 |
+
if dimension.name.is_number or dimension.name.is_NumberSymbol:
|
| 387 |
+
return {}
|
| 388 |
+
|
| 389 |
+
get_for_name = self._get_dimensional_dependencies_for_name
|
| 390 |
+
|
| 391 |
+
if dimension.name.is_Mul:
|
| 392 |
+
ret = collections.defaultdict(int)
|
| 393 |
+
dicts = [get_for_name(i) for i in dimension.name.args]
|
| 394 |
+
for d in dicts:
|
| 395 |
+
for k, v in d.items():
|
| 396 |
+
ret[k] += v
|
| 397 |
+
return {k: v for (k, v) in ret.items() if v != 0}
|
| 398 |
+
|
| 399 |
+
if dimension.name.is_Add:
|
| 400 |
+
dicts = [get_for_name(i) for i in dimension.name.args]
|
| 401 |
+
if all(d == dicts[0] for d in dicts[1:]):
|
| 402 |
+
return dicts[0]
|
| 403 |
+
raise TypeError("Only equivalent dimensions can be added or subtracted.")
|
| 404 |
+
|
| 405 |
+
if dimension.name.is_Pow:
|
| 406 |
+
dim_base = get_for_name(dimension.name.base)
|
| 407 |
+
dim_exp = get_for_name(dimension.name.exp)
|
| 408 |
+
if dim_exp == {} or dimension.name.exp.is_Symbol:
|
| 409 |
+
return {k: v * dimension.name.exp for (k, v) in dim_base.items()}
|
| 410 |
+
else:
|
| 411 |
+
raise TypeError("The exponent for the power operator must be a Symbol or dimensionless.")
|
| 412 |
+
|
| 413 |
+
if dimension.name.is_Function:
|
| 414 |
+
args = (Dimension._from_dimensional_dependencies(
|
| 415 |
+
get_for_name(arg)) for arg in dimension.name.args)
|
| 416 |
+
result = dimension.name.func(*args)
|
| 417 |
+
|
| 418 |
+
dicts = [get_for_name(i) for i in dimension.name.args]
|
| 419 |
+
|
| 420 |
+
if isinstance(result, Dimension):
|
| 421 |
+
return self.get_dimensional_dependencies(result)
|
| 422 |
+
elif result.func == dimension.name.func:
|
| 423 |
+
if isinstance(dimension.name, TrigonometricFunction):
|
| 424 |
+
if dicts[0] in ({}, {Dimension('angle'): 1}):
|
| 425 |
+
return {}
|
| 426 |
+
else:
|
| 427 |
+
raise TypeError("The input argument for the function {} must be dimensionless or have dimensions of angle.".format(dimension.func))
|
| 428 |
+
else:
|
| 429 |
+
if all(item == {} for item in dicts):
|
| 430 |
+
return {}
|
| 431 |
+
else:
|
| 432 |
+
raise TypeError("The input arguments for the function {} must be dimensionless.".format(dimension.func))
|
| 433 |
+
else:
|
| 434 |
+
return get_for_name(result)
|
| 435 |
+
|
| 436 |
+
raise TypeError("Type {} not implemented for get_dimensional_dependencies".format(type(dimension.name)))
|
| 437 |
+
|
| 438 |
+
def get_dimensional_dependencies(self, name, mark_dimensionless=False):
|
| 439 |
+
dimdep = self._get_dimensional_dependencies_for_name(name)
|
| 440 |
+
if mark_dimensionless and dimdep == {}:
|
| 441 |
+
return {Dimension(1): 1}
|
| 442 |
+
return dict(dimdep.items())
|
| 443 |
+
|
| 444 |
+
def equivalent_dims(self, dim1, dim2):
|
| 445 |
+
deps1 = self.get_dimensional_dependencies(dim1)
|
| 446 |
+
deps2 = self.get_dimensional_dependencies(dim2)
|
| 447 |
+
return deps1 == deps2
|
| 448 |
+
|
| 449 |
+
def extend(self, new_base_dims, new_derived_dims=(), new_dim_deps=None):
|
| 450 |
+
deps = dict(self.dimensional_dependencies)
|
| 451 |
+
if new_dim_deps:
|
| 452 |
+
deps.update(new_dim_deps)
|
| 453 |
+
|
| 454 |
+
new_dim_sys = DimensionSystem(
|
| 455 |
+
tuple(self.base_dims) + tuple(new_base_dims),
|
| 456 |
+
tuple(self.derived_dims) + tuple(new_derived_dims),
|
| 457 |
+
deps
|
| 458 |
+
)
|
| 459 |
+
new_dim_sys._quantity_dimension_map.update(self._quantity_dimension_map)
|
| 460 |
+
new_dim_sys._quantity_scale_factors.update(self._quantity_scale_factors)
|
| 461 |
+
return new_dim_sys
|
| 462 |
+
|
| 463 |
+
def is_dimensionless(self, dimension):
|
| 464 |
+
"""
|
| 465 |
+
Check if the dimension object really has a dimension.
|
| 466 |
+
|
| 467 |
+
A dimension should have at least one component with non-zero power.
|
| 468 |
+
"""
|
| 469 |
+
if dimension.name == 1:
|
| 470 |
+
return True
|
| 471 |
+
return self.get_dimensional_dependencies(dimension) == {}
|
| 472 |
+
|
| 473 |
+
@property
|
| 474 |
+
def list_can_dims(self):
|
| 475 |
+
"""
|
| 476 |
+
Useless method, kept for compatibility with previous versions.
|
| 477 |
+
|
| 478 |
+
DO NOT USE.
|
| 479 |
+
|
| 480 |
+
List all canonical dimension names.
|
| 481 |
+
"""
|
| 482 |
+
dimset = set()
|
| 483 |
+
for i in self.base_dims:
|
| 484 |
+
dimset.update(set(self.get_dimensional_dependencies(i).keys()))
|
| 485 |
+
return tuple(sorted(dimset, key=str))
|
| 486 |
+
|
| 487 |
+
@property
|
| 488 |
+
def inv_can_transf_matrix(self):
|
| 489 |
+
"""
|
| 490 |
+
Useless method, kept for compatibility with previous versions.
|
| 491 |
+
|
| 492 |
+
DO NOT USE.
|
| 493 |
+
|
| 494 |
+
Compute the inverse transformation matrix from the base to the
|
| 495 |
+
canonical dimension basis.
|
| 496 |
+
|
| 497 |
+
It corresponds to the matrix where columns are the vector of base
|
| 498 |
+
dimensions in canonical basis.
|
| 499 |
+
|
| 500 |
+
This matrix will almost never be used because dimensions are always
|
| 501 |
+
defined with respect to the canonical basis, so no work has to be done
|
| 502 |
+
to get them in this basis. Nonetheless if this matrix is not square
|
| 503 |
+
(or not invertible) it means that we have chosen a bad basis.
|
| 504 |
+
"""
|
| 505 |
+
matrix = reduce(lambda x, y: x.row_join(y),
|
| 506 |
+
[self.dim_can_vector(d) for d in self.base_dims])
|
| 507 |
+
return matrix
|
| 508 |
+
|
| 509 |
+
@property
|
| 510 |
+
def can_transf_matrix(self):
|
| 511 |
+
"""
|
| 512 |
+
Useless method, kept for compatibility with previous versions.
|
| 513 |
+
|
| 514 |
+
DO NOT USE.
|
| 515 |
+
|
| 516 |
+
Return the canonical transformation matrix from the canonical to the
|
| 517 |
+
base dimension basis.
|
| 518 |
+
|
| 519 |
+
It is the inverse of the matrix computed with inv_can_transf_matrix().
|
| 520 |
+
"""
|
| 521 |
+
|
| 522 |
+
#TODO: the inversion will fail if the system is inconsistent, for
|
| 523 |
+
# example if the matrix is not a square
|
| 524 |
+
return reduce(lambda x, y: x.row_join(y),
|
| 525 |
+
[self.dim_can_vector(d) for d in sorted(self.base_dims, key=str)]
|
| 526 |
+
).inv()
|
| 527 |
+
|
| 528 |
+
def dim_can_vector(self, dim):
|
| 529 |
+
"""
|
| 530 |
+
Useless method, kept for compatibility with previous versions.
|
| 531 |
+
|
| 532 |
+
DO NOT USE.
|
| 533 |
+
|
| 534 |
+
Dimensional representation in terms of the canonical base dimensions.
|
| 535 |
+
"""
|
| 536 |
+
|
| 537 |
+
vec = []
|
| 538 |
+
for d in self.list_can_dims:
|
| 539 |
+
vec.append(self.get_dimensional_dependencies(dim).get(d, 0))
|
| 540 |
+
return Matrix(vec)
|
| 541 |
+
|
| 542 |
+
def dim_vector(self, dim):
|
| 543 |
+
"""
|
| 544 |
+
Useless method, kept for compatibility with previous versions.
|
| 545 |
+
|
| 546 |
+
DO NOT USE.
|
| 547 |
+
|
| 548 |
+
|
| 549 |
+
Vector representation in terms of the base dimensions.
|
| 550 |
+
"""
|
| 551 |
+
return self.can_transf_matrix * Matrix(self.dim_can_vector(dim))
|
| 552 |
+
|
| 553 |
+
def print_dim_base(self, dim):
|
| 554 |
+
"""
|
| 555 |
+
Give the string expression of a dimension in term of the basis symbols.
|
| 556 |
+
"""
|
| 557 |
+
dims = self.dim_vector(dim)
|
| 558 |
+
symbols = [i.symbol if i.symbol is not None else i.name for i in self.base_dims]
|
| 559 |
+
res = S.One
|
| 560 |
+
for (s, p) in zip(symbols, dims):
|
| 561 |
+
res *= s**p
|
| 562 |
+
return res
|
| 563 |
+
|
| 564 |
+
@property
|
| 565 |
+
def dim(self):
|
| 566 |
+
"""
|
| 567 |
+
Useless method, kept for compatibility with previous versions.
|
| 568 |
+
|
| 569 |
+
DO NOT USE.
|
| 570 |
+
|
| 571 |
+
Give the dimension of the system.
|
| 572 |
+
|
| 573 |
+
That is return the number of dimensions forming the basis.
|
| 574 |
+
"""
|
| 575 |
+
return len(self.base_dims)
|
| 576 |
+
|
| 577 |
+
@property
|
| 578 |
+
def is_consistent(self):
|
| 579 |
+
"""
|
| 580 |
+
Useless method, kept for compatibility with previous versions.
|
| 581 |
+
|
| 582 |
+
DO NOT USE.
|
| 583 |
+
|
| 584 |
+
Check if the system is well defined.
|
| 585 |
+
"""
|
| 586 |
+
|
| 587 |
+
# not enough or too many base dimensions compared to independent
|
| 588 |
+
# dimensions
|
| 589 |
+
# in vector language: the set of vectors do not form a basis
|
| 590 |
+
return self.inv_can_transf_matrix.is_square
|
.venv/Lib/site-packages/sympy/physics/units/prefixes.py
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Module defining unit prefixe class and some constants.
|
| 3 |
+
|
| 4 |
+
Constant dict for SI and binary prefixes are defined as PREFIXES and
|
| 5 |
+
BIN_PREFIXES.
|
| 6 |
+
"""
|
| 7 |
+
from sympy.core.expr import Expr
|
| 8 |
+
from sympy.core.sympify import sympify
|
| 9 |
+
from sympy.core.singleton import S
|
| 10 |
+
|
| 11 |
+
class Prefix(Expr):
|
| 12 |
+
"""
|
| 13 |
+
This class represent prefixes, with their name, symbol and factor.
|
| 14 |
+
|
| 15 |
+
Prefixes are used to create derived units from a given unit. They should
|
| 16 |
+
always be encapsulated into units.
|
| 17 |
+
|
| 18 |
+
The factor is constructed from a base (default is 10) to some power, and
|
| 19 |
+
it gives the total multiple or fraction. For example the kilometer km
|
| 20 |
+
is constructed from the meter (factor 1) and the kilo (10 to the power 3,
|
| 21 |
+
i.e. 1000). The base can be changed to allow e.g. binary prefixes.
|
| 22 |
+
|
| 23 |
+
A prefix multiplied by something will always return the product of this
|
| 24 |
+
other object times the factor, except if the other object:
|
| 25 |
+
|
| 26 |
+
- is a prefix and they can be combined into a new prefix;
|
| 27 |
+
- defines multiplication with prefixes (which is the case for the Unit
|
| 28 |
+
class).
|
| 29 |
+
"""
|
| 30 |
+
_op_priority = 13.0
|
| 31 |
+
is_commutative = True
|
| 32 |
+
|
| 33 |
+
def __new__(cls, name, abbrev, exponent, base=sympify(10), latex_repr=None):
|
| 34 |
+
|
| 35 |
+
name = sympify(name)
|
| 36 |
+
abbrev = sympify(abbrev)
|
| 37 |
+
exponent = sympify(exponent)
|
| 38 |
+
base = sympify(base)
|
| 39 |
+
|
| 40 |
+
obj = Expr.__new__(cls, name, abbrev, exponent, base)
|
| 41 |
+
obj._name = name
|
| 42 |
+
obj._abbrev = abbrev
|
| 43 |
+
obj._scale_factor = base**exponent
|
| 44 |
+
obj._exponent = exponent
|
| 45 |
+
obj._base = base
|
| 46 |
+
obj._latex_repr = latex_repr
|
| 47 |
+
return obj
|
| 48 |
+
|
| 49 |
+
@property
|
| 50 |
+
def name(self):
|
| 51 |
+
return self._name
|
| 52 |
+
|
| 53 |
+
@property
|
| 54 |
+
def abbrev(self):
|
| 55 |
+
return self._abbrev
|
| 56 |
+
|
| 57 |
+
@property
|
| 58 |
+
def scale_factor(self):
|
| 59 |
+
return self._scale_factor
|
| 60 |
+
|
| 61 |
+
def _latex(self, printer):
|
| 62 |
+
if self._latex_repr is None:
|
| 63 |
+
return r'\text{%s}' % self._abbrev
|
| 64 |
+
return self._latex_repr
|
| 65 |
+
|
| 66 |
+
@property
|
| 67 |
+
def base(self):
|
| 68 |
+
return self._base
|
| 69 |
+
|
| 70 |
+
def __str__(self):
|
| 71 |
+
return str(self._abbrev)
|
| 72 |
+
|
| 73 |
+
def __repr__(self):
|
| 74 |
+
if self.base == 10:
|
| 75 |
+
return "Prefix(%r, %r, %r)" % (
|
| 76 |
+
str(self.name), str(self.abbrev), self._exponent)
|
| 77 |
+
else:
|
| 78 |
+
return "Prefix(%r, %r, %r, %r)" % (
|
| 79 |
+
str(self.name), str(self.abbrev), self._exponent, self.base)
|
| 80 |
+
|
| 81 |
+
def __mul__(self, other):
|
| 82 |
+
from sympy.physics.units import Quantity
|
| 83 |
+
if not isinstance(other, (Quantity, Prefix)):
|
| 84 |
+
return super().__mul__(other)
|
| 85 |
+
|
| 86 |
+
fact = self.scale_factor * other.scale_factor
|
| 87 |
+
|
| 88 |
+
if isinstance(other, Prefix):
|
| 89 |
+
if fact == 1:
|
| 90 |
+
return S.One
|
| 91 |
+
# simplify prefix
|
| 92 |
+
for p in PREFIXES:
|
| 93 |
+
if PREFIXES[p].scale_factor == fact:
|
| 94 |
+
return PREFIXES[p]
|
| 95 |
+
return fact
|
| 96 |
+
|
| 97 |
+
return self.scale_factor * other
|
| 98 |
+
|
| 99 |
+
def __truediv__(self, other):
|
| 100 |
+
if not hasattr(other, "scale_factor"):
|
| 101 |
+
return super().__truediv__(other)
|
| 102 |
+
|
| 103 |
+
fact = self.scale_factor / other.scale_factor
|
| 104 |
+
|
| 105 |
+
if fact == 1:
|
| 106 |
+
return S.One
|
| 107 |
+
elif isinstance(other, Prefix):
|
| 108 |
+
for p in PREFIXES:
|
| 109 |
+
if PREFIXES[p].scale_factor == fact:
|
| 110 |
+
return PREFIXES[p]
|
| 111 |
+
return fact
|
| 112 |
+
|
| 113 |
+
return self.scale_factor / other
|
| 114 |
+
|
| 115 |
+
def __rtruediv__(self, other):
|
| 116 |
+
if other == 1:
|
| 117 |
+
for p in PREFIXES:
|
| 118 |
+
if PREFIXES[p].scale_factor == 1 / self.scale_factor:
|
| 119 |
+
return PREFIXES[p]
|
| 120 |
+
return other / self.scale_factor
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def prefix_unit(unit, prefixes):
|
| 124 |
+
"""
|
| 125 |
+
Return a list of all units formed by unit and the given prefixes.
|
| 126 |
+
|
| 127 |
+
You can use the predefined PREFIXES or BIN_PREFIXES, but you can also
|
| 128 |
+
pass as argument a subdict of them if you do not want all prefixed units.
|
| 129 |
+
|
| 130 |
+
>>> from sympy.physics.units.prefixes import (PREFIXES,
|
| 131 |
+
... prefix_unit)
|
| 132 |
+
>>> from sympy.physics.units import m
|
| 133 |
+
>>> pref = {"m": PREFIXES["m"], "c": PREFIXES["c"], "d": PREFIXES["d"]}
|
| 134 |
+
>>> prefix_unit(m, pref) # doctest: +SKIP
|
| 135 |
+
[millimeter, centimeter, decimeter]
|
| 136 |
+
"""
|
| 137 |
+
|
| 138 |
+
from sympy.physics.units.quantities import Quantity
|
| 139 |
+
from sympy.physics.units import UnitSystem
|
| 140 |
+
|
| 141 |
+
prefixed_units = []
|
| 142 |
+
|
| 143 |
+
for prefix in prefixes.values():
|
| 144 |
+
quantity = Quantity(
|
| 145 |
+
"%s%s" % (prefix.name, unit.name),
|
| 146 |
+
abbrev=("%s%s" % (prefix.abbrev, unit.abbrev)),
|
| 147 |
+
is_prefixed=True,
|
| 148 |
+
)
|
| 149 |
+
UnitSystem._quantity_dimensional_equivalence_map_global[quantity] = unit
|
| 150 |
+
UnitSystem._quantity_scale_factors_global[quantity] = (prefix.scale_factor, unit)
|
| 151 |
+
prefixed_units.append(quantity)
|
| 152 |
+
|
| 153 |
+
return prefixed_units
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
yotta = Prefix('yotta', 'Y', 24)
|
| 157 |
+
zetta = Prefix('zetta', 'Z', 21)
|
| 158 |
+
exa = Prefix('exa', 'E', 18)
|
| 159 |
+
peta = Prefix('peta', 'P', 15)
|
| 160 |
+
tera = Prefix('tera', 'T', 12)
|
| 161 |
+
giga = Prefix('giga', 'G', 9)
|
| 162 |
+
mega = Prefix('mega', 'M', 6)
|
| 163 |
+
kilo = Prefix('kilo', 'k', 3)
|
| 164 |
+
hecto = Prefix('hecto', 'h', 2)
|
| 165 |
+
deca = Prefix('deca', 'da', 1)
|
| 166 |
+
deci = Prefix('deci', 'd', -1)
|
| 167 |
+
centi = Prefix('centi', 'c', -2)
|
| 168 |
+
milli = Prefix('milli', 'm', -3)
|
| 169 |
+
micro = Prefix('micro', 'mu', -6, latex_repr=r"\mu")
|
| 170 |
+
nano = Prefix('nano', 'n', -9)
|
| 171 |
+
pico = Prefix('pico', 'p', -12)
|
| 172 |
+
femto = Prefix('femto', 'f', -15)
|
| 173 |
+
atto = Prefix('atto', 'a', -18)
|
| 174 |
+
zepto = Prefix('zepto', 'z', -21)
|
| 175 |
+
yocto = Prefix('yocto', 'y', -24)
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
# https://physics.nist.gov/cuu/Units/prefixes.html
|
| 179 |
+
PREFIXES = {
|
| 180 |
+
'Y': yotta,
|
| 181 |
+
'Z': zetta,
|
| 182 |
+
'E': exa,
|
| 183 |
+
'P': peta,
|
| 184 |
+
'T': tera,
|
| 185 |
+
'G': giga,
|
| 186 |
+
'M': mega,
|
| 187 |
+
'k': kilo,
|
| 188 |
+
'h': hecto,
|
| 189 |
+
'da': deca,
|
| 190 |
+
'd': deci,
|
| 191 |
+
'c': centi,
|
| 192 |
+
'm': milli,
|
| 193 |
+
'mu': micro,
|
| 194 |
+
'n': nano,
|
| 195 |
+
'p': pico,
|
| 196 |
+
'f': femto,
|
| 197 |
+
'a': atto,
|
| 198 |
+
'z': zepto,
|
| 199 |
+
'y': yocto,
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
kibi = Prefix('kibi', 'Y', 10, 2)
|
| 204 |
+
mebi = Prefix('mebi', 'Y', 20, 2)
|
| 205 |
+
gibi = Prefix('gibi', 'Y', 30, 2)
|
| 206 |
+
tebi = Prefix('tebi', 'Y', 40, 2)
|
| 207 |
+
pebi = Prefix('pebi', 'Y', 50, 2)
|
| 208 |
+
exbi = Prefix('exbi', 'Y', 60, 2)
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
# https://physics.nist.gov/cuu/Units/binary.html
|
| 212 |
+
BIN_PREFIXES = {
|
| 213 |
+
'Ki': kibi,
|
| 214 |
+
'Mi': mebi,
|
| 215 |
+
'Gi': gibi,
|
| 216 |
+
'Ti': tebi,
|
| 217 |
+
'Pi': pebi,
|
| 218 |
+
'Ei': exbi,
|
| 219 |
+
}
|
.venv/Lib/site-packages/sympy/physics/units/quantities.py
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Physical quantities.
|
| 3 |
+
"""
|
| 4 |
+
|
| 5 |
+
from sympy.core.expr import AtomicExpr
|
| 6 |
+
from sympy.core.symbol import Symbol
|
| 7 |
+
from sympy.core.sympify import sympify
|
| 8 |
+
from sympy.physics.units.dimensions import _QuantityMapper
|
| 9 |
+
from sympy.physics.units.prefixes import Prefix
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class Quantity(AtomicExpr):
|
| 13 |
+
"""
|
| 14 |
+
Physical quantity: can be a unit of measure, a constant or a generic quantity.
|
| 15 |
+
"""
|
| 16 |
+
|
| 17 |
+
is_commutative = True
|
| 18 |
+
is_real = True
|
| 19 |
+
is_number = False
|
| 20 |
+
is_nonzero = True
|
| 21 |
+
is_physical_constant = False
|
| 22 |
+
_diff_wrt = True
|
| 23 |
+
|
| 24 |
+
def __new__(cls, name, abbrev=None,
|
| 25 |
+
latex_repr=None, pretty_unicode_repr=None,
|
| 26 |
+
pretty_ascii_repr=None, mathml_presentation_repr=None,
|
| 27 |
+
is_prefixed=False,
|
| 28 |
+
**assumptions):
|
| 29 |
+
|
| 30 |
+
if not isinstance(name, Symbol):
|
| 31 |
+
name = Symbol(name)
|
| 32 |
+
|
| 33 |
+
if abbrev is None:
|
| 34 |
+
abbrev = name
|
| 35 |
+
elif isinstance(abbrev, str):
|
| 36 |
+
abbrev = Symbol(abbrev)
|
| 37 |
+
|
| 38 |
+
# HACK: These are here purely for type checking. They actually get assigned below.
|
| 39 |
+
cls._is_prefixed = is_prefixed
|
| 40 |
+
|
| 41 |
+
obj = AtomicExpr.__new__(cls, name, abbrev)
|
| 42 |
+
obj._name = name
|
| 43 |
+
obj._abbrev = abbrev
|
| 44 |
+
obj._latex_repr = latex_repr
|
| 45 |
+
obj._unicode_repr = pretty_unicode_repr
|
| 46 |
+
obj._ascii_repr = pretty_ascii_repr
|
| 47 |
+
obj._mathml_repr = mathml_presentation_repr
|
| 48 |
+
obj._is_prefixed = is_prefixed
|
| 49 |
+
return obj
|
| 50 |
+
|
| 51 |
+
def set_global_dimension(self, dimension):
|
| 52 |
+
_QuantityMapper._quantity_dimension_global[self] = dimension
|
| 53 |
+
|
| 54 |
+
def set_global_relative_scale_factor(self, scale_factor, reference_quantity):
|
| 55 |
+
"""
|
| 56 |
+
Setting a scale factor that is valid across all unit system.
|
| 57 |
+
"""
|
| 58 |
+
from sympy.physics.units import UnitSystem
|
| 59 |
+
scale_factor = sympify(scale_factor)
|
| 60 |
+
if isinstance(scale_factor, Prefix):
|
| 61 |
+
self._is_prefixed = True
|
| 62 |
+
# replace all prefixes by their ratio to canonical units:
|
| 63 |
+
scale_factor = scale_factor.replace(
|
| 64 |
+
lambda x: isinstance(x, Prefix),
|
| 65 |
+
lambda x: x.scale_factor
|
| 66 |
+
)
|
| 67 |
+
scale_factor = sympify(scale_factor)
|
| 68 |
+
UnitSystem._quantity_scale_factors_global[self] = (scale_factor, reference_quantity)
|
| 69 |
+
UnitSystem._quantity_dimensional_equivalence_map_global[self] = reference_quantity
|
| 70 |
+
|
| 71 |
+
@property
|
| 72 |
+
def name(self):
|
| 73 |
+
return self._name
|
| 74 |
+
|
| 75 |
+
@property
|
| 76 |
+
def dimension(self):
|
| 77 |
+
from sympy.physics.units import UnitSystem
|
| 78 |
+
unit_system = UnitSystem.get_default_unit_system()
|
| 79 |
+
return unit_system.get_quantity_dimension(self)
|
| 80 |
+
|
| 81 |
+
@property
|
| 82 |
+
def abbrev(self):
|
| 83 |
+
"""
|
| 84 |
+
Symbol representing the unit name.
|
| 85 |
+
|
| 86 |
+
Prepend the abbreviation with the prefix symbol if it is defines.
|
| 87 |
+
"""
|
| 88 |
+
return self._abbrev
|
| 89 |
+
|
| 90 |
+
@property
|
| 91 |
+
def scale_factor(self):
|
| 92 |
+
"""
|
| 93 |
+
Overall magnitude of the quantity as compared to the canonical units.
|
| 94 |
+
"""
|
| 95 |
+
from sympy.physics.units import UnitSystem
|
| 96 |
+
unit_system = UnitSystem.get_default_unit_system()
|
| 97 |
+
return unit_system.get_quantity_scale_factor(self)
|
| 98 |
+
|
| 99 |
+
def _eval_is_positive(self):
|
| 100 |
+
return True
|
| 101 |
+
|
| 102 |
+
def _eval_is_constant(self):
|
| 103 |
+
return True
|
| 104 |
+
|
| 105 |
+
def _eval_Abs(self):
|
| 106 |
+
return self
|
| 107 |
+
|
| 108 |
+
def _eval_subs(self, old, new):
|
| 109 |
+
if isinstance(new, Quantity) and self != old:
|
| 110 |
+
return self
|
| 111 |
+
|
| 112 |
+
def _latex(self, printer):
|
| 113 |
+
if self._latex_repr:
|
| 114 |
+
return self._latex_repr
|
| 115 |
+
else:
|
| 116 |
+
return r'\text{{{}}}'.format(self.args[1] \
|
| 117 |
+
if len(self.args) >= 2 else self.args[0])
|
| 118 |
+
|
| 119 |
+
def convert_to(self, other, unit_system="SI"):
|
| 120 |
+
"""
|
| 121 |
+
Convert the quantity to another quantity of same dimensions.
|
| 122 |
+
|
| 123 |
+
Examples
|
| 124 |
+
========
|
| 125 |
+
|
| 126 |
+
>>> from sympy.physics.units import speed_of_light, meter, second
|
| 127 |
+
>>> speed_of_light
|
| 128 |
+
speed_of_light
|
| 129 |
+
>>> speed_of_light.convert_to(meter/second)
|
| 130 |
+
299792458*meter/second
|
| 131 |
+
|
| 132 |
+
>>> from sympy.physics.units import liter
|
| 133 |
+
>>> liter.convert_to(meter**3)
|
| 134 |
+
meter**3/1000
|
| 135 |
+
"""
|
| 136 |
+
from .util import convert_to
|
| 137 |
+
return convert_to(self, other, unit_system)
|
| 138 |
+
|
| 139 |
+
@property
|
| 140 |
+
def free_symbols(self):
|
| 141 |
+
"""Return free symbols from quantity."""
|
| 142 |
+
return set()
|
| 143 |
+
|
| 144 |
+
@property
|
| 145 |
+
def is_prefixed(self):
|
| 146 |
+
"""Whether or not the quantity is prefixed. Eg. `kilogram` is prefixed, but `gram` is not."""
|
| 147 |
+
return self._is_prefixed
|
| 148 |
+
|
| 149 |
+
class PhysicalConstant(Quantity):
|
| 150 |
+
"""Represents a physical constant, eg. `speed_of_light` or `avogadro_constant`."""
|
| 151 |
+
|
| 152 |
+
is_physical_constant = True
|
.venv/Lib/site-packages/sympy/physics/units/systems/__init__.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.physics.units.systems.mks import MKS
|
| 2 |
+
from sympy.physics.units.systems.mksa import MKSA
|
| 3 |
+
from sympy.physics.units.systems.natural import natural
|
| 4 |
+
from sympy.physics.units.systems.si import SI
|
| 5 |
+
|
| 6 |
+
__all__ = ['MKS', 'MKSA', 'natural', 'SI']
|
.venv/Lib/site-packages/sympy/physics/units/systems/cgs.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.singleton import S
|
| 2 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 3 |
+
from sympy.physics.units import UnitSystem, centimeter, gram, second, coulomb, charge, speed_of_light, current, mass, \
|
| 4 |
+
length, voltage, magnetic_density, magnetic_flux
|
| 5 |
+
from sympy.physics.units.definitions import coulombs_constant
|
| 6 |
+
from sympy.physics.units.definitions.unit_definitions import statcoulomb, statampere, statvolt, volt, tesla, gauss, \
|
| 7 |
+
weber, maxwell, debye, oersted, ohm, farad, henry, erg, ampere, coulomb_constant
|
| 8 |
+
from sympy.physics.units.systems.mks import dimsys_length_weight_time
|
| 9 |
+
|
| 10 |
+
One = S.One
|
| 11 |
+
|
| 12 |
+
dimsys_cgs = dimsys_length_weight_time.extend(
|
| 13 |
+
[],
|
| 14 |
+
new_dim_deps={
|
| 15 |
+
# Dimensional dependencies for derived dimensions
|
| 16 |
+
"impedance": {"time": 1, "length": -1},
|
| 17 |
+
"conductance": {"time": -1, "length": 1},
|
| 18 |
+
"capacitance": {"length": 1},
|
| 19 |
+
"inductance": {"time": 2, "length": -1},
|
| 20 |
+
"charge": {"mass": S.Half, "length": S(3)/2, "time": -1},
|
| 21 |
+
"current": {"mass": One/2, "length": 3*One/2, "time": -2},
|
| 22 |
+
"voltage": {"length": -One/2, "mass": One/2, "time": -1},
|
| 23 |
+
"magnetic_density": {"length": -One/2, "mass": One/2, "time": -1},
|
| 24 |
+
"magnetic_flux": {"length": 3*One/2, "mass": One/2, "time": -1},
|
| 25 |
+
}
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
cgs_gauss = UnitSystem(
|
| 29 |
+
base_units=[centimeter, gram, second],
|
| 30 |
+
units=[],
|
| 31 |
+
name="cgs_gauss",
|
| 32 |
+
dimension_system=dimsys_cgs)
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
cgs_gauss.set_quantity_scale_factor(coulombs_constant, 1)
|
| 36 |
+
|
| 37 |
+
cgs_gauss.set_quantity_dimension(statcoulomb, charge)
|
| 38 |
+
cgs_gauss.set_quantity_scale_factor(statcoulomb, centimeter**(S(3)/2)*gram**(S.Half)/second)
|
| 39 |
+
|
| 40 |
+
cgs_gauss.set_quantity_dimension(coulomb, charge)
|
| 41 |
+
|
| 42 |
+
cgs_gauss.set_quantity_dimension(statampere, current)
|
| 43 |
+
cgs_gauss.set_quantity_scale_factor(statampere, statcoulomb/second)
|
| 44 |
+
|
| 45 |
+
cgs_gauss.set_quantity_dimension(statvolt, voltage)
|
| 46 |
+
cgs_gauss.set_quantity_scale_factor(statvolt, erg/statcoulomb)
|
| 47 |
+
|
| 48 |
+
cgs_gauss.set_quantity_dimension(volt, voltage)
|
| 49 |
+
|
| 50 |
+
cgs_gauss.set_quantity_dimension(gauss, magnetic_density)
|
| 51 |
+
cgs_gauss.set_quantity_scale_factor(gauss, sqrt(gram/centimeter)/second)
|
| 52 |
+
|
| 53 |
+
cgs_gauss.set_quantity_dimension(tesla, magnetic_density)
|
| 54 |
+
|
| 55 |
+
cgs_gauss.set_quantity_dimension(maxwell, magnetic_flux)
|
| 56 |
+
cgs_gauss.set_quantity_scale_factor(maxwell, sqrt(centimeter**3*gram)/second)
|
| 57 |
+
|
| 58 |
+
# SI units expressed in CGS-gaussian units:
|
| 59 |
+
cgs_gauss.set_quantity_scale_factor(coulomb, 10*speed_of_light*statcoulomb)
|
| 60 |
+
cgs_gauss.set_quantity_scale_factor(ampere, 10*speed_of_light*statcoulomb/second)
|
| 61 |
+
cgs_gauss.set_quantity_scale_factor(volt, 10**6/speed_of_light*statvolt)
|
| 62 |
+
cgs_gauss.set_quantity_scale_factor(weber, 10**8*maxwell)
|
| 63 |
+
cgs_gauss.set_quantity_scale_factor(tesla, 10**4*gauss)
|
| 64 |
+
cgs_gauss.set_quantity_scale_factor(debye, One/10**18*statcoulomb*centimeter)
|
| 65 |
+
cgs_gauss.set_quantity_scale_factor(oersted, sqrt(gram/centimeter)/second)
|
| 66 |
+
cgs_gauss.set_quantity_scale_factor(ohm, 10**5/speed_of_light**2*second/centimeter)
|
| 67 |
+
cgs_gauss.set_quantity_scale_factor(farad, One/10**5*speed_of_light**2*centimeter)
|
| 68 |
+
cgs_gauss.set_quantity_scale_factor(henry, 10**5/speed_of_light**2/centimeter*second**2)
|
| 69 |
+
|
| 70 |
+
# Coulomb's constant:
|
| 71 |
+
cgs_gauss.set_quantity_dimension(coulomb_constant, 1)
|
| 72 |
+
cgs_gauss.set_quantity_scale_factor(coulomb_constant, 1)
|
| 73 |
+
|
| 74 |
+
__all__ = [
|
| 75 |
+
'ohm', 'tesla', 'maxwell', 'speed_of_light', 'volt', 'second', 'voltage',
|
| 76 |
+
'debye', 'dimsys_length_weight_time', 'centimeter', 'coulomb_constant',
|
| 77 |
+
'farad', 'sqrt', 'UnitSystem', 'current', 'charge', 'weber', 'gram',
|
| 78 |
+
'statcoulomb', 'gauss', 'S', 'statvolt', 'oersted', 'statampere',
|
| 79 |
+
'dimsys_cgs', 'coulomb', 'magnetic_density', 'magnetic_flux', 'One',
|
| 80 |
+
'length', 'erg', 'mass', 'coulombs_constant', 'henry', 'ampere',
|
| 81 |
+
'cgs_gauss',
|
| 82 |
+
]
|
.venv/Lib/site-packages/sympy/physics/units/systems/length_weight_time.py
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.singleton import S
|
| 2 |
+
|
| 3 |
+
from sympy.core.numbers import pi
|
| 4 |
+
|
| 5 |
+
from sympy.physics.units import DimensionSystem, hertz, kilogram
|
| 6 |
+
from sympy.physics.units.definitions import (
|
| 7 |
+
G, Hz, J, N, Pa, W, c, g, kg, m, s, meter, gram, second, newton,
|
| 8 |
+
joule, watt, pascal)
|
| 9 |
+
from sympy.physics.units.definitions.dimension_definitions import (
|
| 10 |
+
acceleration, action, energy, force, frequency, momentum,
|
| 11 |
+
power, pressure, velocity, length, mass, time)
|
| 12 |
+
from sympy.physics.units.prefixes import PREFIXES, prefix_unit
|
| 13 |
+
from sympy.physics.units.prefixes import (
|
| 14 |
+
kibi, mebi, gibi, tebi, pebi, exbi
|
| 15 |
+
)
|
| 16 |
+
from sympy.physics.units.definitions import (
|
| 17 |
+
cd, K, coulomb, volt, ohm, siemens, farad, henry, tesla, weber, dioptre,
|
| 18 |
+
lux, katal, gray, becquerel, inch, hectare, liter, julian_year,
|
| 19 |
+
gravitational_constant, speed_of_light, elementary_charge, planck, hbar,
|
| 20 |
+
electronvolt, avogadro_number, avogadro_constant, boltzmann_constant,
|
| 21 |
+
stefan_boltzmann_constant, atomic_mass_constant, molar_gas_constant,
|
| 22 |
+
faraday_constant, josephson_constant, von_klitzing_constant,
|
| 23 |
+
acceleration_due_to_gravity, magnetic_constant, vacuum_permittivity,
|
| 24 |
+
vacuum_impedance, coulomb_constant, atmosphere, bar, pound, psi, mmHg,
|
| 25 |
+
milli_mass_unit, quart, lightyear, astronomical_unit, planck_mass,
|
| 26 |
+
planck_time, planck_temperature, planck_length, planck_charge,
|
| 27 |
+
planck_area, planck_volume, planck_momentum, planck_energy, planck_force,
|
| 28 |
+
planck_power, planck_density, planck_energy_density, planck_intensity,
|
| 29 |
+
planck_angular_frequency, planck_pressure, planck_current, planck_voltage,
|
| 30 |
+
planck_impedance, planck_acceleration, bit, byte, kibibyte, mebibyte,
|
| 31 |
+
gibibyte, tebibyte, pebibyte, exbibyte, curie, rutherford, radian, degree,
|
| 32 |
+
steradian, angular_mil, atomic_mass_unit, gee, kPa, ampere, u0, kelvin,
|
| 33 |
+
mol, mole, candela, electric_constant, boltzmann, angstrom
|
| 34 |
+
)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
dimsys_length_weight_time = DimensionSystem([
|
| 38 |
+
# Dimensional dependencies for MKS base dimensions
|
| 39 |
+
length,
|
| 40 |
+
mass,
|
| 41 |
+
time,
|
| 42 |
+
], dimensional_dependencies={
|
| 43 |
+
# Dimensional dependencies for derived dimensions
|
| 44 |
+
"velocity": {"length": 1, "time": -1},
|
| 45 |
+
"acceleration": {"length": 1, "time": -2},
|
| 46 |
+
"momentum": {"mass": 1, "length": 1, "time": -1},
|
| 47 |
+
"force": {"mass": 1, "length": 1, "time": -2},
|
| 48 |
+
"energy": {"mass": 1, "length": 2, "time": -2},
|
| 49 |
+
"power": {"length": 2, "mass": 1, "time": -3},
|
| 50 |
+
"pressure": {"mass": 1, "length": -1, "time": -2},
|
| 51 |
+
"frequency": {"time": -1},
|
| 52 |
+
"action": {"length": 2, "mass": 1, "time": -1},
|
| 53 |
+
"area": {"length": 2},
|
| 54 |
+
"volume": {"length": 3},
|
| 55 |
+
})
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
One = S.One
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
# Base units:
|
| 62 |
+
dimsys_length_weight_time.set_quantity_dimension(meter, length)
|
| 63 |
+
dimsys_length_weight_time.set_quantity_scale_factor(meter, One)
|
| 64 |
+
|
| 65 |
+
# gram; used to define its prefixed units
|
| 66 |
+
dimsys_length_weight_time.set_quantity_dimension(gram, mass)
|
| 67 |
+
dimsys_length_weight_time.set_quantity_scale_factor(gram, One)
|
| 68 |
+
|
| 69 |
+
dimsys_length_weight_time.set_quantity_dimension(second, time)
|
| 70 |
+
dimsys_length_weight_time.set_quantity_scale_factor(second, One)
|
| 71 |
+
|
| 72 |
+
# derived units
|
| 73 |
+
|
| 74 |
+
dimsys_length_weight_time.set_quantity_dimension(newton, force)
|
| 75 |
+
dimsys_length_weight_time.set_quantity_scale_factor(newton, kilogram*meter/second**2)
|
| 76 |
+
|
| 77 |
+
dimsys_length_weight_time.set_quantity_dimension(joule, energy)
|
| 78 |
+
dimsys_length_weight_time.set_quantity_scale_factor(joule, newton*meter)
|
| 79 |
+
|
| 80 |
+
dimsys_length_weight_time.set_quantity_dimension(watt, power)
|
| 81 |
+
dimsys_length_weight_time.set_quantity_scale_factor(watt, joule/second)
|
| 82 |
+
|
| 83 |
+
dimsys_length_weight_time.set_quantity_dimension(pascal, pressure)
|
| 84 |
+
dimsys_length_weight_time.set_quantity_scale_factor(pascal, newton/meter**2)
|
| 85 |
+
|
| 86 |
+
dimsys_length_weight_time.set_quantity_dimension(hertz, frequency)
|
| 87 |
+
dimsys_length_weight_time.set_quantity_scale_factor(hertz, One)
|
| 88 |
+
|
| 89 |
+
# Other derived units:
|
| 90 |
+
|
| 91 |
+
dimsys_length_weight_time.set_quantity_dimension(dioptre, 1 / length)
|
| 92 |
+
dimsys_length_weight_time.set_quantity_scale_factor(dioptre, 1/meter)
|
| 93 |
+
|
| 94 |
+
# Common volume and area units
|
| 95 |
+
|
| 96 |
+
dimsys_length_weight_time.set_quantity_dimension(hectare, length**2)
|
| 97 |
+
dimsys_length_weight_time.set_quantity_scale_factor(hectare, (meter**2)*(10000))
|
| 98 |
+
|
| 99 |
+
dimsys_length_weight_time.set_quantity_dimension(liter, length**3)
|
| 100 |
+
dimsys_length_weight_time.set_quantity_scale_factor(liter, meter**3/1000)
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
# Newton constant
|
| 104 |
+
# REF: NIST SP 959 (June 2019)
|
| 105 |
+
|
| 106 |
+
dimsys_length_weight_time.set_quantity_dimension(gravitational_constant, length ** 3 * mass ** -1 * time ** -2)
|
| 107 |
+
dimsys_length_weight_time.set_quantity_scale_factor(gravitational_constant, 6.67430e-11*m**3/(kg*s**2))
|
| 108 |
+
|
| 109 |
+
# speed of light
|
| 110 |
+
|
| 111 |
+
dimsys_length_weight_time.set_quantity_dimension(speed_of_light, velocity)
|
| 112 |
+
dimsys_length_weight_time.set_quantity_scale_factor(speed_of_light, 299792458*meter/second)
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
# Planck constant
|
| 116 |
+
# REF: NIST SP 959 (June 2019)
|
| 117 |
+
|
| 118 |
+
dimsys_length_weight_time.set_quantity_dimension(planck, action)
|
| 119 |
+
dimsys_length_weight_time.set_quantity_scale_factor(planck, 6.62607015e-34*joule*second)
|
| 120 |
+
|
| 121 |
+
# Reduced Planck constant
|
| 122 |
+
# REF: NIST SP 959 (June 2019)
|
| 123 |
+
|
| 124 |
+
dimsys_length_weight_time.set_quantity_dimension(hbar, action)
|
| 125 |
+
dimsys_length_weight_time.set_quantity_scale_factor(hbar, planck / (2 * pi))
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
__all__ = [
|
| 129 |
+
'mmHg', 'atmosphere', 'newton', 'meter', 'vacuum_permittivity', 'pascal',
|
| 130 |
+
'magnetic_constant', 'angular_mil', 'julian_year', 'weber', 'exbibyte',
|
| 131 |
+
'liter', 'molar_gas_constant', 'faraday_constant', 'avogadro_constant',
|
| 132 |
+
'planck_momentum', 'planck_density', 'gee', 'mol', 'bit', 'gray', 'kibi',
|
| 133 |
+
'bar', 'curie', 'prefix_unit', 'PREFIXES', 'planck_time', 'gram',
|
| 134 |
+
'candela', 'force', 'planck_intensity', 'energy', 'becquerel',
|
| 135 |
+
'planck_acceleration', 'speed_of_light', 'dioptre', 'second', 'frequency',
|
| 136 |
+
'Hz', 'power', 'lux', 'planck_current', 'momentum', 'tebibyte',
|
| 137 |
+
'planck_power', 'degree', 'mebi', 'K', 'planck_volume',
|
| 138 |
+
'quart', 'pressure', 'W', 'joule', 'boltzmann_constant', 'c', 'g',
|
| 139 |
+
'planck_force', 'exbi', 's', 'watt', 'action', 'hbar', 'gibibyte',
|
| 140 |
+
'DimensionSystem', 'cd', 'volt', 'planck_charge', 'angstrom',
|
| 141 |
+
'dimsys_length_weight_time', 'pebi', 'vacuum_impedance', 'planck',
|
| 142 |
+
'farad', 'gravitational_constant', 'u0', 'hertz', 'tesla', 'steradian',
|
| 143 |
+
'josephson_constant', 'planck_area', 'stefan_boltzmann_constant',
|
| 144 |
+
'astronomical_unit', 'J', 'N', 'planck_voltage', 'planck_energy',
|
| 145 |
+
'atomic_mass_constant', 'rutherford', 'elementary_charge', 'Pa',
|
| 146 |
+
'planck_mass', 'henry', 'planck_angular_frequency', 'ohm', 'pound',
|
| 147 |
+
'planck_pressure', 'G', 'avogadro_number', 'psi', 'von_klitzing_constant',
|
| 148 |
+
'planck_length', 'radian', 'mole', 'acceleration',
|
| 149 |
+
'planck_energy_density', 'mebibyte', 'length',
|
| 150 |
+
'acceleration_due_to_gravity', 'planck_temperature', 'tebi', 'inch',
|
| 151 |
+
'electronvolt', 'coulomb_constant', 'kelvin', 'kPa', 'boltzmann',
|
| 152 |
+
'milli_mass_unit', 'gibi', 'planck_impedance', 'electric_constant', 'kg',
|
| 153 |
+
'coulomb', 'siemens', 'byte', 'atomic_mass_unit', 'm', 'kibibyte',
|
| 154 |
+
'kilogram', 'lightyear', 'mass', 'time', 'pebibyte', 'velocity',
|
| 155 |
+
'ampere', 'katal',
|
| 156 |
+
]
|
.venv/Lib/site-packages/sympy/physics/units/systems/mks.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
MKS unit system.
|
| 3 |
+
|
| 4 |
+
MKS stands for "meter, kilogram, second".
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
from sympy.physics.units import UnitSystem
|
| 8 |
+
from sympy.physics.units.definitions import gravitational_constant, hertz, joule, newton, pascal, watt, speed_of_light, gram, kilogram, meter, second
|
| 9 |
+
from sympy.physics.units.definitions.dimension_definitions import (
|
| 10 |
+
acceleration, action, energy, force, frequency, momentum,
|
| 11 |
+
power, pressure, velocity, length, mass, time)
|
| 12 |
+
from sympy.physics.units.prefixes import PREFIXES, prefix_unit
|
| 13 |
+
from sympy.physics.units.systems.length_weight_time import dimsys_length_weight_time
|
| 14 |
+
|
| 15 |
+
dims = (velocity, acceleration, momentum, force, energy, power, pressure,
|
| 16 |
+
frequency, action)
|
| 17 |
+
|
| 18 |
+
units = [meter, gram, second, joule, newton, watt, pascal, hertz]
|
| 19 |
+
all_units = []
|
| 20 |
+
|
| 21 |
+
# Prefixes of units like gram, joule, newton etc get added using `prefix_unit`
|
| 22 |
+
# in the for loop, but the actual units have to be added manually.
|
| 23 |
+
all_units.extend([gram, joule, newton, watt, pascal, hertz])
|
| 24 |
+
|
| 25 |
+
for u in units:
|
| 26 |
+
all_units.extend(prefix_unit(u, PREFIXES))
|
| 27 |
+
all_units.extend([gravitational_constant, speed_of_light])
|
| 28 |
+
|
| 29 |
+
# unit system
|
| 30 |
+
MKS = UnitSystem(base_units=(meter, kilogram, second), units=all_units, name="MKS", dimension_system=dimsys_length_weight_time, derived_units={
|
| 31 |
+
power: watt,
|
| 32 |
+
time: second,
|
| 33 |
+
pressure: pascal,
|
| 34 |
+
length: meter,
|
| 35 |
+
frequency: hertz,
|
| 36 |
+
mass: kilogram,
|
| 37 |
+
force: newton,
|
| 38 |
+
energy: joule,
|
| 39 |
+
velocity: meter/second,
|
| 40 |
+
acceleration: meter/(second**2),
|
| 41 |
+
})
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
__all__ = [
|
| 45 |
+
'MKS', 'units', 'all_units', 'dims',
|
| 46 |
+
]
|
.venv/Lib/site-packages/sympy/physics/units/systems/mksa.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
MKS unit system.
|
| 3 |
+
|
| 4 |
+
MKS stands for "meter, kilogram, second, ampere".
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
from __future__ import annotations
|
| 8 |
+
|
| 9 |
+
from sympy.physics.units.definitions import Z0, ampere, coulomb, farad, henry, siemens, tesla, volt, weber, ohm
|
| 10 |
+
from sympy.physics.units.definitions.dimension_definitions import (
|
| 11 |
+
capacitance, charge, conductance, current, impedance, inductance,
|
| 12 |
+
magnetic_density, magnetic_flux, voltage)
|
| 13 |
+
from sympy.physics.units.prefixes import PREFIXES, prefix_unit
|
| 14 |
+
from sympy.physics.units.systems.mks import MKS, dimsys_length_weight_time
|
| 15 |
+
from sympy.physics.units.quantities import Quantity
|
| 16 |
+
|
| 17 |
+
dims = (voltage, impedance, conductance, current, capacitance, inductance, charge,
|
| 18 |
+
magnetic_density, magnetic_flux)
|
| 19 |
+
|
| 20 |
+
units = [ampere, volt, ohm, siemens, farad, henry, coulomb, tesla, weber]
|
| 21 |
+
|
| 22 |
+
all_units: list[Quantity] = []
|
| 23 |
+
for u in units:
|
| 24 |
+
all_units.extend(prefix_unit(u, PREFIXES))
|
| 25 |
+
all_units.extend(units)
|
| 26 |
+
|
| 27 |
+
all_units.append(Z0)
|
| 28 |
+
|
| 29 |
+
dimsys_MKSA = dimsys_length_weight_time.extend([
|
| 30 |
+
# Dimensional dependencies for base dimensions (MKSA not in MKS)
|
| 31 |
+
current,
|
| 32 |
+
], new_dim_deps={
|
| 33 |
+
# Dimensional dependencies for derived dimensions
|
| 34 |
+
"voltage": {"mass": 1, "length": 2, "current": -1, "time": -3},
|
| 35 |
+
"impedance": {"mass": 1, "length": 2, "current": -2, "time": -3},
|
| 36 |
+
"conductance": {"mass": -1, "length": -2, "current": 2, "time": 3},
|
| 37 |
+
"capacitance": {"mass": -1, "length": -2, "current": 2, "time": 4},
|
| 38 |
+
"inductance": {"mass": 1, "length": 2, "current": -2, "time": -2},
|
| 39 |
+
"charge": {"current": 1, "time": 1},
|
| 40 |
+
"magnetic_density": {"mass": 1, "current": -1, "time": -2},
|
| 41 |
+
"magnetic_flux": {"length": 2, "mass": 1, "current": -1, "time": -2},
|
| 42 |
+
})
|
| 43 |
+
|
| 44 |
+
MKSA = MKS.extend(base=(ampere,), units=all_units, name='MKSA', dimension_system=dimsys_MKSA, derived_units={
|
| 45 |
+
magnetic_flux: weber,
|
| 46 |
+
impedance: ohm,
|
| 47 |
+
current: ampere,
|
| 48 |
+
voltage: volt,
|
| 49 |
+
inductance: henry,
|
| 50 |
+
conductance: siemens,
|
| 51 |
+
magnetic_density: tesla,
|
| 52 |
+
charge: coulomb,
|
| 53 |
+
capacitance: farad,
|
| 54 |
+
})
|
.venv/Lib/site-packages/sympy/physics/units/systems/natural.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Naturalunit system.
|
| 3 |
+
|
| 4 |
+
The natural system comes from "setting c = 1, hbar = 1". From the computer
|
| 5 |
+
point of view it means that we use velocity and action instead of length and
|
| 6 |
+
time. Moreover instead of mass we use energy.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
from sympy.physics.units import DimensionSystem
|
| 10 |
+
from sympy.physics.units.definitions import c, eV, hbar
|
| 11 |
+
from sympy.physics.units.definitions.dimension_definitions import (
|
| 12 |
+
action, energy, force, frequency, length, mass, momentum,
|
| 13 |
+
power, time, velocity)
|
| 14 |
+
from sympy.physics.units.prefixes import PREFIXES, prefix_unit
|
| 15 |
+
from sympy.physics.units.unitsystem import UnitSystem
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
# dimension system
|
| 19 |
+
_natural_dim = DimensionSystem(
|
| 20 |
+
base_dims=(action, energy, velocity),
|
| 21 |
+
derived_dims=(length, mass, time, momentum, force, power, frequency)
|
| 22 |
+
)
|
| 23 |
+
|
| 24 |
+
units = prefix_unit(eV, PREFIXES)
|
| 25 |
+
|
| 26 |
+
# unit system
|
| 27 |
+
natural = UnitSystem(base_units=(hbar, eV, c), units=units, name="Natural system")
|
.venv/Lib/site-packages/sympy/physics/units/systems/si.py
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
SI unit system.
|
| 3 |
+
Based on MKSA, which stands for "meter, kilogram, second, ampere".
|
| 4 |
+
Added kelvin, candela and mole.
|
| 5 |
+
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
from __future__ import annotations
|
| 9 |
+
|
| 10 |
+
from sympy.physics.units import DimensionSystem, Dimension, dHg0
|
| 11 |
+
|
| 12 |
+
from sympy.physics.units.quantities import Quantity
|
| 13 |
+
|
| 14 |
+
from sympy.core.numbers import (Rational, pi)
|
| 15 |
+
from sympy.core.singleton import S
|
| 16 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 17 |
+
from sympy.physics.units.definitions.dimension_definitions import (
|
| 18 |
+
acceleration, action, current, impedance, length, mass, time, velocity,
|
| 19 |
+
amount_of_substance, temperature, information, frequency, force, pressure,
|
| 20 |
+
energy, power, charge, voltage, capacitance, conductance, magnetic_flux,
|
| 21 |
+
magnetic_density, inductance, luminous_intensity
|
| 22 |
+
)
|
| 23 |
+
from sympy.physics.units.definitions import (
|
| 24 |
+
kilogram, newton, second, meter, gram, cd, K, joule, watt, pascal, hertz,
|
| 25 |
+
coulomb, volt, ohm, siemens, farad, henry, tesla, weber, dioptre, lux,
|
| 26 |
+
katal, gray, becquerel, inch, liter, julian_year, gravitational_constant,
|
| 27 |
+
speed_of_light, elementary_charge, planck, hbar, electronvolt,
|
| 28 |
+
avogadro_number, avogadro_constant, boltzmann_constant, electron_rest_mass,
|
| 29 |
+
stefan_boltzmann_constant, Da, atomic_mass_constant, molar_gas_constant,
|
| 30 |
+
faraday_constant, josephson_constant, von_klitzing_constant,
|
| 31 |
+
acceleration_due_to_gravity, magnetic_constant, vacuum_permittivity,
|
| 32 |
+
vacuum_impedance, coulomb_constant, atmosphere, bar, pound, psi, mmHg,
|
| 33 |
+
milli_mass_unit, quart, lightyear, astronomical_unit, planck_mass,
|
| 34 |
+
planck_time, planck_temperature, planck_length, planck_charge, planck_area,
|
| 35 |
+
planck_volume, planck_momentum, planck_energy, planck_force, planck_power,
|
| 36 |
+
planck_density, planck_energy_density, planck_intensity,
|
| 37 |
+
planck_angular_frequency, planck_pressure, planck_current, planck_voltage,
|
| 38 |
+
planck_impedance, planck_acceleration, bit, byte, kibibyte, mebibyte,
|
| 39 |
+
gibibyte, tebibyte, pebibyte, exbibyte, curie, rutherford, radian, degree,
|
| 40 |
+
steradian, angular_mil, atomic_mass_unit, gee, kPa, ampere, u0, c, kelvin,
|
| 41 |
+
mol, mole, candela, m, kg, s, electric_constant, G, boltzmann
|
| 42 |
+
)
|
| 43 |
+
from sympy.physics.units.prefixes import PREFIXES, prefix_unit
|
| 44 |
+
from sympy.physics.units.systems.mksa import MKSA, dimsys_MKSA
|
| 45 |
+
|
| 46 |
+
derived_dims = (frequency, force, pressure, energy, power, charge, voltage,
|
| 47 |
+
capacitance, conductance, magnetic_flux,
|
| 48 |
+
magnetic_density, inductance, luminous_intensity)
|
| 49 |
+
base_dims = (amount_of_substance, luminous_intensity, temperature)
|
| 50 |
+
|
| 51 |
+
units = [mol, cd, K, lux, hertz, newton, pascal, joule, watt, coulomb, volt,
|
| 52 |
+
farad, ohm, siemens, weber, tesla, henry, candela, lux, becquerel,
|
| 53 |
+
gray, katal]
|
| 54 |
+
|
| 55 |
+
all_units: list[Quantity] = []
|
| 56 |
+
for u in units:
|
| 57 |
+
all_units.extend(prefix_unit(u, PREFIXES))
|
| 58 |
+
|
| 59 |
+
all_units.extend(units)
|
| 60 |
+
all_units.extend([mol, cd, K, lux])
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
dimsys_SI = dimsys_MKSA.extend(
|
| 64 |
+
[
|
| 65 |
+
# Dimensional dependencies for other base dimensions:
|
| 66 |
+
temperature,
|
| 67 |
+
amount_of_substance,
|
| 68 |
+
luminous_intensity,
|
| 69 |
+
])
|
| 70 |
+
|
| 71 |
+
dimsys_default = dimsys_SI.extend(
|
| 72 |
+
[information],
|
| 73 |
+
)
|
| 74 |
+
|
| 75 |
+
SI = MKSA.extend(base=(mol, cd, K), units=all_units, name='SI', dimension_system=dimsys_SI, derived_units={
|
| 76 |
+
power: watt,
|
| 77 |
+
magnetic_flux: weber,
|
| 78 |
+
time: second,
|
| 79 |
+
impedance: ohm,
|
| 80 |
+
pressure: pascal,
|
| 81 |
+
current: ampere,
|
| 82 |
+
voltage: volt,
|
| 83 |
+
length: meter,
|
| 84 |
+
frequency: hertz,
|
| 85 |
+
inductance: henry,
|
| 86 |
+
temperature: kelvin,
|
| 87 |
+
amount_of_substance: mole,
|
| 88 |
+
luminous_intensity: candela,
|
| 89 |
+
conductance: siemens,
|
| 90 |
+
mass: kilogram,
|
| 91 |
+
magnetic_density: tesla,
|
| 92 |
+
charge: coulomb,
|
| 93 |
+
force: newton,
|
| 94 |
+
capacitance: farad,
|
| 95 |
+
energy: joule,
|
| 96 |
+
velocity: meter/second,
|
| 97 |
+
})
|
| 98 |
+
|
| 99 |
+
One = S.One
|
| 100 |
+
|
| 101 |
+
SI.set_quantity_dimension(radian, One)
|
| 102 |
+
|
| 103 |
+
SI.set_quantity_scale_factor(ampere, One)
|
| 104 |
+
|
| 105 |
+
SI.set_quantity_scale_factor(kelvin, One)
|
| 106 |
+
|
| 107 |
+
SI.set_quantity_scale_factor(mole, One)
|
| 108 |
+
|
| 109 |
+
SI.set_quantity_scale_factor(candela, One)
|
| 110 |
+
|
| 111 |
+
# MKSA extension to MKS: derived units
|
| 112 |
+
|
| 113 |
+
SI.set_quantity_scale_factor(coulomb, One)
|
| 114 |
+
|
| 115 |
+
SI.set_quantity_scale_factor(volt, joule/coulomb)
|
| 116 |
+
|
| 117 |
+
SI.set_quantity_scale_factor(ohm, volt/ampere)
|
| 118 |
+
|
| 119 |
+
SI.set_quantity_scale_factor(siemens, ampere/volt)
|
| 120 |
+
|
| 121 |
+
SI.set_quantity_scale_factor(farad, coulomb/volt)
|
| 122 |
+
|
| 123 |
+
SI.set_quantity_scale_factor(henry, volt*second/ampere)
|
| 124 |
+
|
| 125 |
+
SI.set_quantity_scale_factor(tesla, volt*second/meter**2)
|
| 126 |
+
|
| 127 |
+
SI.set_quantity_scale_factor(weber, joule/ampere)
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
SI.set_quantity_dimension(lux, luminous_intensity / length ** 2)
|
| 131 |
+
SI.set_quantity_scale_factor(lux, steradian*candela/meter**2)
|
| 132 |
+
|
| 133 |
+
# katal is the SI unit of catalytic activity
|
| 134 |
+
|
| 135 |
+
SI.set_quantity_dimension(katal, amount_of_substance / time)
|
| 136 |
+
SI.set_quantity_scale_factor(katal, mol/second)
|
| 137 |
+
|
| 138 |
+
# gray is the SI unit of absorbed dose
|
| 139 |
+
|
| 140 |
+
SI.set_quantity_dimension(gray, energy / mass)
|
| 141 |
+
SI.set_quantity_scale_factor(gray, meter**2/second**2)
|
| 142 |
+
|
| 143 |
+
# becquerel is the SI unit of radioactivity
|
| 144 |
+
|
| 145 |
+
SI.set_quantity_dimension(becquerel, 1 / time)
|
| 146 |
+
SI.set_quantity_scale_factor(becquerel, 1/second)
|
| 147 |
+
|
| 148 |
+
#### CONSTANTS ####
|
| 149 |
+
|
| 150 |
+
# elementary charge
|
| 151 |
+
# REF: NIST SP 959 (June 2019)
|
| 152 |
+
|
| 153 |
+
SI.set_quantity_dimension(elementary_charge, charge)
|
| 154 |
+
SI.set_quantity_scale_factor(elementary_charge, 1.602176634e-19*coulomb)
|
| 155 |
+
|
| 156 |
+
# Electronvolt
|
| 157 |
+
# REF: NIST SP 959 (June 2019)
|
| 158 |
+
|
| 159 |
+
SI.set_quantity_dimension(electronvolt, energy)
|
| 160 |
+
SI.set_quantity_scale_factor(electronvolt, 1.602176634e-19*joule)
|
| 161 |
+
|
| 162 |
+
# Avogadro number
|
| 163 |
+
# REF: NIST SP 959 (June 2019)
|
| 164 |
+
|
| 165 |
+
SI.set_quantity_dimension(avogadro_number, One)
|
| 166 |
+
SI.set_quantity_scale_factor(avogadro_number, 6.02214076e23)
|
| 167 |
+
|
| 168 |
+
# Avogadro constant
|
| 169 |
+
|
| 170 |
+
SI.set_quantity_dimension(avogadro_constant, amount_of_substance ** -1)
|
| 171 |
+
SI.set_quantity_scale_factor(avogadro_constant, avogadro_number / mol)
|
| 172 |
+
|
| 173 |
+
# Boltzmann constant
|
| 174 |
+
# REF: NIST SP 959 (June 2019)
|
| 175 |
+
|
| 176 |
+
SI.set_quantity_dimension(boltzmann_constant, energy / temperature)
|
| 177 |
+
SI.set_quantity_scale_factor(boltzmann_constant, 1.380649e-23*joule/kelvin)
|
| 178 |
+
|
| 179 |
+
# Stefan-Boltzmann constant
|
| 180 |
+
# REF: NIST SP 959 (June 2019)
|
| 181 |
+
|
| 182 |
+
SI.set_quantity_dimension(stefan_boltzmann_constant, energy * time ** -1 * length ** -2 * temperature ** -4)
|
| 183 |
+
SI.set_quantity_scale_factor(stefan_boltzmann_constant, pi**2 * boltzmann_constant**4 / (60 * hbar**3 * speed_of_light ** 2))
|
| 184 |
+
|
| 185 |
+
# Atomic mass
|
| 186 |
+
# REF: NIST SP 959 (June 2019)
|
| 187 |
+
|
| 188 |
+
SI.set_quantity_dimension(atomic_mass_constant, mass)
|
| 189 |
+
SI.set_quantity_scale_factor(atomic_mass_constant, 1.66053906660e-24*gram)
|
| 190 |
+
|
| 191 |
+
# Molar gas constant
|
| 192 |
+
# REF: NIST SP 959 (June 2019)
|
| 193 |
+
|
| 194 |
+
SI.set_quantity_dimension(molar_gas_constant, energy / (temperature * amount_of_substance))
|
| 195 |
+
SI.set_quantity_scale_factor(molar_gas_constant, boltzmann_constant * avogadro_constant)
|
| 196 |
+
|
| 197 |
+
# Faraday constant
|
| 198 |
+
|
| 199 |
+
SI.set_quantity_dimension(faraday_constant, charge / amount_of_substance)
|
| 200 |
+
SI.set_quantity_scale_factor(faraday_constant, elementary_charge * avogadro_constant)
|
| 201 |
+
|
| 202 |
+
# Josephson constant
|
| 203 |
+
|
| 204 |
+
SI.set_quantity_dimension(josephson_constant, frequency / voltage)
|
| 205 |
+
SI.set_quantity_scale_factor(josephson_constant, 0.5 * planck / elementary_charge)
|
| 206 |
+
|
| 207 |
+
# Von Klitzing constant
|
| 208 |
+
|
| 209 |
+
SI.set_quantity_dimension(von_klitzing_constant, voltage / current)
|
| 210 |
+
SI.set_quantity_scale_factor(von_klitzing_constant, hbar / elementary_charge ** 2)
|
| 211 |
+
|
| 212 |
+
# Acceleration due to gravity (on the Earth surface)
|
| 213 |
+
|
| 214 |
+
SI.set_quantity_dimension(acceleration_due_to_gravity, acceleration)
|
| 215 |
+
SI.set_quantity_scale_factor(acceleration_due_to_gravity, 9.80665*meter/second**2)
|
| 216 |
+
|
| 217 |
+
# magnetic constant:
|
| 218 |
+
|
| 219 |
+
SI.set_quantity_dimension(magnetic_constant, force / current ** 2)
|
| 220 |
+
SI.set_quantity_scale_factor(magnetic_constant, 4*pi/10**7 * newton/ampere**2)
|
| 221 |
+
|
| 222 |
+
# electric constant:
|
| 223 |
+
|
| 224 |
+
SI.set_quantity_dimension(vacuum_permittivity, capacitance / length)
|
| 225 |
+
SI.set_quantity_scale_factor(vacuum_permittivity, 1/(u0 * c**2))
|
| 226 |
+
|
| 227 |
+
# vacuum impedance:
|
| 228 |
+
|
| 229 |
+
SI.set_quantity_dimension(vacuum_impedance, impedance)
|
| 230 |
+
SI.set_quantity_scale_factor(vacuum_impedance, u0 * c)
|
| 231 |
+
|
| 232 |
+
# Electron rest mass
|
| 233 |
+
SI.set_quantity_dimension(electron_rest_mass, mass)
|
| 234 |
+
SI.set_quantity_scale_factor(electron_rest_mass, 9.1093837015e-31*kilogram)
|
| 235 |
+
|
| 236 |
+
# Coulomb's constant:
|
| 237 |
+
SI.set_quantity_dimension(coulomb_constant, force * length ** 2 / charge ** 2)
|
| 238 |
+
SI.set_quantity_scale_factor(coulomb_constant, 1/(4*pi*vacuum_permittivity))
|
| 239 |
+
|
| 240 |
+
SI.set_quantity_dimension(psi, pressure)
|
| 241 |
+
SI.set_quantity_scale_factor(psi, pound * gee / inch ** 2)
|
| 242 |
+
|
| 243 |
+
SI.set_quantity_dimension(mmHg, pressure)
|
| 244 |
+
SI.set_quantity_scale_factor(mmHg, dHg0 * acceleration_due_to_gravity * kilogram / meter**2)
|
| 245 |
+
|
| 246 |
+
SI.set_quantity_dimension(milli_mass_unit, mass)
|
| 247 |
+
SI.set_quantity_scale_factor(milli_mass_unit, atomic_mass_unit/1000)
|
| 248 |
+
|
| 249 |
+
SI.set_quantity_dimension(quart, length ** 3)
|
| 250 |
+
SI.set_quantity_scale_factor(quart, Rational(231, 4) * inch**3)
|
| 251 |
+
|
| 252 |
+
# Other convenient units and magnitudes
|
| 253 |
+
|
| 254 |
+
SI.set_quantity_dimension(lightyear, length)
|
| 255 |
+
SI.set_quantity_scale_factor(lightyear, speed_of_light*julian_year)
|
| 256 |
+
|
| 257 |
+
SI.set_quantity_dimension(astronomical_unit, length)
|
| 258 |
+
SI.set_quantity_scale_factor(astronomical_unit, 149597870691*meter)
|
| 259 |
+
|
| 260 |
+
# Fundamental Planck units:
|
| 261 |
+
|
| 262 |
+
SI.set_quantity_dimension(planck_mass, mass)
|
| 263 |
+
SI.set_quantity_scale_factor(planck_mass, sqrt(hbar*speed_of_light/G))
|
| 264 |
+
|
| 265 |
+
SI.set_quantity_dimension(planck_time, time)
|
| 266 |
+
SI.set_quantity_scale_factor(planck_time, sqrt(hbar*G/speed_of_light**5))
|
| 267 |
+
|
| 268 |
+
SI.set_quantity_dimension(planck_temperature, temperature)
|
| 269 |
+
SI.set_quantity_scale_factor(planck_temperature, sqrt(hbar*speed_of_light**5/G/boltzmann**2))
|
| 270 |
+
|
| 271 |
+
SI.set_quantity_dimension(planck_length, length)
|
| 272 |
+
SI.set_quantity_scale_factor(planck_length, sqrt(hbar*G/speed_of_light**3))
|
| 273 |
+
|
| 274 |
+
SI.set_quantity_dimension(planck_charge, charge)
|
| 275 |
+
SI.set_quantity_scale_factor(planck_charge, sqrt(4*pi*electric_constant*hbar*speed_of_light))
|
| 276 |
+
|
| 277 |
+
# Derived Planck units:
|
| 278 |
+
|
| 279 |
+
SI.set_quantity_dimension(planck_area, length ** 2)
|
| 280 |
+
SI.set_quantity_scale_factor(planck_area, planck_length**2)
|
| 281 |
+
|
| 282 |
+
SI.set_quantity_dimension(planck_volume, length ** 3)
|
| 283 |
+
SI.set_quantity_scale_factor(planck_volume, planck_length**3)
|
| 284 |
+
|
| 285 |
+
SI.set_quantity_dimension(planck_momentum, mass * velocity)
|
| 286 |
+
SI.set_quantity_scale_factor(planck_momentum, planck_mass * speed_of_light)
|
| 287 |
+
|
| 288 |
+
SI.set_quantity_dimension(planck_energy, energy)
|
| 289 |
+
SI.set_quantity_scale_factor(planck_energy, planck_mass * speed_of_light**2)
|
| 290 |
+
|
| 291 |
+
SI.set_quantity_dimension(planck_force, force)
|
| 292 |
+
SI.set_quantity_scale_factor(planck_force, planck_energy / planck_length)
|
| 293 |
+
|
| 294 |
+
SI.set_quantity_dimension(planck_power, power)
|
| 295 |
+
SI.set_quantity_scale_factor(planck_power, planck_energy / planck_time)
|
| 296 |
+
|
| 297 |
+
SI.set_quantity_dimension(planck_density, mass / length ** 3)
|
| 298 |
+
SI.set_quantity_scale_factor(planck_density, planck_mass / planck_length**3)
|
| 299 |
+
|
| 300 |
+
SI.set_quantity_dimension(planck_energy_density, energy / length ** 3)
|
| 301 |
+
SI.set_quantity_scale_factor(planck_energy_density, planck_energy / planck_length**3)
|
| 302 |
+
|
| 303 |
+
SI.set_quantity_dimension(planck_intensity, mass * time ** (-3))
|
| 304 |
+
SI.set_quantity_scale_factor(planck_intensity, planck_energy_density * speed_of_light)
|
| 305 |
+
|
| 306 |
+
SI.set_quantity_dimension(planck_angular_frequency, 1 / time)
|
| 307 |
+
SI.set_quantity_scale_factor(planck_angular_frequency, 1 / planck_time)
|
| 308 |
+
|
| 309 |
+
SI.set_quantity_dimension(planck_pressure, pressure)
|
| 310 |
+
SI.set_quantity_scale_factor(planck_pressure, planck_force / planck_length**2)
|
| 311 |
+
|
| 312 |
+
SI.set_quantity_dimension(planck_current, current)
|
| 313 |
+
SI.set_quantity_scale_factor(planck_current, planck_charge / planck_time)
|
| 314 |
+
|
| 315 |
+
SI.set_quantity_dimension(planck_voltage, voltage)
|
| 316 |
+
SI.set_quantity_scale_factor(planck_voltage, planck_energy / planck_charge)
|
| 317 |
+
|
| 318 |
+
SI.set_quantity_dimension(planck_impedance, impedance)
|
| 319 |
+
SI.set_quantity_scale_factor(planck_impedance, planck_voltage / planck_current)
|
| 320 |
+
|
| 321 |
+
SI.set_quantity_dimension(planck_acceleration, acceleration)
|
| 322 |
+
SI.set_quantity_scale_factor(planck_acceleration, speed_of_light / planck_time)
|
| 323 |
+
|
| 324 |
+
# Older units for radioactivity
|
| 325 |
+
|
| 326 |
+
SI.set_quantity_dimension(curie, 1 / time)
|
| 327 |
+
SI.set_quantity_scale_factor(curie, 37000000000*becquerel)
|
| 328 |
+
|
| 329 |
+
SI.set_quantity_dimension(rutherford, 1 / time)
|
| 330 |
+
SI.set_quantity_scale_factor(rutherford, 1000000*becquerel)
|
| 331 |
+
|
| 332 |
+
|
| 333 |
+
# check that scale factors are the right SI dimensions:
|
| 334 |
+
for _scale_factor, _dimension in zip(
|
| 335 |
+
SI._quantity_scale_factors.values(),
|
| 336 |
+
SI._quantity_dimension_map.values()
|
| 337 |
+
):
|
| 338 |
+
dimex = SI.get_dimensional_expr(_scale_factor)
|
| 339 |
+
if dimex != 1:
|
| 340 |
+
# XXX: equivalent_dims is an instance method taking two arguments in
|
| 341 |
+
# addition to self so this can not work:
|
| 342 |
+
if not DimensionSystem.equivalent_dims(_dimension, Dimension(dimex)): # type: ignore
|
| 343 |
+
raise ValueError("quantity value and dimension mismatch")
|
| 344 |
+
del _scale_factor, _dimension
|
| 345 |
+
|
| 346 |
+
__all__ = [
|
| 347 |
+
'mmHg', 'atmosphere', 'inductance', 'newton', 'meter',
|
| 348 |
+
'vacuum_permittivity', 'pascal', 'magnetic_constant', 'voltage',
|
| 349 |
+
'angular_mil', 'luminous_intensity', 'all_units',
|
| 350 |
+
'julian_year', 'weber', 'exbibyte', 'liter',
|
| 351 |
+
'molar_gas_constant', 'faraday_constant', 'avogadro_constant',
|
| 352 |
+
'lightyear', 'planck_density', 'gee', 'mol', 'bit', 'gray',
|
| 353 |
+
'planck_momentum', 'bar', 'magnetic_density', 'prefix_unit', 'PREFIXES',
|
| 354 |
+
'planck_time', 'dimex', 'gram', 'candela', 'force', 'planck_intensity',
|
| 355 |
+
'energy', 'becquerel', 'planck_acceleration', 'speed_of_light',
|
| 356 |
+
'conductance', 'frequency', 'coulomb_constant', 'degree', 'lux', 'planck',
|
| 357 |
+
'current', 'planck_current', 'tebibyte', 'planck_power', 'MKSA', 'power',
|
| 358 |
+
'K', 'planck_volume', 'quart', 'pressure', 'amount_of_substance',
|
| 359 |
+
'joule', 'boltzmann_constant', 'Dimension', 'c', 'planck_force', 'length',
|
| 360 |
+
'watt', 'action', 'hbar', 'gibibyte', 'DimensionSystem', 'cd', 'volt',
|
| 361 |
+
'planck_charge', 'dioptre', 'vacuum_impedance', 'dimsys_default', 'farad',
|
| 362 |
+
'charge', 'gravitational_constant', 'temperature', 'u0', 'hertz',
|
| 363 |
+
'capacitance', 'tesla', 'steradian', 'planck_mass', 'josephson_constant',
|
| 364 |
+
'planck_area', 'stefan_boltzmann_constant', 'base_dims',
|
| 365 |
+
'astronomical_unit', 'radian', 'planck_voltage', 'impedance',
|
| 366 |
+
'planck_energy', 'Da', 'atomic_mass_constant', 'rutherford', 'second', 'inch',
|
| 367 |
+
'elementary_charge', 'SI', 'electronvolt', 'dimsys_SI', 'henry',
|
| 368 |
+
'planck_angular_frequency', 'ohm', 'pound', 'planck_pressure', 'G', 'psi',
|
| 369 |
+
'dHg0', 'von_klitzing_constant', 'planck_length', 'avogadro_number',
|
| 370 |
+
'mole', 'acceleration', 'information', 'planck_energy_density',
|
| 371 |
+
'mebibyte', 's', 'acceleration_due_to_gravity', 'electron_rest_mass',
|
| 372 |
+
'planck_temperature', 'units', 'mass', 'dimsys_MKSA', 'kelvin', 'kPa',
|
| 373 |
+
'boltzmann', 'milli_mass_unit', 'planck_impedance', 'electric_constant',
|
| 374 |
+
'derived_dims', 'kg', 'coulomb', 'siemens', 'byte', 'magnetic_flux',
|
| 375 |
+
'atomic_mass_unit', 'm', 'kibibyte', 'kilogram', 'One', 'curie', 'u',
|
| 376 |
+
'time', 'pebibyte', 'velocity', 'ampere', 'katal',
|
| 377 |
+
]
|
.venv/Lib/site-packages/sympy/physics/units/tests/__init__.py
ADDED
|
File without changes
|
.venv/Lib/site-packages/sympy/physics/units/tests/test_dimensions.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.physics.units.systems.si import dimsys_SI
|
| 2 |
+
|
| 3 |
+
from sympy.core.numbers import pi
|
| 4 |
+
from sympy.core.singleton import S
|
| 5 |
+
from sympy.core.symbol import Symbol
|
| 6 |
+
from sympy.functions.elementary.complexes import Abs
|
| 7 |
+
from sympy.functions.elementary.exponential import log
|
| 8 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 9 |
+
from sympy.functions.elementary.trigonometric import (acos, atan2, cos)
|
| 10 |
+
from sympy.physics.units.dimensions import Dimension
|
| 11 |
+
from sympy.physics.units.definitions.dimension_definitions import (
|
| 12 |
+
length, time, mass, force, pressure, angle
|
| 13 |
+
)
|
| 14 |
+
from sympy.physics.units import foot
|
| 15 |
+
from sympy.testing.pytest import raises
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def test_Dimension_definition():
|
| 19 |
+
assert dimsys_SI.get_dimensional_dependencies(length) == {length: 1}
|
| 20 |
+
assert length.name == Symbol("length")
|
| 21 |
+
assert length.symbol == Symbol("L")
|
| 22 |
+
|
| 23 |
+
halflength = sqrt(length)
|
| 24 |
+
assert dimsys_SI.get_dimensional_dependencies(halflength) == {length: S.Half}
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def test_Dimension_error_definition():
|
| 28 |
+
# tuple with more or less than two entries
|
| 29 |
+
raises(TypeError, lambda: Dimension(("length", 1, 2)))
|
| 30 |
+
raises(TypeError, lambda: Dimension(["length"]))
|
| 31 |
+
|
| 32 |
+
# non-number power
|
| 33 |
+
raises(TypeError, lambda: Dimension({"length": "a"}))
|
| 34 |
+
|
| 35 |
+
# non-number with named argument
|
| 36 |
+
raises(TypeError, lambda: Dimension({"length": (1, 2)}))
|
| 37 |
+
|
| 38 |
+
# symbol should by Symbol or str
|
| 39 |
+
raises(AssertionError, lambda: Dimension("length", symbol=1))
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def test_str():
|
| 43 |
+
assert str(Dimension("length")) == "Dimension(length)"
|
| 44 |
+
assert str(Dimension("length", "L")) == "Dimension(length, L)"
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def test_Dimension_properties():
|
| 48 |
+
assert dimsys_SI.is_dimensionless(length) is False
|
| 49 |
+
assert dimsys_SI.is_dimensionless(length/length) is True
|
| 50 |
+
assert dimsys_SI.is_dimensionless(Dimension("undefined")) is False
|
| 51 |
+
|
| 52 |
+
assert length.has_integer_powers(dimsys_SI) is True
|
| 53 |
+
assert (length**(-1)).has_integer_powers(dimsys_SI) is True
|
| 54 |
+
assert (length**1.5).has_integer_powers(dimsys_SI) is False
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
def test_Dimension_add_sub():
|
| 58 |
+
assert length + length == length
|
| 59 |
+
assert length - length == length
|
| 60 |
+
assert -length == length
|
| 61 |
+
|
| 62 |
+
raises(TypeError, lambda: length + foot)
|
| 63 |
+
raises(TypeError, lambda: foot + length)
|
| 64 |
+
raises(TypeError, lambda: length - foot)
|
| 65 |
+
raises(TypeError, lambda: foot - length)
|
| 66 |
+
|
| 67 |
+
# issue 14547 - only raise error for dimensional args; allow
|
| 68 |
+
# others to pass
|
| 69 |
+
x = Symbol('x')
|
| 70 |
+
e = length + x
|
| 71 |
+
assert e == x + length and e.is_Add and set(e.args) == {length, x}
|
| 72 |
+
e = length + 1
|
| 73 |
+
assert e == 1 + length == 1 - length and e.is_Add and set(e.args) == {length, 1}
|
| 74 |
+
|
| 75 |
+
assert dimsys_SI.get_dimensional_dependencies(mass * length / time**2 + force) == \
|
| 76 |
+
{length: 1, mass: 1, time: -2}
|
| 77 |
+
assert dimsys_SI.get_dimensional_dependencies(mass * length / time**2 + force -
|
| 78 |
+
pressure * length**2) == \
|
| 79 |
+
{length: 1, mass: 1, time: -2}
|
| 80 |
+
|
| 81 |
+
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(mass * length / time**2 + pressure))
|
| 82 |
+
|
| 83 |
+
def test_Dimension_mul_div_exp():
|
| 84 |
+
assert 2*length == length*2 == length/2 == length
|
| 85 |
+
assert 2/length == 1/length
|
| 86 |
+
x = Symbol('x')
|
| 87 |
+
m = x*length
|
| 88 |
+
assert m == length*x and m.is_Mul and set(m.args) == {x, length}
|
| 89 |
+
d = x/length
|
| 90 |
+
assert d == x*length**-1 and d.is_Mul and set(d.args) == {x, 1/length}
|
| 91 |
+
d = length/x
|
| 92 |
+
assert d == length*x**-1 and d.is_Mul and set(d.args) == {1/x, length}
|
| 93 |
+
|
| 94 |
+
velo = length / time
|
| 95 |
+
|
| 96 |
+
assert (length * length) == length ** 2
|
| 97 |
+
|
| 98 |
+
assert dimsys_SI.get_dimensional_dependencies(length * length) == {length: 2}
|
| 99 |
+
assert dimsys_SI.get_dimensional_dependencies(length ** 2) == {length: 2}
|
| 100 |
+
assert dimsys_SI.get_dimensional_dependencies(length * time) == {length: 1, time: 1}
|
| 101 |
+
assert dimsys_SI.get_dimensional_dependencies(velo) == {length: 1, time: -1}
|
| 102 |
+
assert dimsys_SI.get_dimensional_dependencies(velo ** 2) == {length: 2, time: -2}
|
| 103 |
+
|
| 104 |
+
assert dimsys_SI.get_dimensional_dependencies(length / length) == {}
|
| 105 |
+
assert dimsys_SI.get_dimensional_dependencies(velo / length * time) == {}
|
| 106 |
+
assert dimsys_SI.get_dimensional_dependencies(length ** -1) == {length: -1}
|
| 107 |
+
assert dimsys_SI.get_dimensional_dependencies(velo ** -1.5) == {length: -1.5, time: 1.5}
|
| 108 |
+
|
| 109 |
+
length_a = length**"a"
|
| 110 |
+
assert dimsys_SI.get_dimensional_dependencies(length_a) == {length: Symbol("a")}
|
| 111 |
+
|
| 112 |
+
assert dimsys_SI.get_dimensional_dependencies(length**pi) == {length: pi}
|
| 113 |
+
assert dimsys_SI.get_dimensional_dependencies(length**(length/length)) == {length: Dimension(1)}
|
| 114 |
+
|
| 115 |
+
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(length**length))
|
| 116 |
+
|
| 117 |
+
assert length != 1
|
| 118 |
+
assert length / length != 1
|
| 119 |
+
|
| 120 |
+
length_0 = length ** 0
|
| 121 |
+
assert dimsys_SI.get_dimensional_dependencies(length_0) == {}
|
| 122 |
+
|
| 123 |
+
# issue 18738
|
| 124 |
+
a = Symbol('a')
|
| 125 |
+
b = Symbol('b')
|
| 126 |
+
c = sqrt(a**2 + b**2)
|
| 127 |
+
c_dim = c.subs({a: length, b: length})
|
| 128 |
+
assert dimsys_SI.equivalent_dims(c_dim, length)
|
| 129 |
+
|
| 130 |
+
def test_Dimension_functions():
|
| 131 |
+
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(cos(length)))
|
| 132 |
+
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(acos(angle)))
|
| 133 |
+
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(atan2(length, time)))
|
| 134 |
+
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(log(length)))
|
| 135 |
+
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(log(100, length)))
|
| 136 |
+
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(log(length, 10)))
|
| 137 |
+
|
| 138 |
+
assert dimsys_SI.get_dimensional_dependencies(pi) == {}
|
| 139 |
+
|
| 140 |
+
assert dimsys_SI.get_dimensional_dependencies(cos(1)) == {}
|
| 141 |
+
assert dimsys_SI.get_dimensional_dependencies(cos(angle)) == {}
|
| 142 |
+
|
| 143 |
+
assert dimsys_SI.get_dimensional_dependencies(atan2(length, length)) == {}
|
| 144 |
+
|
| 145 |
+
assert dimsys_SI.get_dimensional_dependencies(log(length / length, length / length)) == {}
|
| 146 |
+
|
| 147 |
+
assert dimsys_SI.get_dimensional_dependencies(Abs(length)) == {length: 1}
|
| 148 |
+
assert dimsys_SI.get_dimensional_dependencies(Abs(length / length)) == {}
|
| 149 |
+
|
| 150 |
+
assert dimsys_SI.get_dimensional_dependencies(sqrt(-1)) == {}
|
.venv/Lib/site-packages/sympy/physics/units/tests/test_dimensionsystem.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.symbol import symbols
|
| 2 |
+
from sympy.matrices.dense import (Matrix, eye)
|
| 3 |
+
from sympy.physics.units.definitions.dimension_definitions import (
|
| 4 |
+
action, current, length, mass, time,
|
| 5 |
+
velocity)
|
| 6 |
+
from sympy.physics.units.dimensions import DimensionSystem
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def test_extend():
|
| 10 |
+
ms = DimensionSystem((length, time), (velocity,))
|
| 11 |
+
|
| 12 |
+
mks = ms.extend((mass,), (action,))
|
| 13 |
+
|
| 14 |
+
res = DimensionSystem((length, time, mass), (velocity, action))
|
| 15 |
+
assert mks.base_dims == res.base_dims
|
| 16 |
+
assert mks.derived_dims == res.derived_dims
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def test_list_dims():
|
| 20 |
+
dimsys = DimensionSystem((length, time, mass))
|
| 21 |
+
|
| 22 |
+
assert dimsys.list_can_dims == (length, mass, time)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def test_dim_can_vector():
|
| 26 |
+
dimsys = DimensionSystem(
|
| 27 |
+
[length, mass, time],
|
| 28 |
+
[velocity, action],
|
| 29 |
+
{
|
| 30 |
+
velocity: {length: 1, time: -1}
|
| 31 |
+
}
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
assert dimsys.dim_can_vector(length) == Matrix([1, 0, 0])
|
| 35 |
+
assert dimsys.dim_can_vector(velocity) == Matrix([1, 0, -1])
|
| 36 |
+
|
| 37 |
+
dimsys = DimensionSystem(
|
| 38 |
+
(length, velocity, action),
|
| 39 |
+
(mass, time),
|
| 40 |
+
{
|
| 41 |
+
time: {length: 1, velocity: -1}
|
| 42 |
+
}
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
assert dimsys.dim_can_vector(length) == Matrix([0, 1, 0])
|
| 46 |
+
assert dimsys.dim_can_vector(velocity) == Matrix([0, 0, 1])
|
| 47 |
+
assert dimsys.dim_can_vector(time) == Matrix([0, 1, -1])
|
| 48 |
+
|
| 49 |
+
dimsys = DimensionSystem(
|
| 50 |
+
(length, mass, time),
|
| 51 |
+
(velocity, action),
|
| 52 |
+
{velocity: {length: 1, time: -1},
|
| 53 |
+
action: {mass: 1, length: 2, time: -1}})
|
| 54 |
+
|
| 55 |
+
assert dimsys.dim_vector(length) == Matrix([1, 0, 0])
|
| 56 |
+
assert dimsys.dim_vector(velocity) == Matrix([1, 0, -1])
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def test_inv_can_transf_matrix():
|
| 60 |
+
dimsys = DimensionSystem((length, mass, time))
|
| 61 |
+
assert dimsys.inv_can_transf_matrix == eye(3)
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
def test_can_transf_matrix():
|
| 65 |
+
dimsys = DimensionSystem((length, mass, time))
|
| 66 |
+
assert dimsys.can_transf_matrix == eye(3)
|
| 67 |
+
|
| 68 |
+
dimsys = DimensionSystem((length, velocity, action))
|
| 69 |
+
assert dimsys.can_transf_matrix == eye(3)
|
| 70 |
+
|
| 71 |
+
dimsys = DimensionSystem((length, time), (velocity,), {velocity: {length: 1, time: -1}})
|
| 72 |
+
assert dimsys.can_transf_matrix == eye(2)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def test_is_consistent():
|
| 76 |
+
assert DimensionSystem((length, time)).is_consistent is True
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def test_print_dim_base():
|
| 80 |
+
mksa = DimensionSystem(
|
| 81 |
+
(length, time, mass, current),
|
| 82 |
+
(action,),
|
| 83 |
+
{action: {mass: 1, length: 2, time: -1}})
|
| 84 |
+
L, M, T = symbols("L M T")
|
| 85 |
+
assert mksa.print_dim_base(action) == L**2*M/T
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def test_dim():
|
| 89 |
+
dimsys = DimensionSystem(
|
| 90 |
+
(length, mass, time),
|
| 91 |
+
(velocity, action),
|
| 92 |
+
{velocity: {length: 1, time: -1},
|
| 93 |
+
action: {mass: 1, length: 2, time: -1}}
|
| 94 |
+
)
|
| 95 |
+
assert dimsys.dim == 3
|
.venv/Lib/site-packages/sympy/physics/units/tests/test_prefixes.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.core.mul import Mul
|
| 2 |
+
from sympy.core.numbers import Rational
|
| 3 |
+
from sympy.core.singleton import S
|
| 4 |
+
from sympy.core.symbol import (Symbol, symbols)
|
| 5 |
+
from sympy.physics.units import Quantity, length, meter, W
|
| 6 |
+
from sympy.physics.units.prefixes import PREFIXES, Prefix, prefix_unit, kilo, \
|
| 7 |
+
kibi
|
| 8 |
+
from sympy.physics.units.systems import SI
|
| 9 |
+
|
| 10 |
+
x = Symbol('x')
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def test_prefix_operations():
|
| 14 |
+
m = PREFIXES['m']
|
| 15 |
+
k = PREFIXES['k']
|
| 16 |
+
M = PREFIXES['M']
|
| 17 |
+
|
| 18 |
+
dodeca = Prefix('dodeca', 'dd', 1, base=12)
|
| 19 |
+
|
| 20 |
+
assert m * k is S.One
|
| 21 |
+
assert m * W == W / 1000
|
| 22 |
+
assert k * k == M
|
| 23 |
+
assert 1 / m == k
|
| 24 |
+
assert k / m == M
|
| 25 |
+
|
| 26 |
+
assert dodeca * dodeca == 144
|
| 27 |
+
assert 1 / dodeca == S.One / 12
|
| 28 |
+
assert k / dodeca == S(1000) / 12
|
| 29 |
+
assert dodeca / dodeca is S.One
|
| 30 |
+
|
| 31 |
+
m = Quantity("fake_meter")
|
| 32 |
+
SI.set_quantity_dimension(m, S.One)
|
| 33 |
+
SI.set_quantity_scale_factor(m, S.One)
|
| 34 |
+
|
| 35 |
+
assert dodeca * m == 12 * m
|
| 36 |
+
assert dodeca / m == 12 / m
|
| 37 |
+
|
| 38 |
+
expr1 = kilo * 3
|
| 39 |
+
assert isinstance(expr1, Mul)
|
| 40 |
+
assert expr1.args == (3, kilo)
|
| 41 |
+
|
| 42 |
+
expr2 = kilo * x
|
| 43 |
+
assert isinstance(expr2, Mul)
|
| 44 |
+
assert expr2.args == (x, kilo)
|
| 45 |
+
|
| 46 |
+
expr3 = kilo / 3
|
| 47 |
+
assert isinstance(expr3, Mul)
|
| 48 |
+
assert expr3.args == (Rational(1, 3), kilo)
|
| 49 |
+
assert expr3.args == (S.One/3, kilo)
|
| 50 |
+
|
| 51 |
+
expr4 = kilo / x
|
| 52 |
+
assert isinstance(expr4, Mul)
|
| 53 |
+
assert expr4.args == (1/x, kilo)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def test_prefix_unit():
|
| 57 |
+
m = Quantity("fake_meter", abbrev="m")
|
| 58 |
+
m.set_global_relative_scale_factor(1, meter)
|
| 59 |
+
|
| 60 |
+
pref = {"m": PREFIXES["m"], "c": PREFIXES["c"], "d": PREFIXES["d"]}
|
| 61 |
+
|
| 62 |
+
q1 = Quantity("millifake_meter", abbrev="mm")
|
| 63 |
+
q2 = Quantity("centifake_meter", abbrev="cm")
|
| 64 |
+
q3 = Quantity("decifake_meter", abbrev="dm")
|
| 65 |
+
|
| 66 |
+
SI.set_quantity_dimension(q1, length)
|
| 67 |
+
|
| 68 |
+
SI.set_quantity_scale_factor(q1, PREFIXES["m"])
|
| 69 |
+
SI.set_quantity_scale_factor(q1, PREFIXES["c"])
|
| 70 |
+
SI.set_quantity_scale_factor(q1, PREFIXES["d"])
|
| 71 |
+
|
| 72 |
+
res = [q1, q2, q3]
|
| 73 |
+
|
| 74 |
+
prefs = prefix_unit(m, pref)
|
| 75 |
+
assert set(prefs) == set(res)
|
| 76 |
+
assert {v.abbrev for v in prefs} == set(symbols("mm,cm,dm"))
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def test_bases():
|
| 80 |
+
assert kilo.base == 10
|
| 81 |
+
assert kibi.base == 2
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def test_repr():
|
| 85 |
+
assert eval(repr(kilo)) == kilo
|
| 86 |
+
assert eval(repr(kibi)) == kibi
|
.venv/Lib/site-packages/sympy/physics/units/tests/test_quantities.py
ADDED
|
@@ -0,0 +1,575 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import warnings
|
| 2 |
+
|
| 3 |
+
from sympy.core.add import Add
|
| 4 |
+
from sympy.core.function import (Function, diff)
|
| 5 |
+
from sympy.core.numbers import (Number, Rational)
|
| 6 |
+
from sympy.core.singleton import S
|
| 7 |
+
from sympy.core.symbol import (Symbol, symbols)
|
| 8 |
+
from sympy.functions.elementary.complexes import Abs
|
| 9 |
+
from sympy.functions.elementary.exponential import (exp, log)
|
| 10 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 11 |
+
from sympy.functions.elementary.trigonometric import sin
|
| 12 |
+
from sympy.integrals.integrals import integrate
|
| 13 |
+
from sympy.physics.units import (amount_of_substance, area, convert_to, find_unit,
|
| 14 |
+
volume, kilometer, joule, molar_gas_constant,
|
| 15 |
+
vacuum_permittivity, elementary_charge, volt,
|
| 16 |
+
ohm)
|
| 17 |
+
from sympy.physics.units.definitions import (amu, au, centimeter, coulomb,
|
| 18 |
+
day, foot, grams, hour, inch, kg, km, m, meter, millimeter,
|
| 19 |
+
minute, quart, s, second, speed_of_light, bit,
|
| 20 |
+
byte, kibibyte, mebibyte, gibibyte, tebibyte, pebibyte, exbibyte,
|
| 21 |
+
kilogram, gravitational_constant, electron_rest_mass)
|
| 22 |
+
|
| 23 |
+
from sympy.physics.units.definitions.dimension_definitions import (
|
| 24 |
+
Dimension, charge, length, time, temperature, pressure,
|
| 25 |
+
energy, mass
|
| 26 |
+
)
|
| 27 |
+
from sympy.physics.units.prefixes import PREFIXES, kilo
|
| 28 |
+
from sympy.physics.units.quantities import PhysicalConstant, Quantity
|
| 29 |
+
from sympy.physics.units.systems import SI
|
| 30 |
+
from sympy.testing.pytest import raises
|
| 31 |
+
|
| 32 |
+
k = PREFIXES["k"]
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def test_str_repr():
|
| 36 |
+
assert str(kg) == "kilogram"
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def test_eq():
|
| 40 |
+
# simple test
|
| 41 |
+
assert 10*m == 10*m
|
| 42 |
+
assert 10*m != 10*s
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def test_convert_to():
|
| 46 |
+
q = Quantity("q1")
|
| 47 |
+
q.set_global_relative_scale_factor(S(5000), meter)
|
| 48 |
+
|
| 49 |
+
assert q.convert_to(m) == 5000*m
|
| 50 |
+
|
| 51 |
+
assert speed_of_light.convert_to(m / s) == 299792458 * m / s
|
| 52 |
+
assert day.convert_to(s) == 86400*s
|
| 53 |
+
|
| 54 |
+
# Wrong dimension to convert:
|
| 55 |
+
assert q.convert_to(s) == q
|
| 56 |
+
assert speed_of_light.convert_to(m) == speed_of_light
|
| 57 |
+
|
| 58 |
+
expr = joule*second
|
| 59 |
+
conv = convert_to(expr, joule)
|
| 60 |
+
assert conv == joule*second
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def test_Quantity_definition():
|
| 64 |
+
q = Quantity("s10", abbrev="sabbr")
|
| 65 |
+
q.set_global_relative_scale_factor(10, second)
|
| 66 |
+
u = Quantity("u", abbrev="dam")
|
| 67 |
+
u.set_global_relative_scale_factor(10, meter)
|
| 68 |
+
km = Quantity("km")
|
| 69 |
+
km.set_global_relative_scale_factor(kilo, meter)
|
| 70 |
+
v = Quantity("u")
|
| 71 |
+
v.set_global_relative_scale_factor(5*kilo, meter)
|
| 72 |
+
|
| 73 |
+
assert q.scale_factor == 10
|
| 74 |
+
assert q.dimension == time
|
| 75 |
+
assert q.abbrev == Symbol("sabbr")
|
| 76 |
+
|
| 77 |
+
assert u.dimension == length
|
| 78 |
+
assert u.scale_factor == 10
|
| 79 |
+
assert u.abbrev == Symbol("dam")
|
| 80 |
+
|
| 81 |
+
assert km.scale_factor == 1000
|
| 82 |
+
assert km.func(*km.args) == km
|
| 83 |
+
assert km.func(*km.args).args == km.args
|
| 84 |
+
|
| 85 |
+
assert v.dimension == length
|
| 86 |
+
assert v.scale_factor == 5000
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
def test_abbrev():
|
| 90 |
+
u = Quantity("u")
|
| 91 |
+
u.set_global_relative_scale_factor(S.One, meter)
|
| 92 |
+
|
| 93 |
+
assert u.name == Symbol("u")
|
| 94 |
+
assert u.abbrev == Symbol("u")
|
| 95 |
+
|
| 96 |
+
u = Quantity("u", abbrev="om")
|
| 97 |
+
u.set_global_relative_scale_factor(S(2), meter)
|
| 98 |
+
|
| 99 |
+
assert u.name == Symbol("u")
|
| 100 |
+
assert u.abbrev == Symbol("om")
|
| 101 |
+
assert u.scale_factor == 2
|
| 102 |
+
assert isinstance(u.scale_factor, Number)
|
| 103 |
+
|
| 104 |
+
u = Quantity("u", abbrev="ikm")
|
| 105 |
+
u.set_global_relative_scale_factor(3*kilo, meter)
|
| 106 |
+
|
| 107 |
+
assert u.abbrev == Symbol("ikm")
|
| 108 |
+
assert u.scale_factor == 3000
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
def test_print():
|
| 112 |
+
u = Quantity("unitname", abbrev="dam")
|
| 113 |
+
assert repr(u) == "unitname"
|
| 114 |
+
assert str(u) == "unitname"
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def test_Quantity_eq():
|
| 118 |
+
u = Quantity("u", abbrev="dam")
|
| 119 |
+
v = Quantity("v1")
|
| 120 |
+
assert u != v
|
| 121 |
+
v = Quantity("v2", abbrev="ds")
|
| 122 |
+
assert u != v
|
| 123 |
+
v = Quantity("v3", abbrev="dm")
|
| 124 |
+
assert u != v
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def test_add_sub():
|
| 128 |
+
u = Quantity("u")
|
| 129 |
+
v = Quantity("v")
|
| 130 |
+
w = Quantity("w")
|
| 131 |
+
|
| 132 |
+
u.set_global_relative_scale_factor(S(10), meter)
|
| 133 |
+
v.set_global_relative_scale_factor(S(5), meter)
|
| 134 |
+
w.set_global_relative_scale_factor(S(2), second)
|
| 135 |
+
|
| 136 |
+
assert isinstance(u + v, Add)
|
| 137 |
+
assert (u + v.convert_to(u)) == (1 + S.Half)*u
|
| 138 |
+
assert isinstance(u - v, Add)
|
| 139 |
+
assert (u - v.convert_to(u)) == S.Half*u
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
def test_quantity_abs():
|
| 143 |
+
v_w1 = Quantity('v_w1')
|
| 144 |
+
v_w2 = Quantity('v_w2')
|
| 145 |
+
v_w3 = Quantity('v_w3')
|
| 146 |
+
|
| 147 |
+
v_w1.set_global_relative_scale_factor(1, meter/second)
|
| 148 |
+
v_w2.set_global_relative_scale_factor(1, meter/second)
|
| 149 |
+
v_w3.set_global_relative_scale_factor(1, meter/second)
|
| 150 |
+
|
| 151 |
+
expr = v_w3 - Abs(v_w1 - v_w2)
|
| 152 |
+
|
| 153 |
+
assert SI.get_dimensional_expr(v_w1) == (length/time).name
|
| 154 |
+
|
| 155 |
+
Dq = Dimension(SI.get_dimensional_expr(expr))
|
| 156 |
+
|
| 157 |
+
assert SI.get_dimension_system().get_dimensional_dependencies(Dq) == {
|
| 158 |
+
length: 1,
|
| 159 |
+
time: -1,
|
| 160 |
+
}
|
| 161 |
+
assert meter == sqrt(meter**2)
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
def test_check_unit_consistency():
|
| 165 |
+
u = Quantity("u")
|
| 166 |
+
v = Quantity("v")
|
| 167 |
+
w = Quantity("w")
|
| 168 |
+
|
| 169 |
+
u.set_global_relative_scale_factor(S(10), meter)
|
| 170 |
+
v.set_global_relative_scale_factor(S(5), meter)
|
| 171 |
+
w.set_global_relative_scale_factor(S(2), second)
|
| 172 |
+
|
| 173 |
+
def check_unit_consistency(expr):
|
| 174 |
+
SI._collect_factor_and_dimension(expr)
|
| 175 |
+
|
| 176 |
+
raises(ValueError, lambda: check_unit_consistency(u + w))
|
| 177 |
+
raises(ValueError, lambda: check_unit_consistency(u - w))
|
| 178 |
+
raises(ValueError, lambda: check_unit_consistency(u + 1))
|
| 179 |
+
raises(ValueError, lambda: check_unit_consistency(u - 1))
|
| 180 |
+
raises(ValueError, lambda: check_unit_consistency(1 - exp(u / w)))
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
def test_mul_div():
|
| 184 |
+
u = Quantity("u")
|
| 185 |
+
v = Quantity("v")
|
| 186 |
+
t = Quantity("t")
|
| 187 |
+
ut = Quantity("ut")
|
| 188 |
+
v2 = Quantity("v")
|
| 189 |
+
|
| 190 |
+
u.set_global_relative_scale_factor(S(10), meter)
|
| 191 |
+
v.set_global_relative_scale_factor(S(5), meter)
|
| 192 |
+
t.set_global_relative_scale_factor(S(2), second)
|
| 193 |
+
ut.set_global_relative_scale_factor(S(20), meter*second)
|
| 194 |
+
v2.set_global_relative_scale_factor(S(5), meter/second)
|
| 195 |
+
|
| 196 |
+
assert 1 / u == u**(-1)
|
| 197 |
+
assert u / 1 == u
|
| 198 |
+
|
| 199 |
+
v1 = u / t
|
| 200 |
+
v2 = v
|
| 201 |
+
|
| 202 |
+
# Pow only supports structural equality:
|
| 203 |
+
assert v1 != v2
|
| 204 |
+
assert v1 == v2.convert_to(v1)
|
| 205 |
+
|
| 206 |
+
# TODO: decide whether to allow such expression in the future
|
| 207 |
+
# (requires somehow manipulating the core).
|
| 208 |
+
# assert u / Quantity('l2', dimension=length, scale_factor=2) == 5
|
| 209 |
+
|
| 210 |
+
assert u * 1 == u
|
| 211 |
+
|
| 212 |
+
ut1 = u * t
|
| 213 |
+
ut2 = ut
|
| 214 |
+
|
| 215 |
+
# Mul only supports structural equality:
|
| 216 |
+
assert ut1 != ut2
|
| 217 |
+
assert ut1 == ut2.convert_to(ut1)
|
| 218 |
+
|
| 219 |
+
# Mul only supports structural equality:
|
| 220 |
+
lp1 = Quantity("lp1")
|
| 221 |
+
lp1.set_global_relative_scale_factor(S(2), 1/meter)
|
| 222 |
+
assert u * lp1 != 20
|
| 223 |
+
|
| 224 |
+
assert u**0 == 1
|
| 225 |
+
assert u**1 == u
|
| 226 |
+
|
| 227 |
+
# TODO: Pow only support structural equality:
|
| 228 |
+
u2 = Quantity("u2")
|
| 229 |
+
u3 = Quantity("u3")
|
| 230 |
+
u2.set_global_relative_scale_factor(S(100), meter**2)
|
| 231 |
+
u3.set_global_relative_scale_factor(Rational(1, 10), 1/meter)
|
| 232 |
+
|
| 233 |
+
assert u ** 2 != u2
|
| 234 |
+
assert u ** -1 != u3
|
| 235 |
+
|
| 236 |
+
assert u ** 2 == u2.convert_to(u)
|
| 237 |
+
assert u ** -1 == u3.convert_to(u)
|
| 238 |
+
|
| 239 |
+
|
| 240 |
+
def test_units():
|
| 241 |
+
assert convert_to((5*m/s * day) / km, 1) == 432
|
| 242 |
+
assert convert_to(foot / meter, meter) == Rational(3048, 10000)
|
| 243 |
+
# amu is a pure mass so mass/mass gives a number, not an amount (mol)
|
| 244 |
+
# TODO: need better simplification routine:
|
| 245 |
+
assert str(convert_to(grams/amu, grams).n(2)) == '6.0e+23'
|
| 246 |
+
|
| 247 |
+
# Light from the sun needs about 8.3 minutes to reach earth
|
| 248 |
+
t = (1*au / speed_of_light) / minute
|
| 249 |
+
# TODO: need a better way to simplify expressions containing units:
|
| 250 |
+
t = convert_to(convert_to(t, meter / minute), meter)
|
| 251 |
+
assert t.simplify() == Rational(49865956897, 5995849160)
|
| 252 |
+
|
| 253 |
+
# TODO: fix this, it should give `m` without `Abs`
|
| 254 |
+
assert sqrt(m**2) == m
|
| 255 |
+
assert (sqrt(m))**2 == m
|
| 256 |
+
|
| 257 |
+
t = Symbol('t')
|
| 258 |
+
assert integrate(t*m/s, (t, 1*s, 5*s)) == 12*m*s
|
| 259 |
+
assert (t * m/s).integrate((t, 1*s, 5*s)) == 12*m*s
|
| 260 |
+
|
| 261 |
+
|
| 262 |
+
def test_issue_quart():
|
| 263 |
+
assert convert_to(4 * quart / inch ** 3, meter) == 231
|
| 264 |
+
assert convert_to(4 * quart / inch ** 3, millimeter) == 231
|
| 265 |
+
|
| 266 |
+
def test_electron_rest_mass():
|
| 267 |
+
assert convert_to(electron_rest_mass, kilogram) == 9.1093837015e-31*kilogram
|
| 268 |
+
assert convert_to(electron_rest_mass, grams) == 9.1093837015e-28*grams
|
| 269 |
+
|
| 270 |
+
def test_issue_5565():
|
| 271 |
+
assert (m < s).is_Relational
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
def test_find_unit():
|
| 275 |
+
assert find_unit('coulomb') == ['coulomb', 'coulombs', 'coulomb_constant']
|
| 276 |
+
assert find_unit(coulomb) == ['C', 'coulomb', 'coulombs', 'planck_charge', 'elementary_charge']
|
| 277 |
+
assert find_unit(charge) == ['C', 'coulomb', 'coulombs', 'planck_charge', 'elementary_charge']
|
| 278 |
+
assert find_unit(inch) == [
|
| 279 |
+
'm', 'au', 'cm', 'dm', 'ft', 'km', 'ly', 'mi', 'mm', 'nm', 'pm', 'um', 'yd',
|
| 280 |
+
'nmi', 'feet', 'foot', 'inch', 'mile', 'yard', 'meter', 'miles', 'yards',
|
| 281 |
+
'inches', 'meters', 'micron', 'microns', 'angstrom', 'angstroms', 'decimeter',
|
| 282 |
+
'kilometer', 'lightyear', 'nanometer', 'picometer', 'centimeter', 'decimeters',
|
| 283 |
+
'kilometers', 'lightyears', 'micrometer', 'millimeter', 'nanometers', 'picometers',
|
| 284 |
+
'centimeters', 'micrometers', 'millimeters', 'nautical_mile', 'planck_length',
|
| 285 |
+
'nautical_miles', 'astronomical_unit', 'astronomical_units']
|
| 286 |
+
assert find_unit(inch**-1) == ['D', 'dioptre', 'optical_power']
|
| 287 |
+
assert find_unit(length**-1) == ['D', 'dioptre', 'optical_power']
|
| 288 |
+
assert find_unit(inch ** 2) == ['ha', 'hectare', 'planck_area']
|
| 289 |
+
assert find_unit(inch ** 3) == [
|
| 290 |
+
'L', 'l', 'cL', 'cl', 'dL', 'dl', 'mL', 'ml', 'liter', 'quart', 'liters', 'quarts',
|
| 291 |
+
'deciliter', 'centiliter', 'deciliters', 'milliliter',
|
| 292 |
+
'centiliters', 'milliliters', 'planck_volume']
|
| 293 |
+
assert find_unit('voltage') == ['V', 'v', 'volt', 'volts', 'planck_voltage']
|
| 294 |
+
assert find_unit(grams) == ['g', 't', 'Da', 'kg', 'me', 'mg', 'ug', 'amu', 'mmu', 'amus',
|
| 295 |
+
'gram', 'mmus', 'grams', 'pound', 'tonne', 'dalton', 'pounds',
|
| 296 |
+
'kilogram', 'kilograms', 'microgram', 'milligram', 'metric_ton',
|
| 297 |
+
'micrograms', 'milligrams', 'planck_mass', 'milli_mass_unit', 'atomic_mass_unit',
|
| 298 |
+
'electron_rest_mass', 'atomic_mass_constant']
|
| 299 |
+
|
| 300 |
+
|
| 301 |
+
def test_Quantity_derivative():
|
| 302 |
+
x = symbols("x")
|
| 303 |
+
assert diff(x*meter, x) == meter
|
| 304 |
+
assert diff(x**3*meter**2, x) == 3*x**2*meter**2
|
| 305 |
+
assert diff(meter, meter) == 1
|
| 306 |
+
assert diff(meter**2, meter) == 2*meter
|
| 307 |
+
|
| 308 |
+
|
| 309 |
+
def test_quantity_postprocessing():
|
| 310 |
+
q1 = Quantity('q1')
|
| 311 |
+
q2 = Quantity('q2')
|
| 312 |
+
|
| 313 |
+
SI.set_quantity_dimension(q1, length*pressure**2*temperature/time)
|
| 314 |
+
SI.set_quantity_dimension(q2, energy*pressure*temperature/(length**2*time))
|
| 315 |
+
|
| 316 |
+
assert q1 + q2
|
| 317 |
+
q = q1 + q2
|
| 318 |
+
Dq = Dimension(SI.get_dimensional_expr(q))
|
| 319 |
+
assert SI.get_dimension_system().get_dimensional_dependencies(Dq) == {
|
| 320 |
+
length: -1,
|
| 321 |
+
mass: 2,
|
| 322 |
+
temperature: 1,
|
| 323 |
+
time: -5,
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
|
| 327 |
+
def test_factor_and_dimension():
|
| 328 |
+
assert (3000, Dimension(1)) == SI._collect_factor_and_dimension(3000)
|
| 329 |
+
assert (1001, length) == SI._collect_factor_and_dimension(meter + km)
|
| 330 |
+
assert (2, length/time) == SI._collect_factor_and_dimension(
|
| 331 |
+
meter/second + 36*km/(10*hour))
|
| 332 |
+
|
| 333 |
+
x, y = symbols('x y')
|
| 334 |
+
assert (x + y/100, length) == SI._collect_factor_and_dimension(
|
| 335 |
+
x*m + y*centimeter)
|
| 336 |
+
|
| 337 |
+
cH = Quantity('cH')
|
| 338 |
+
SI.set_quantity_dimension(cH, amount_of_substance/volume)
|
| 339 |
+
|
| 340 |
+
pH = -log(cH)
|
| 341 |
+
|
| 342 |
+
assert (1, volume/amount_of_substance) == SI._collect_factor_and_dimension(
|
| 343 |
+
exp(pH))
|
| 344 |
+
|
| 345 |
+
v_w1 = Quantity('v_w1')
|
| 346 |
+
v_w2 = Quantity('v_w2')
|
| 347 |
+
|
| 348 |
+
v_w1.set_global_relative_scale_factor(Rational(3, 2), meter/second)
|
| 349 |
+
v_w2.set_global_relative_scale_factor(2, meter/second)
|
| 350 |
+
|
| 351 |
+
expr = Abs(v_w1/2 - v_w2)
|
| 352 |
+
assert (Rational(5, 4), length/time) == \
|
| 353 |
+
SI._collect_factor_and_dimension(expr)
|
| 354 |
+
|
| 355 |
+
expr = Rational(5, 2)*second/meter*v_w1 - 3000
|
| 356 |
+
assert (-(2996 + Rational(1, 4)), Dimension(1)) == \
|
| 357 |
+
SI._collect_factor_and_dimension(expr)
|
| 358 |
+
|
| 359 |
+
expr = v_w1**(v_w2/v_w1)
|
| 360 |
+
assert ((Rational(3, 2))**Rational(4, 3), (length/time)**Rational(4, 3)) == \
|
| 361 |
+
SI._collect_factor_and_dimension(expr)
|
| 362 |
+
|
| 363 |
+
|
| 364 |
+
def test_dimensional_expr_of_derivative():
|
| 365 |
+
l = Quantity('l')
|
| 366 |
+
t = Quantity('t')
|
| 367 |
+
t1 = Quantity('t1')
|
| 368 |
+
l.set_global_relative_scale_factor(36, km)
|
| 369 |
+
t.set_global_relative_scale_factor(1, hour)
|
| 370 |
+
t1.set_global_relative_scale_factor(1, second)
|
| 371 |
+
x = Symbol('x')
|
| 372 |
+
y = Symbol('y')
|
| 373 |
+
f = Function('f')
|
| 374 |
+
dfdx = f(x, y).diff(x, y)
|
| 375 |
+
dl_dt = dfdx.subs({f(x, y): l, x: t, y: t1})
|
| 376 |
+
assert SI.get_dimensional_expr(dl_dt) ==\
|
| 377 |
+
SI.get_dimensional_expr(l / t / t1) ==\
|
| 378 |
+
Symbol("length")/Symbol("time")**2
|
| 379 |
+
assert SI._collect_factor_and_dimension(dl_dt) ==\
|
| 380 |
+
SI._collect_factor_and_dimension(l / t / t1) ==\
|
| 381 |
+
(10, length/time**2)
|
| 382 |
+
|
| 383 |
+
|
| 384 |
+
def test_get_dimensional_expr_with_function():
|
| 385 |
+
v_w1 = Quantity('v_w1')
|
| 386 |
+
v_w2 = Quantity('v_w2')
|
| 387 |
+
v_w1.set_global_relative_scale_factor(1, meter/second)
|
| 388 |
+
v_w2.set_global_relative_scale_factor(1, meter/second)
|
| 389 |
+
|
| 390 |
+
assert SI.get_dimensional_expr(sin(v_w1)) == \
|
| 391 |
+
sin(SI.get_dimensional_expr(v_w1))
|
| 392 |
+
assert SI.get_dimensional_expr(sin(v_w1/v_w2)) == 1
|
| 393 |
+
|
| 394 |
+
|
| 395 |
+
def test_binary_information():
|
| 396 |
+
assert convert_to(kibibyte, byte) == 1024*byte
|
| 397 |
+
assert convert_to(mebibyte, byte) == 1024**2*byte
|
| 398 |
+
assert convert_to(gibibyte, byte) == 1024**3*byte
|
| 399 |
+
assert convert_to(tebibyte, byte) == 1024**4*byte
|
| 400 |
+
assert convert_to(pebibyte, byte) == 1024**5*byte
|
| 401 |
+
assert convert_to(exbibyte, byte) == 1024**6*byte
|
| 402 |
+
|
| 403 |
+
assert kibibyte.convert_to(bit) == 8*1024*bit
|
| 404 |
+
assert byte.convert_to(bit) == 8*bit
|
| 405 |
+
|
| 406 |
+
a = 10*kibibyte*hour
|
| 407 |
+
|
| 408 |
+
assert convert_to(a, byte) == 10240*byte*hour
|
| 409 |
+
assert convert_to(a, minute) == 600*kibibyte*minute
|
| 410 |
+
assert convert_to(a, [byte, minute]) == 614400*byte*minute
|
| 411 |
+
|
| 412 |
+
|
| 413 |
+
def test_conversion_with_2_nonstandard_dimensions():
|
| 414 |
+
good_grade = Quantity("good_grade")
|
| 415 |
+
kilo_good_grade = Quantity("kilo_good_grade")
|
| 416 |
+
centi_good_grade = Quantity("centi_good_grade")
|
| 417 |
+
|
| 418 |
+
kilo_good_grade.set_global_relative_scale_factor(1000, good_grade)
|
| 419 |
+
centi_good_grade.set_global_relative_scale_factor(S.One/10**5, kilo_good_grade)
|
| 420 |
+
|
| 421 |
+
charity_points = Quantity("charity_points")
|
| 422 |
+
milli_charity_points = Quantity("milli_charity_points")
|
| 423 |
+
missions = Quantity("missions")
|
| 424 |
+
|
| 425 |
+
milli_charity_points.set_global_relative_scale_factor(S.One/1000, charity_points)
|
| 426 |
+
missions.set_global_relative_scale_factor(251, charity_points)
|
| 427 |
+
|
| 428 |
+
assert convert_to(
|
| 429 |
+
kilo_good_grade*milli_charity_points*millimeter,
|
| 430 |
+
[centi_good_grade, missions, centimeter]
|
| 431 |
+
) == S.One * 10**5 / (251*1000) / 10 * centi_good_grade*missions*centimeter
|
| 432 |
+
|
| 433 |
+
|
| 434 |
+
def test_eval_subs():
|
| 435 |
+
energy, mass, force = symbols('energy mass force')
|
| 436 |
+
expr1 = energy/mass
|
| 437 |
+
units = {energy: kilogram*meter**2/second**2, mass: kilogram}
|
| 438 |
+
assert expr1.subs(units) == meter**2/second**2
|
| 439 |
+
expr2 = force/mass
|
| 440 |
+
units = {force:gravitational_constant*kilogram**2/meter**2, mass:kilogram}
|
| 441 |
+
assert expr2.subs(units) == gravitational_constant*kilogram/meter**2
|
| 442 |
+
|
| 443 |
+
|
| 444 |
+
def test_issue_14932():
|
| 445 |
+
assert (log(inch) - log(2)).simplify() == log(inch/2)
|
| 446 |
+
assert (log(inch) - log(foot)).simplify() == -log(12)
|
| 447 |
+
p = symbols('p', positive=True)
|
| 448 |
+
assert (log(inch) - log(p)).simplify() == log(inch/p)
|
| 449 |
+
|
| 450 |
+
|
| 451 |
+
def test_issue_14547():
|
| 452 |
+
# the root issue is that an argument with dimensions should
|
| 453 |
+
# not raise an error when the `arg - 1` calculation is
|
| 454 |
+
# performed in the assumptions system
|
| 455 |
+
from sympy.physics.units import foot, inch
|
| 456 |
+
from sympy.core.relational import Eq
|
| 457 |
+
assert log(foot).is_zero is None
|
| 458 |
+
assert log(foot).is_positive is None
|
| 459 |
+
assert log(foot).is_nonnegative is None
|
| 460 |
+
assert log(foot).is_negative is None
|
| 461 |
+
assert log(foot).is_algebraic is None
|
| 462 |
+
assert log(foot).is_rational is None
|
| 463 |
+
# doesn't raise error
|
| 464 |
+
assert Eq(log(foot), log(inch)) is not None # might be False or unevaluated
|
| 465 |
+
|
| 466 |
+
x = Symbol('x')
|
| 467 |
+
e = foot + x
|
| 468 |
+
assert e.is_Add and set(e.args) == {foot, x}
|
| 469 |
+
e = foot + 1
|
| 470 |
+
assert e.is_Add and set(e.args) == {foot, 1}
|
| 471 |
+
|
| 472 |
+
|
| 473 |
+
def test_issue_22164():
|
| 474 |
+
warnings.simplefilter("error")
|
| 475 |
+
dm = Quantity("dm")
|
| 476 |
+
SI.set_quantity_dimension(dm, length)
|
| 477 |
+
SI.set_quantity_scale_factor(dm, 1)
|
| 478 |
+
|
| 479 |
+
bad_exp = Quantity("bad_exp")
|
| 480 |
+
SI.set_quantity_dimension(bad_exp, length)
|
| 481 |
+
SI.set_quantity_scale_factor(bad_exp, 1)
|
| 482 |
+
|
| 483 |
+
expr = dm ** bad_exp
|
| 484 |
+
|
| 485 |
+
# deprecation warning is not expected here
|
| 486 |
+
SI._collect_factor_and_dimension(expr)
|
| 487 |
+
|
| 488 |
+
|
| 489 |
+
def test_issue_22819():
|
| 490 |
+
from sympy.physics.units import tonne, gram, Da
|
| 491 |
+
from sympy.physics.units.systems.si import dimsys_SI
|
| 492 |
+
assert tonne.convert_to(gram) == 1000000*gram
|
| 493 |
+
assert dimsys_SI.get_dimensional_dependencies(area) == {length: 2}
|
| 494 |
+
assert Da.scale_factor == 1.66053906660000e-24
|
| 495 |
+
|
| 496 |
+
|
| 497 |
+
def test_issue_20288():
|
| 498 |
+
from sympy.core.numbers import E
|
| 499 |
+
from sympy.physics.units import energy
|
| 500 |
+
u = Quantity('u')
|
| 501 |
+
v = Quantity('v')
|
| 502 |
+
SI.set_quantity_dimension(u, energy)
|
| 503 |
+
SI.set_quantity_dimension(v, energy)
|
| 504 |
+
u.set_global_relative_scale_factor(1, joule)
|
| 505 |
+
v.set_global_relative_scale_factor(1, joule)
|
| 506 |
+
expr = 1 + exp(u**2/v**2)
|
| 507 |
+
assert SI._collect_factor_and_dimension(expr) == (1 + E, Dimension(1))
|
| 508 |
+
|
| 509 |
+
|
| 510 |
+
def test_issue_24062():
|
| 511 |
+
from sympy.core.numbers import E
|
| 512 |
+
from sympy.physics.units import impedance, capacitance, time, ohm, farad, second
|
| 513 |
+
|
| 514 |
+
R = Quantity('R')
|
| 515 |
+
C = Quantity('C')
|
| 516 |
+
T = Quantity('T')
|
| 517 |
+
SI.set_quantity_dimension(R, impedance)
|
| 518 |
+
SI.set_quantity_dimension(C, capacitance)
|
| 519 |
+
SI.set_quantity_dimension(T, time)
|
| 520 |
+
R.set_global_relative_scale_factor(1, ohm)
|
| 521 |
+
C.set_global_relative_scale_factor(1, farad)
|
| 522 |
+
T.set_global_relative_scale_factor(1, second)
|
| 523 |
+
expr = T / (R * C)
|
| 524 |
+
dim = SI._collect_factor_and_dimension(expr)[1]
|
| 525 |
+
assert SI.get_dimension_system().is_dimensionless(dim)
|
| 526 |
+
|
| 527 |
+
exp_expr = 1 + exp(expr)
|
| 528 |
+
assert SI._collect_factor_and_dimension(exp_expr) == (1 + E, Dimension(1))
|
| 529 |
+
|
| 530 |
+
def test_issue_24211():
|
| 531 |
+
from sympy.physics.units import time, velocity, acceleration, second, meter
|
| 532 |
+
V1 = Quantity('V1')
|
| 533 |
+
SI.set_quantity_dimension(V1, velocity)
|
| 534 |
+
SI.set_quantity_scale_factor(V1, 1 * meter / second)
|
| 535 |
+
A1 = Quantity('A1')
|
| 536 |
+
SI.set_quantity_dimension(A1, acceleration)
|
| 537 |
+
SI.set_quantity_scale_factor(A1, 1 * meter / second**2)
|
| 538 |
+
T1 = Quantity('T1')
|
| 539 |
+
SI.set_quantity_dimension(T1, time)
|
| 540 |
+
SI.set_quantity_scale_factor(T1, 1 * second)
|
| 541 |
+
|
| 542 |
+
expr = A1*T1 + V1
|
| 543 |
+
# should not throw ValueError here
|
| 544 |
+
SI._collect_factor_and_dimension(expr)
|
| 545 |
+
|
| 546 |
+
|
| 547 |
+
def test_prefixed_property():
|
| 548 |
+
assert not meter.is_prefixed
|
| 549 |
+
assert not joule.is_prefixed
|
| 550 |
+
assert not day.is_prefixed
|
| 551 |
+
assert not second.is_prefixed
|
| 552 |
+
assert not volt.is_prefixed
|
| 553 |
+
assert not ohm.is_prefixed
|
| 554 |
+
assert centimeter.is_prefixed
|
| 555 |
+
assert kilometer.is_prefixed
|
| 556 |
+
assert kilogram.is_prefixed
|
| 557 |
+
assert pebibyte.is_prefixed
|
| 558 |
+
|
| 559 |
+
def test_physics_constant():
|
| 560 |
+
from sympy.physics.units import definitions
|
| 561 |
+
|
| 562 |
+
for name in dir(definitions):
|
| 563 |
+
quantity = getattr(definitions, name)
|
| 564 |
+
if not isinstance(quantity, Quantity):
|
| 565 |
+
continue
|
| 566 |
+
if name.endswith('_constant'):
|
| 567 |
+
assert isinstance(quantity, PhysicalConstant), f"{quantity} must be PhysicalConstant, but is {type(quantity)}"
|
| 568 |
+
assert quantity.is_physical_constant, f"{name} is not marked as physics constant when it should be"
|
| 569 |
+
|
| 570 |
+
for const in [gravitational_constant, molar_gas_constant, vacuum_permittivity, speed_of_light, elementary_charge]:
|
| 571 |
+
assert isinstance(const, PhysicalConstant), f"{const} must be PhysicalConstant, but is {type(const)}"
|
| 572 |
+
assert const.is_physical_constant, f"{const} is not marked as physics constant when it should be"
|
| 573 |
+
|
| 574 |
+
assert not meter.is_physical_constant
|
| 575 |
+
assert not joule.is_physical_constant
|
.venv/Lib/site-packages/sympy/physics/units/tests/test_unit_system_cgs_gauss.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sympy.concrete.tests.test_sums_products import NS
|
| 2 |
+
|
| 3 |
+
from sympy.core.singleton import S
|
| 4 |
+
from sympy.functions.elementary.miscellaneous import sqrt
|
| 5 |
+
from sympy.physics.units import convert_to, coulomb_constant, elementary_charge, gravitational_constant, planck
|
| 6 |
+
from sympy.physics.units.definitions.unit_definitions import angstrom, statcoulomb, coulomb, second, gram, centimeter, erg, \
|
| 7 |
+
newton, joule, dyne, speed_of_light, meter, farad, henry, statvolt, volt, ohm
|
| 8 |
+
from sympy.physics.units.systems import SI
|
| 9 |
+
from sympy.physics.units.systems.cgs import cgs_gauss
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def test_conversion_to_from_si():
|
| 13 |
+
assert convert_to(statcoulomb, coulomb, cgs_gauss) == coulomb/2997924580
|
| 14 |
+
assert convert_to(coulomb, statcoulomb, cgs_gauss) == 2997924580*statcoulomb
|
| 15 |
+
assert convert_to(statcoulomb, sqrt(gram*centimeter**3)/second, cgs_gauss) == centimeter**(S(3)/2)*sqrt(gram)/second
|
| 16 |
+
assert convert_to(coulomb, sqrt(gram*centimeter**3)/second, cgs_gauss) == 2997924580*centimeter**(S(3)/2)*sqrt(gram)/second
|
| 17 |
+
|
| 18 |
+
# SI units have an additional base unit, no conversion in case of electromagnetism:
|
| 19 |
+
assert convert_to(coulomb, statcoulomb, SI) == coulomb
|
| 20 |
+
assert convert_to(statcoulomb, coulomb, SI) == statcoulomb
|
| 21 |
+
|
| 22 |
+
# SI without electromagnetism:
|
| 23 |
+
assert convert_to(erg, joule, SI) == joule/10**7
|
| 24 |
+
assert convert_to(erg, joule, cgs_gauss) == joule/10**7
|
| 25 |
+
assert convert_to(joule, erg, SI) == 10**7*erg
|
| 26 |
+
assert convert_to(joule, erg, cgs_gauss) == 10**7*erg
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
assert convert_to(dyne, newton, SI) == newton/10**5
|
| 30 |
+
assert convert_to(dyne, newton, cgs_gauss) == newton/10**5
|
| 31 |
+
assert convert_to(newton, dyne, SI) == 10**5*dyne
|
| 32 |
+
assert convert_to(newton, dyne, cgs_gauss) == 10**5*dyne
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def test_cgs_gauss_convert_constants():
|
| 36 |
+
|
| 37 |
+
assert convert_to(speed_of_light, centimeter/second, cgs_gauss) == 29979245800*centimeter/second
|
| 38 |
+
|
| 39 |
+
assert convert_to(coulomb_constant, 1, cgs_gauss) == 1
|
| 40 |
+
assert convert_to(coulomb_constant, newton*meter**2/coulomb**2, cgs_gauss) == 22468879468420441*meter**2*newton/(2500000*coulomb**2)
|
| 41 |
+
assert convert_to(coulomb_constant, newton*meter**2/coulomb**2, SI) == 22468879468420441*meter**2*newton/(2500000*coulomb**2)
|
| 42 |
+
assert convert_to(coulomb_constant, dyne*centimeter**2/statcoulomb**2, cgs_gauss) == centimeter**2*dyne/statcoulomb**2
|
| 43 |
+
assert convert_to(coulomb_constant, 1, SI) == coulomb_constant
|
| 44 |
+
assert NS(convert_to(coulomb_constant, newton*meter**2/coulomb**2, SI)) == '8987551787.36818*meter**2*newton/coulomb**2'
|
| 45 |
+
|
| 46 |
+
assert convert_to(elementary_charge, statcoulomb, cgs_gauss)
|
| 47 |
+
assert convert_to(angstrom, centimeter, cgs_gauss) == 1*centimeter/10**8
|
| 48 |
+
assert convert_to(gravitational_constant, dyne*centimeter**2/gram**2, cgs_gauss)
|
| 49 |
+
assert NS(convert_to(planck, erg*second, cgs_gauss)) == '6.62607015e-27*erg*second'
|
| 50 |
+
|
| 51 |
+
spc = 25000*second/(22468879468420441*centimeter)
|
| 52 |
+
assert convert_to(ohm, second/centimeter, cgs_gauss) == spc
|
| 53 |
+
assert convert_to(henry, second**2/centimeter, cgs_gauss) == spc*second
|
| 54 |
+
assert convert_to(volt, statvolt, cgs_gauss) == 10**6*statvolt/299792458
|
| 55 |
+
assert convert_to(farad, centimeter, cgs_gauss) == 299792458**2*centimeter/10**5
|