pub struct UnitQuaternion { /* private fields */ }Expand description
Unit quaternion representing an element of SU(2)
Quaternion q = w + xi + yj + zk where w² + x² + y² + z² = 1
§Geometric Interpretation
Every unit quaternion represents a rotation in 3D space:
- Rotation by angle θ around axis n̂ = (nx, ny, nz): q = cos(θ/2) + sin(θ/2)(nx·i + ny·j + nz·k)
§⚠️ Important: Double Cover Property
q and -q represent the SAME rotation but DIFFERENT quantum states:
- Both rotate 3D vectors identically (v → q·v·q⁻¹ = (-q)·v·(-q)⁻¹)
- But q ≠ -q as SU(2) group elements
- Consequence: Fermions change sign under 2π rotation (ψ → -ψ)
This is NOT a numerical issue or degeneracy - it’s fundamental topology!
§Relation to SU(2) Matrix
q = w + xi + yj + zk corresponds to SU(2) matrix:
U = [[ w + ix, -y + iz],
[ y + iz, w - ix]]Note: -q gives matrix -U, which acts identically on vectors but represents a different element of SU(2) (relevant for spinors/fermions).
Implementations§
Source§impl UnitQuaternion
impl UnitQuaternion
Sourcepub fn new(w: f64, x: f64, y: f64, z: f64) -> Self
pub fn new(w: f64, x: f64, y: f64, z: f64) -> Self
Create from components (automatically normalizes to unit quaternion)
Returns identity if input norm < NORM_EPSILON (degenerate case).
Sourcepub fn from_axis_angle(axis: [f64; 3], angle: f64) -> Self
pub fn from_axis_angle(axis: [f64; 3], angle: f64) -> Self
Sourcepub fn to_axis_angle(&self) -> ([f64; 3], f64)
pub fn to_axis_angle(&self) -> ([f64; 3], f64)
Extract axis and angle from quaternion
§Returns
(axis, angle) where axis is normalized and angle ∈ [0, 2π]
Sourcepub fn rotation_x(theta: f64) -> Self
pub fn rotation_x(theta: f64) -> Self
Rotation around X-axis by angle θ
Sourcepub fn rotation_y(theta: f64) -> Self
pub fn rotation_y(theta: f64) -> Self
Rotation around Y-axis by angle θ
Sourcepub fn rotation_z(theta: f64) -> Self
pub fn rotation_z(theta: f64) -> Self
Rotation around Z-axis by angle θ
Sourcepub fn conjugate(&self) -> Self
pub fn conjugate(&self) -> Self
Quaternion conjugate: q* = w - xi - yj - zk
For unit quaternions: q* = q⁻¹ (inverse)
Sourcepub fn norm_squared(&self) -> f64
pub fn norm_squared(&self) -> f64
Norm squared: |q|² = w² + x² + y² + z²
Should always be 1 for unit quaternions
Sourcepub fn norm(&self) -> f64
pub fn norm(&self) -> f64
Norm: |q| = sqrt(w² + x² + y² + z²)
Should always be 1 for unit quaternions
Sourcepub fn distance_to_identity(&self) -> f64
pub fn distance_to_identity(&self) -> f64
Distance to identity (geodesic distance on S³)
d(q, 1) = 2·arccos(|w|)
This is the rotation angle in [0, π]
Sourcepub fn distance_to(&self, other: &Self) -> f64
pub fn distance_to(&self, other: &Self) -> f64
Geodesic distance to another quaternion
d(q₁, q₂) = arccos(|q₁·q₂|) where · is quaternion dot product
Sourcepub fn slerp(&self, other: &Self, t: f64) -> Self
pub fn slerp(&self, other: &Self, t: f64) -> Self
Spherical linear interpolation (SLERP)
Interpolate between self and other with parameter t ∈ [0,1]
Returns shortest path on S³
Sourcepub fn exp(v: [f64; 3]) -> Self
pub fn exp(v: [f64; 3]) -> Self
Exponential map from Lie algebra 𝔰𝔲(2) to group SU(2)
Given a vector v = (v₁, v₂, v₃) ∈ ℝ³ (Lie algebra element), compute exp(v) as a unit quaternion.
Formula: exp(v) = cos(|v|/2) + sin(|v|/2)·(v/|v|)
Sourcepub fn log(&self) -> [f64; 3]
pub fn log(&self) -> [f64; 3]
Logarithm map from group SU(2) to Lie algebra 𝔰𝔲(2)
Returns vector v ∈ ℝ³ such that exp(v) = q
Formula: log(q) = (θ/sin(θ/2))·(x, y, z) where θ = 2·arccos(w)
Sourcepub fn to_matrix(&self) -> [[Complex64; 2]; 2]
pub fn to_matrix(&self) -> [[Complex64; 2]; 2]
Convert to SU(2) matrix representation (for compatibility)
Returns 2×2 complex matrix: U = [[ w + ix, -y + iz], [ y + iz, w - ix]]
Sourcepub fn from_matrix(matrix: [[Complex64; 2]; 2]) -> Self
pub fn from_matrix(matrix: [[Complex64; 2]; 2]) -> Self
Create from SU(2) matrix
Expects matrix [[α, -β*], [β, α*]] with |α|² + |β|² = 1
Sourcepub fn rotate_vector(&self, v: [f64; 3]) -> [f64; 3]
pub fn rotate_vector(&self, v: [f64; 3]) -> [f64; 3]
Act on a 3D vector by conjugation: v’ = qvq*
This is the rotation action of SU(2) on ℝ³ Identifies v = (x,y,z) with quaternion xi + yj + zk
Uses the direct formula (Rodrigues) for efficiency: v’ = v + 2w(n×v) + 2(n×(n×v)) where n = (x,y,z)
Sourcepub fn verify_unit(&self, tolerance: f64) -> bool
pub fn verify_unit(&self, tolerance: f64) -> bool
Verify this is approximately a unit quaternion
Sourcepub fn to_rotation_matrix(&self) -> [[f64; 3]; 3]
pub fn to_rotation_matrix(&self) -> [[f64; 3]; 3]
Construct the 3×3 rotation matrix corresponding to this unit quaternion.
Returns the SO(3) matrix R such that R·v = rotate_vector(v) for all v ∈ ℝ³.
§Lean Correspondence
This is the Rust counterpart of toRotationMatrix in
OrthogonalGroups.lean. The Lean proofs establish:
toRotationMatrix_orthogonal_axiom: R(q)ᵀ·R(q) = ItoRotationMatrix_det_axiom: det(R(q)) = 1toRotationMatrix_mul_axiom: R(q₁·q₂) = R(q₁)·R(q₂)toRotationMatrix_neg: R(-q) = R(q)
Trait Implementations§
Source§impl Clone for UnitQuaternion
impl Clone for UnitQuaternion
Source§fn clone(&self) -> UnitQuaternion
fn clone(&self) -> UnitQuaternion
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for UnitQuaternion
impl Debug for UnitQuaternion
Source§impl Mul for UnitQuaternion
impl Mul for UnitQuaternion
Source§impl MulAssign for UnitQuaternion
impl MulAssign for UnitQuaternion
Source§fn mul_assign(&mut self, rhs: Self)
fn mul_assign(&mut self, rhs: Self)
*= operation. Read moreSource§impl PartialEq for UnitQuaternion
impl PartialEq for UnitQuaternion
impl Copy for UnitQuaternion
impl StructuralPartialEq for UnitQuaternion
Auto Trait Implementations§
impl Freeze for UnitQuaternion
impl RefUnwindSafe for UnitQuaternion
impl Send for UnitQuaternion
impl Sync for UnitQuaternion
impl Unpin for UnitQuaternion
impl UnsafeUnpin for UnitQuaternion
impl UnwindSafe for UnitQuaternion
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.