Skip to main content

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
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 .r, .i, .j, .k, .real, .imag, .components, .data
arithmetic +, -, *, /, -q, @
algebra .conjugate(), .norm(), .normalize(), .inverse(), .exp(), .log(), .pow(t), .re_inner(q), .commutator(q)
rotation .rotate_vector(v), .to_axis_angle(), .to_euler(seq='zyx')
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
quat.linalg svd, 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.optimized 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 full 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/

Metadata

Release files for quat-numpy 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for quat-numpy 0.2.0
File Size Uploaded
quat_numpy-0.2.0.tar.gz 42.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for quat-numpy 0.2.0
File Interpreter ABI Platform
quat_numpy-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 78.3 kB

Release files / quat_numpy-0.2.0.tar.gz

Download URL quat_numpy-0.2.0.tar.gz
Size 42.5 kB
Tags Source
SHA-256 checksum
How to use checksums
6b4953581c052a93f96172dd59843e815706e9607fc0b69f3b28d110f70f1d23
BLAKE2b-256 checksum
How to use checksums
b76bec58885463c45bb5d5e7677576909feb732941a165f15325a5dfdc1bfb74
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 29, 2026.

Transparency log

Release files / quat_numpy-0.2.0-py3-none-any.whl

Download URL quat_numpy-0.2.0-py3-none-any.whl
Size 35.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4746f81a294a791c3a45ce351eec87de0a753f414dc1c1c3068b921fdd6cec32
BLAKE2b-256 checksum
How to use checksums
3f5af84e1db0d40f0756897c3a57e39cc0bb30be2ad950cf323a1fbd61b146b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 29, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page