Skip to main content

Quaternion algebra library with vector/matrix/tensor collections, linear algebra (SVD), interpolation (SLERP/squad), signal processing (QFFT/QConv), distance metrics, kinematics, statistics, and optimized einsum kernels.

Project description

quat

Quaternion Algebra for NumPy

Python NumPy License


quat brings first-class quaternion support to NumPy. Scalar quaternions, vector/matrix/tensor collections, SVD, SLERP interpolation, QFFT signal processing, serialization — with a three-tier-einsum Hamilton kernel that picks the fastest strategy at every data size. All in pure Python, zero C extensions.

pip install quat-numpy

Why quat?

Most quaternion libraries stop at rotating 3D vectors. quat gives you the full toolbox:

What How
Scalar quaternions Full algebra — +, *, /, exp, log, pow, Hamilton product
Collections QuatVector (1D), QuatMatrix (2D), QuatTensor (3D) — broadcast-aware
Linear algebra SVD, rank, condition number, pseudo-inverse, determinant — on quaternion matrices
Interpolation SLERP (shortest arc on S³), squad cubic spline, batch SLERP, angular velocity estimation
Distance & statistics 4 geodesic/chordal distance metrics, quaternion vector mean, Karcher mean, PCA
Signal processing 1D/2D QFFT, quaternion convolution, FIR filter design
Random generation Reproducible generators for all four types
Serialization JSON + compact binary roundtrip for all types; SciPy Rotation interop
Performance Three-tier Hamilton kernel (component-wise → einsum), ~20x faster SVD fast-path

Quickstart

import numpy as np
from quat import Quaternion, QuatVector, QuatMatrix
from quat import slerp, squad, random_unit_quat

# ---- Construction -------------------------------------------------
q = Quaternion(1, 2, 3, 4)                         # a + bi + cj + dk
r = Quaternion(5.0)                                 # pure real
u = Quaternion.from_axis_angle((0,0,1), np.pi/2)    # 90 deg around z
e = Quaternion.from_euler((0.1, 0.2, 0.3))          # intrinsic ZYX

# ---- Hamilton product ---------------------------------------------
i, j, k = Quaternion(0,1,0,0), Quaternion(0,0,1,0), Quaternion(0,0,0,1)
print(i * j)           # Quaternion(0, 0, 0, 1)   — i*j = k
print(i * j * k)       # Quaternion(-1, 0, 0, 0)  — i² = j² = k² = ijk = -1

# ---- Algebra ------------------------------------------------------
q.conjugate()          # Quaternion(1, -2, -3, -4)
q.norm()               # Euclidean norm
q.inverse() * q        # ≈ identity
q.exp()                # quaternion exponential
q.log()                # quaternion logarithm

# ---- 3D rotation --------------------------------------------------
u = Quaternion.from_axis_angle((0, 0, 1), np.pi / 2)
u.rotate_vector((1, 0, 0))           # ≈ (0, 1, 0) — 90° rotation
axis, angle = u.to_axis_angle()      # roundtrip (axis, angle)

# ---- Smooth interpolation -----------------------------------------
a = Quaternion(1, 0, 0, 0)
b = Quaternion(0, 1, 0, 0)
mid = slerp(a, b, 0.5)               # shortest arc on the 3-sphere

q0, q1, q2, q3 = [random_unit_quat() for _ in range(4)]
curve = squad(q0, q1, q2, q3, 0.75)  # cubic spline (Shoemake 1987)

# ---- Collections --------------------------------------------------
v = QuatVector([
    Quaternion(1,0,0,0), Quaternion(0,1,0,0), Quaternion(0,0,1,0)
])
v.real          # array([1., 0., 0.])
v.data.shape    # (3, 4)

A = QuatMatrix.eye(3)
B = QuatMatrix(np.random.randn(3, 4, 4))
C = A @ B       # quaternion matrix multiply (A * B also works)
C.shape         # (3, 4)

# ---- Linear algebra -----------------------------------------------
from quat.linalg import svd, pseudo_inverse, solve

U, s, Vh = svd(C)
A_pinv = pseudo_inverse(C)
x = solve(A_pinv, QuatVector(np.ones((3, 4))))

# ---- Signal processing --------------------------------------------
from quat.signal import qfft, qconv, lowpass

X = qfft(np.random.randn(256, 4))            # 1D quaternion FFT
k = lowpass(16, cutoff=0.2)                  # FIR lowpass filter
y = qconv(np.random.randn(128, 4), k._data)  # quaternion convolution

# ---- Serialization ------------------------------------------------
s = q.to_json()         # → '{"type":"Quaternion","data":[...]}'
b = q.to_bytes()        # → compact binary
q2 = Quaternion.from_json(s)
q3 = Quaternion.from_bytes(b)

# ---- Basis constants ----------------------------------------------
from quat import _I, _J, _K, _R, _ZERO
print(_I * _J * _K)     # -1 (Hamilton's fundamental identity)

API Reference

Quaternion — scalar quaternion

category methods
constructors zero(), one_q(), from_axis_angle(), from_euler(), from_complex_matrix(), from_real_matrix_left()
components .w, .r, .i, .j, .k, .real, .imag, .components, .data
arithmetic +, -, *, /, -q, @
algebra .conjugate(), .norm(), .normalize(), .normalized, .inverse(), .exp(), .log(), .pow(t), .re_inner(q), .commutator(q), .minimal()
rotation .rotate_vector(v), .to_axis_angle(), .to_euler(seq='zyx'), .angle, .axis
validation .isnan(), .isinf(), .isfinite(), .isclose(q)
serialization .to_json(), .from_json(s), .to_bytes(), .from_bytes(b)
matrices .to_complex_matrix(), .to_real_matrix_left(), .to_real_matrix_right()
conversion float(q), int(q), complex(q), abs(q), np.asarray(q)

QuatVector / QuatMatrix / QuatTensor

QuatVector QuatMatrix QuatTensor
ndim 1D 2D 3D
shape (n,) (m, n) (p, q, r)
create zeros, ones zeros, eye zeros
access .data, .real/.i/.j/.k .data, .real/.i/.j/.k, .row(i), .col(j) .data, .real/.i/.j/.k
ops .inner(v), .norm() .norm(), .T, .H, .conjugate() .inner(T), .unfold(mode), .mode_n_product(A)

Module overview

module exports
quat.random random_quat, random_unit_quat, random_quat_vector, random_quat_matrix, random_quat_tensor
quat.interpolate slerp, slerp_vector, squad, angular_velocity, integrate_angular_velocity, rotate_frame
quat.linalg svd, svd_values, rank, condition_number, pseudo_inverse, trace, det, norm, solve
quat.serialization to_json, from_json, to_bytes, from_bytes, to_scipy_rotation, from_scipy_rotation
quat.signal qfft, iqfft, qfft2, iqfft2, qconv, qconv2, lowpass, highpass, bandpass, bandstop
quat.stats rotation.intrinsic, rotation.chordal, rotor.intrinsic, rotor.chordal, mean_rotation, approximate_karcher_mean, quaternion_mean, quaternion_cov, quaternion_pca
quat.algebra hamilton_einsum, quat_matmul, conjugate_batch, norm_squared_batch, normalize_batch

Performance

The Hamilton product kernel uses a three-tier dispatch that selects the fastest strategy based on data size:

size kernel strategy
≤ 500 elements _hamilton_component direct float arithmetic
500 – 5000 _hamilton_einsum_noopt einsum without contraction-path optimisation
> 5000 _hamilton_einsum einsum with cached contraction-path optimisation

SVD fast-path: rank(), condition_number(), and norm(A, 2) compute only singular values via the complex (2×2) representation — ~20× faster than the full 4m×4n real SVD.

Zero-copy interop: q.to_numpy(copy=False) returns the internal buffer without copying. .to_complex_matrix() and .to_real_matrix_left() use np.empty to skip zero-initialisation.

Install

pip install quat-numpy

Requires Python ≥ 3.9, NumPy ≥ 1.21. Optional scipy for to_scipy_rotation / from_scipy_rotation.

For development:

git clone https://github.com/gealachlee/quat.git
cd quat
pip install -e .
pytest tests/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quat_numpy-1.0.0b1.tar.gz (45.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

quat_numpy-1.0.0b1-py3-none-any.whl (37.0 kB view details)

Uploaded Python 3

File details

Details for the file quat_numpy-1.0.0b1.tar.gz.

File metadata

  • Download URL: quat_numpy-1.0.0b1.tar.gz
  • Upload date:
  • Size: 45.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for quat_numpy-1.0.0b1.tar.gz
Algorithm Hash digest
SHA256 b383af27296f7dfbe847dc3668a29c688ff286423d2cf3f48826100bd1386342
MD5 3c5f7a01809e3bbd244c09eeda6fec30
BLAKE2b-256 92a286051143f9d66ed4a37c0750d7a0d16d9e038ddc822e16b3d73210003cab

See more details on using hashes here.

Provenance

The following attestation bundles were made for quat_numpy-1.0.0b1.tar.gz:

Publisher: publish.yml on gealachlee/quat

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quat_numpy-1.0.0b1-py3-none-any.whl.

File metadata

  • Download URL: quat_numpy-1.0.0b1-py3-none-any.whl
  • Upload date:
  • Size: 37.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for quat_numpy-1.0.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 7fa1fe909b72d59cec72a05027546887bd41e1863c65cad66802e86de5ed6718
MD5 cac7d431b9a65889bbe0618b7ad12a42
BLAKE2b-256 ba9617eea4b672aed0e8ac045aa517405b598391cf0f115c37240479e7849bed

See more details on using hashes here.

Provenance

The following attestation bundles were made for quat_numpy-1.0.0b1-py3-none-any.whl:

Publisher: publish.yml on gealachlee/quat

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page