pub struct UnitBiquaternion(/* private fields */);Expand description
Represent SO(3,1) with a normalized biquaternion.
Unit-norm Biquaternions furnish a representation of SO(3,1), analogous to
quaternions and SO(3). If $\vec{x} = (x_1, x_2, x_3, x_4)$ is a vector
in Minkowski space, then $\vec{x}$ can be mapped to a biquaternion
\vec{x} \mapsto X = [x_1, x_2, x_3,h x_4](where h is the imaginary number) whose squared norm is
|X|^2 = x_1^2 + x_2^2 + x_3^2 - x_4^2It can be shown that, for
a unit biquaternion $q$, the transformation
q^* X \overline{q} = X'preserves the norm, i.e.,
|X|^2 = |X'|^2We therefore have that this action by unit biquaternions
produces a representation of SO(3,1). The biquaternion algebra can be used
directly to transform Minkowski 4-vectors, or unit biquaternions can be
represented as matrices using HyperbolicRotationMatrix<4>.
Like quaternions, the unit biquaternion
q = \cos(\theta/2) + \bf{i}\sin(\theta/2)generates a rotation about the $\mathbf{i}$ axis by angle $\theta$:
use approxim::assert_relative_eq;
use hoomd_manifold::{
Biquaternion, HyperbolicRotate, HyperbolicRotationMatrix, Minkowski,
UnitBiquaternion,
};
use num::complex::Complex;
use std::f64::consts::PI;
let q = Biquaternion::from([
Complex::new((PI / 4.0).sin(), 0.0),
Complex::new(0.0, 0.0),
Complex::new(0.0, 0.0),
Complex::new((PI / 4.0).cos(), 0.0),
]);
let v = q.to_unit()?;
let x = Minkowski::from([1.0, 1.0, 1.0, 1.0]);
let rotation = HyperbolicRotationMatrix::from(v);
let rotated = rotation.hyperbolic_rotate(&x);
assert_relative_eq!(rotated, [1.0, -1.0, 1.0, 1.0].into(), epsilon = 1e-12);However, biquaternions also generate boosts via
q = \cosh(v) + \mathbf{i}h\sinh(v)which represents a boost of rapidity $v$ in the $\mathbf{i}$ direction:
use approxim::assert_relative_eq;
use hoomd_manifold::{
Biquaternion, HyperbolicRotate, HyperbolicRotationMatrix, Minkowski,
UnitBiquaternion,
};
use num::complex::Complex;
use std::f64::consts::PI;
let q = Biquaternion::from([
Complex::new(0.0, (0.2_f64).sinh()),
Complex::new(0.0, 0.0),
Complex::new(0.0, 0.0),
Complex::new((0.2_f64).cosh(), 0.0),
]);
let v = q.to_unit()?;
let x = Minkowski::from([0.0, 0.0, 0.0, 1.0]);
let boost = HyperbolicRotationMatrix::from(v);
let boosted = boost.hyperbolic_rotate(&x);
assert_relative_eq!(
boosted,
[(0.4_f64).sinh(), 0.0, 0.0, (0.4_f64).cosh()].into(),
epsilon = 1e-12
);Implementations§
Source§impl UnitBiquaternion
impl UnitBiquaternion
Sourcepub fn normalized(self) -> Self
pub fn normalized(self) -> Self
Normalize a biquaternion.
Sourcepub fn norm_squared(self) -> Complex<f64>
pub fn norm_squared(self) -> Complex<f64>
Compute the square of the norm of a biquaternion.
Trait Implementations§
Source§impl Clone for UnitBiquaternion
impl Clone for UnitBiquaternion
Source§fn clone(&self) -> UnitBiquaternion
fn clone(&self) -> UnitBiquaternion
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for UnitBiquaternion
impl Debug for UnitBiquaternion
Source§impl Distribution<UnitBiquaternion> for StandardUniform
impl Distribution<UnitBiquaternion> for StandardUniform
Source§fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> UnitBiquaternion
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> UnitBiquaternion
Sample a random UnitBiquaternion
§Example
use approxim::assert_relative_eq;
use hoomd_manifold::{Biquaternion, UnitBiquaternion};
use num::complex::Complex;
use rand::{RngExt, SeedableRng, rngs::StdRng};
let mut rng = StdRng::seed_from_u64(1);
let v: UnitBiquaternion = rng.random();
assert_relative_eq!(v.norm_squared().re, 1.0, epsilon = 1e-12);§fn sample_iter<R>(self, rng: R) -> Iter<Self, R, T>where
R: Rng,
Self: Sized,
fn sample_iter<R>(self, rng: R) -> Iter<Self, R, T>where
R: Rng,
Self: Sized,
T, using rng as
the source of randomness. Read moreSource§impl From<UnitBiquaternion> for HyperbolicRotationMatrix<4>
impl From<UnitBiquaternion> for HyperbolicRotationMatrix<4>
Source§fn from(q: UnitBiquaternion) -> HyperbolicRotationMatrix<4>
fn from(q: UnitBiquaternion) -> HyperbolicRotationMatrix<4>
Source§impl HyperbolicRotate<Minkowski<4>> for UnitBiquaternion
impl HyperbolicRotate<Minkowski<4>> for UnitBiquaternion
Source§fn hyperbolic_rotate(&self, vector: &Minkowski<4>) -> Minkowski<4>
fn hyperbolic_rotate(&self, vector: &Minkowski<4>) -> Minkowski<4>
Transform a Minkowski<4> by a UnitBiquaternion.
\overline{\mathbf{q}} \vec{a} \mathbf{q}^*§Examples
Rotation about z axis:
use approxim::assert_relative_eq;
use hoomd_manifold::{
Biquaternion, HyperbolicRotate, Minkowski, UnitBiquaternion,
};
use num::complex::Complex;
use std::f64::consts::PI;
let x = Minkowski::from([1.0, 0.0, 0.0, 1.0]);
let q = Biquaternion::from([
Complex::new(0.0, 0.0),
Complex::new(0.0, 0.0),
Complex::new((PI / 4.0).sin(), 0.0),
Complex::new((PI / 4.0).cos(), 0.0),
]);
let v = q.to_unit_unchecked();
let rotated = v.hyperbolic_rotate(&x);
assert_relative_eq!(rotated, [0.0, 1.0, 0.0, 1.0].into(), epsilon = 1e-12);Boost in x direction:
use approxim::assert_relative_eq;
use hoomd_manifold::{
Biquaternion, HyperbolicRotate, Minkowski, UnitBiquaternion,
};
use num::complex::Complex;
use std::f64::consts::PI;
let x = Minkowski::from([0.0, 0.0, 0.0, 1.0]);
let q = Biquaternion::from([
Complex::new(0.0, PI / 4.0).sin(),
Complex::new(0.0, 0.0),
Complex::new(0.0, 0.0),
Complex::new(0.0, PI / 4.0).cos(),
]);
let v = q.to_unit_unchecked();
let boosted = v.hyperbolic_rotate(&x);
assert_relative_eq!(
boosted,
[(PI / 2.0).sinh(), 0.0, 0.0, (PI / 2.0).cosh()].into(),
epsilon = 1e-12
);