qten.phys
Package reference for qten.phys.
phys
Physics-facing labels and operator assembly.
This package sits between qten.symbolics and
qten.linalg. Use it for two things:
- free-fermion bonds that become tensors
- spin-1/2 labels that decide whether a point group must lift to \(SU(2)\)
Spin and point groups
Spin is a typed irrep inside
U1Basis. Putting Spin.up /
Spin.down on a site is the definition of a spinful Hilbert space. Point-group
code later asks contains_spin; you do not
call .with_spin on the group.
Electron spin always lives in \(\mathbb{C}^2\). The spatial model can be 1D, 2D, or 3D. The map from a point operation \(g\) to spin is the principal \(SU(2)\) lift of the stored 3D rotation \(R(g)\in O(3)\), not a padded copy of the small spatial matrix. Improper isometries first drop inversion, \(R_+(g)=(\det R(g))\,R(g)\in SO(3)\), because spatial inversion does not act on spin-1/2. Then [ u(g)=\cos(\theta/2)\,I-i\sin(\theta/2)\,\hat n\cdot\boldsymbol\sigma, ] where \(R_+(g)\) has axis \(\hat n\) and angle \(\theta\in[0,\pi]\). The cover is two-to-one: \(u\) and \(-u\) determine the same \(R_+\). QTen takes the principal branch \(\operatorname{Re}\operatorname{tr}u\ge 0\).
from qten.phys import Spin, su2_of_point_group
from qten.pointgroups import pointgroup
from qten.symbolics import U1Basis
psi = U1Basis.new(site, Spin.up) # this basis state is spinful
g = pointgroup("C4v", plane="xy") # geometry is fixed here
u = su2_of_point_group(g.elements()[1]) # 2x2 SU(2) factor
Inspect a lift when you need the matrix. Projection and representation
assembly live in qten.pointgroups:
hilbert_repr builds
\(D(g)=D_{\mathrm{orb}}(g)\otimes u(g)\) on a spinful space.
Rare exception, still at construction: pointgroup("C4v", spin="trivial")
sets \(u(g)=I\) (flavor spin / no SOC). Do not redefine an already built group.
Spin APIs
Spin— \(m_s=\pm 1/2\) labelsSpin.up/Spin.downas_spin—Spinor leftover"up"/"down"stringscontains_spin— Hilbert space already has a spin-1/2 labelsu2_of_point_group— principal lift ofrotation3su2_numeric— the same factor as complex floatsexpand_spin— \(u(g)|s\rangle\) in the \(\{\uparrow,\downarrow\}\) basisproper_rotation_matrix— \(O(3)\to SO(3)\) before the liftsu2_from_so3— lift a proper \(3\times 3\) matrixSU2_SECTION_CONVENTION—qten-su2-principal-v1
Free-fermion assembly
Bondstores a weighted directed transition between twoU1Basisstates.FFObservableaccumulates bond terms and converts them into a rank-2Tensor.
Exported API
Bond
dataclass
Bond(coef: Number, base: BaseType)
Bases: Multiple[Tuple[U1Basis, U1Basis]]
Weighted directed transition between two U1Basis states.
Bond specializes Multiple for the common physics case where the base
object is an ordered pair (src, dst) of basis states. The scalar
coefficient is kept separate from the endpoint states so symbolic
manipulations can preserve the structural meaning of the bond until a later
tensor-construction step.
In an FFObservable, the ordered pair is
interpreted as a matrix element from src to dst. The observable is
responsible for adding the Hermitian conjugate contribution when converting
the collected bonds to a tensor.
In index notation this directed entry is \(O_{\mathrm{src},\mathrm{dst}}\).
Attributes:
| Name | Type | Description |
|---|---|---|
coef |
Number
|
Symbolic coefficient multiplying the bond contribution. |
base |
Tuple[U1Basis, U1Basis]
|
Ordered pair |
See Also
qten.phys.FFObservable
Observable builder that consumes Bond instances.
coef
instance-attribute
coef: Number
Numeric SymPy coefficient applied to base, kept separate so callers can
accumulate scalar factors without eagerly rebuilding symbolic expressions.
base
instance-attribute
base: BaseType
The symbolic or scalar object being multiplied by coef, preserved in
structured form for later operator application or simplification.
FFObservable
FFObservable()
Free-fermionic observable assembled from symbolic Bond terms.
The observable stores a list of weighted basis-state transitions and can
convert them into a Hermitian matrix representation on the minimal
HilbertSpace spanned by the bond endpoints after ray reduction.
Each accumulated Bond contributes one directed matrix
element. During tensor conversion, endpoint basis states are reduced to
their rays, repeated rays are coalesced into a single Hilbert-space basis,
and off-diagonal entries are mirrored by complex conjugation.
In matrix notation, inserting a bond from \(|i\rangle\) to \(|j\rangle\) with coefficient \(c\) writes \(O_{ij} = c\) and, for \(i \ne j\), the Hermitian completion \(O_{ji} = c^{*}\).
Notes
Bonds are retained internally in insertion order so the generated Hilbert
space is deterministic for a fixed sequence of add_bond calls.
Initialize an empty observable with no bond contributions.
New terms can be added with add_bond().
Source code in src/qten/phys/_ff_observables.py
67 68 69 70 71 72 73 | |
add_bond
add_bond(bond: Bond)
Append a bond contribution to the observable.
Supported forms
add_bond(bond)add_bond(coef, src, dst)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bond
|
Bond
|
Already-constructed bond term for the single-argument form. |
required |
Returns:
| Type | Description |
|---|---|
None
|
The observable is updated in place. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
Source code in src/qten/phys/_ff_observables.py
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | |
to_tensor
to_tensor(*, device: Optional[Device] = None) -> Tensor
Convert the accumulated bonds into a Hermitian matrix Tensor.
Each bond contributes the matrix element induced by its coefficient and
endpoint basis-state amplitudes. Basis states are first reduced to their
ray representatives, and the output HilbertSpace is built from the
resulting insertion-ordered unique rays. Off-diagonal entries are
mirrored by complex conjugation so the returned tensor is Hermitian.
The resulting data satisfy \(O_{ij} = O_{ji}^{*}\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device
|
Device | None
|
Logical device on which to allocate the output tensor data. If omitted, PyTorch uses its default device. |
None
|
Returns:
| Type | Description |
|---|---|
Tensor
|
Rank-2 tensor whose dimensions are the minimal Hilbert space spanned by the bond endpoint rays. |
Source code in src/qten/phys/_ff_observables.py
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | |
SU2_SECTION_CONVENTION
module-attribute
SU2_SECTION_CONVENTION = 'qten-su2-principal-v1'
Spin
dataclass
Spin(ms: Rational)
Bases: Operable
Spin-1/2 projection label \(m_s = \pm 1/2\).
Use as a typed irrep inside U1Basis:
psi = U1Basis.new(site, Spin.up)
Attributes:
| Name | Type | Description |
|---|---|---|
ms |
Rational
|
Magnetic quantum number. Must be |
ms
instance-attribute
ms: Rational
up
class-attribute
up: Spin
down
class-attribute
down: Spin
is_up
property
is_up: bool
is_down
property
is_down: bool
__post_init__
__post_init__() -> None
Source code in src/qten/phys/spin.py
74 75 76 77 78 | |
__str__
__str__() -> str
Source code in src/qten/phys/spin.py
88 89 | |
__repr__
__repr__() -> str
Source code in src/qten/phys/spin.py
91 92 | |
as_spin
as_spin(rep: object) -> Spin | None
Return a Spin label, or None if rep is not a spin-1/2 irrep.
Accepts Spin and the leftover strings "up" /
"down" so old bases still count as spinful instead of silently
selecting ordinary projectors. The string "spin-up" is not a spin
label.
Source code in src/qten/phys/spin.py
535 536 537 538 539 540 541 542 543 544 545 546 547 | |
contains_spin
contains_spin(space: 'HilbertSpace') -> bool
Return True if any basis state carries a spin-1/2 irrep.
Source code in src/qten/phys/spin.py
550 551 552 | |
expand_spin
expand_spin(
g: "PointGroupElement | PointGroupOpr", spin: Spin
) -> Tuple[Tuple[sy.Expr, Spin], ...]
Expand \(u(g)|s\rangle\) in the \(\{|\uparrow\rangle,|\downarrow\rangle\}\) basis.
Columns of \(u(g)\) are ordered \((\uparrow,\downarrow)\), so [ u(g)|s\rangle=\sum_{s'}u(g)_{s's}\,|s'\rangle ] with only the nonzero amplitudes returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
g
|
PointGroupElement | PointGroupOpr
|
Point operation whose \(SU(2)\) factor is applied. |
required |
spin
|
Spin
|
Input spin-1/2 label. |
required |
Returns:
| Type | Description |
|---|---|
tuple[tuple[Expr, Spin], ...]
|
Nonzero |
Source code in src/qten/phys/spin.py
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 | |
proper_rotation_matrix
proper_rotation_matrix(
R: Matrix,
) -> sy.ImmutableDenseMatrix
Return the proper \(SO(3)\) factor used for the spinor lift.
Returns \(R_+=(\det R)\,R\). For \(\det R=+1\) this is \(R\). For an improper isometry (\(\det R=-1\)) it is \(-R\) (now det \(+1\)): \(R=i\circ R_+\) with spatial inversion \(i=-I\), and inversion does not act on spin-1/2, so the lift uses \(R_+\) only.
Source code in src/qten/phys/spin.py
183 184 185 186 187 188 189 190 191 192 193 194 195 | |
su2_from_so3
su2_from_so3(R: Matrix) -> sy.ImmutableDenseMatrix
Lift an \(SO(3)\) matrix to one \(SU(2)\) factor \(u(R)\).
Writes \(R\) in axis-angle form, \(\cos\theta=(\operatorname{tr}R-1)/2\), \(\theta\in[0,\pi]\), and returns [ u=\cos(\theta/2)\,I-i\sin(\theta/2)\,\hat n\cdot\boldsymbol\sigma. ] Both \(\pm u\) cover the same \(R\). The principal branch is the one continuous from the identity, equivalently \(\operatorname{Re}\operatorname{tr}u\ge 0\). At \(\theta=\pi\) the two signs are equally valid; an axis convention picks one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
R
|
Matrix
|
Proper \(3\times 3\) rotation matrix (\(\det = +1\)). |
required |
Returns:
| Type | Description |
|---|---|
ImmutableDenseMatrix
|
\(2\times 2\) unitary matrix with determinant \(1\). |
Source code in src/qten/phys/spin.py
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | |
su2_numeric
su2_numeric(
g: "PointGroupElement | PointGroupOpr",
) -> list[list[complex]]
Complex \(2\times 2\) \(SU(2)\) factor for fast Hilbert-space assembly.
Source code in src/qten/phys/spin.py
491 492 493 494 495 496 | |
su2_of_point_group
su2_of_point_group(
g: "PointGroupElement | PointGroupOpr",
) -> sy.ImmutableDenseMatrix
Return the \(SU(2)\) factor of a point operation in the Cartesian spin frame.
Reads the stored \(R(g)\) (rotation3, or the 3D irrep when that is
already Cartesian) and returns
\(u(g)=u\bigl(R_+(g)\bigr)\) with
\(R_+=(\det R)\,R\). A group built with spin="trivial" returns \(I\).
A 1D or 2D element with no rotation3 raises: the lift is not a padded
copy of the spatial matrix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
g
|
PointGroupElement | PointGroupOpr
|
Point operation whose stored 3D rotation is lifted. |
required |
Returns:
| Type | Description |
|---|---|
ImmutableDenseMatrix
|
\(2\times 2\) \(SU(2)\) matrix, or the identity when the spin policy is trivial. |
Source code in src/qten/phys/spin.py
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | |