This is a symbolic quaternion library for 3D rotation algebra built on SymPy.
Project description
sym-quaternions
A Python library for symbolic quaternion operations using SymPy, designed for 3D rotation algebra and analysis.
Description
sym-quaternions provides a powerful symbolic implementation of quaternions for representing and manipulating 3D rotations. Built on top of SymPy, the library enables symbolic algebra, automatic differentiation, and analytical solutions for rotation problems. It offers methods for:
- Creating rotation quaternions from angle-axis representation (with symbolic or numeric parameters)
- Rotating vectors and coordinate bases symbolically
- Converting quaternions to rotation matrices
- Quaternion arithmetic (multiplication, conjugation, inversion, normalization)
- Symbolic simplification and evaluation
- Converting between angle-axis and quaternion representations
Installation
Install from PyPI:
pip install sym-quaternions
Or install from source:
git clone https://github.com/avabr/sym-quaternions.git
cd sym-quaternions
pip install -e .
Usage
Basic Example
import sympy as sp
from sym_quaternions import SymQuaternion
# Create a quaternion representing 90-degree rotation around x-axis
q = SymQuaternion(angle=sp.pi/2, axis=[1, 0, 0])
# Define a vector
v = sp.Matrix([0, 1, 0])
# Rotate the vector
rotated = q.rotate_vector(v)
print(rotated) # Output: Matrix([[0], [0], [1]])
Creating Quaternions
import sympy as sp
# Identity quaternion (no rotation)
q = SymQuaternion()
# From angle-axis representation
q = SymQuaternion(angle=sp.pi/4, axis=[0, 0, 1])
# From quaternion components
q = SymQuaternion(w=1, x=0, y=0, z=0)
# With symbolic parameters
theta = sp.Symbol('theta', real=True)
q = SymQuaternion(angle=theta, axis=[0, 0, 1])
# Parameters:
# - angle: rotation angle (numeric or symbolic)
# - axis: rotation axis as list, tuple, or sp.Matrix (will be normalized)
# - w, x, y, z: quaternion components (alternative to angle-axis)
Symbolic Parameters
One of the key features of sym-quaternions is the ability to work with symbolic parameters:
import sympy as sp
# Create symbolic quaternion
theta = sp.Symbol('theta', real=True)
q = SymQuaternion(angle=theta, axis=[0, 0, 1])
# Get rotation matrix symbolically
M = q.to_rotation_matrix()
print(M)
# Output: symbolic 3x3 matrix in terms of theta
# Simplify expressions
M_simplified = sp.simplify(M)
# Substitute specific values
M_45deg = M.subs(theta, sp.pi/4)
# Or evaluate the quaternion directly
q_45deg = q.eval(theta=sp.pi/4)
Rotating Vectors
import sympy as sp
q = SymQuaternion(angle=sp.pi/2, axis=[1, 0, 0])
# Rotate a vector in space (q * v * q⁻¹)
v = sp.Matrix([0, 1, 0])
v_rotated = q.rotate_vector(v)
# Rotate the coordinate basis (inverse rotation: q⁻¹ * v * q)
v_basis = q.rotate_basis(v)
# Works with symbolic vectors too
x, y, z = sp.symbols('x y z', real=True)
v_sym = sp.Matrix([x, y, z])
v_rotated_sym = q.rotate_vector(v_sym)
Getting Rotation Matrix
# Get the 3x3 rotation matrix
M = q.to_rotation_matrix()
print(M)
# The matrix can be used for standard matrix operations
v_matrix = sp.Matrix([1, 0, 0])
v_rotated = M * v_matrix
# Simplify the result
v_rotated = sp.simplify(v_rotated)
Quaternion Operations
import sympy as sp
q = SymQuaternion(angle=sp.pi/4, axis=[0, 0, 1])
# Quaternion conjugate
q_conj = q.conjugate()
# Quaternion norm (squared magnitude)
norm_sq = q.norm()
# Quaternion inverse
q_inv = q.inv()
# Normalize quaternion (make it unit quaternion)
q_unit = q.normalize()
# Quaternion multiplication
q1 = SymQuaternion(angle=sp.pi/4, axis=[0, 0, 1])
q2 = SymQuaternion(angle=sp.pi/4, axis=[0, 0, 1])
q_result = q1 * q2 # 90-degree rotation
# Scalar multiplication
q_scaled = q * 2
q_scaled = 2 * q # Also works
# Simplify quaternion components
q_simple = q.simplify()
# Expand quaternion components
q_expanded = q.expand()
Angle-Axis Conversion
import sympy as sp
# Create from angle-axis
q = SymQuaternion(angle=sp.pi/3, axis=[1, 1, 1])
# Convert back to angle-axis
angle, axis = q.to_angle_axis()
print(f"Angle: {angle}")
print(f"Axis: {axis}")
# Get axis as sp.Matrix instead of list
angle, axis = q.to_angle_axis(return_matrix=True)
Complete Example: Symbolic Rotation Analysis
import sympy as sp
from sym_quaternions import SymQuaternion
# Define symbolic rotation angle
theta = sp.Symbol('theta', real=True)
# Create a rotation around the z-axis
q = SymQuaternion(angle=theta, axis=[0, 0, 1])
# Define a point
point = sp.Matrix([1, 0, 0])
# Rotate the point symbolically
rotated_point = q.rotate_vector(point)
print("Rotated point (symbolic):")
print(rotated_point)
# Output: Matrix([[cos(theta)], [sin(theta)], [0]])
# Get the rotation matrix
matrix = q.to_rotation_matrix()
print("\nRotation matrix (symbolic):")
print(sp.simplify(matrix))
# Evaluate at specific angle (45 degrees)
q_45 = q.eval(theta=sp.pi/4)
rotated_45 = q_45.rotate_vector(sp.Matrix([1, 0, 0]))
print("\nRotated point at 45 degrees:")
print(rotated_45)
print(f"Numerical: [{float(rotated_45[0]):.3f}, {float(rotated_45[1]):.3f}, {float(rotated_45[2]):.3f}]")
Integration with NumPy
For numerical evaluation, you can convert symbolic results to NumPy:
import sympy as sp
import numpy as np
theta = sp.Symbol('theta')
q = SymQuaternion(angle=theta, axis=[0, 0, 1])
# Get rotation matrix symbolically
M_sym = q.to_rotation_matrix()
# Convert to numerical function
M_func = sp.lambdify(theta, M_sym, 'numpy')
# Evaluate at multiple angles
angles = np.linspace(0, 2*np.pi, 10)
for angle in angles:
M_num = M_func(angle)
print(f"Angle: {angle:.2f}, Matrix:\n{M_num}\n")
API Reference
Constructor
SymQuaternion(angle=None, axis=None, w=None, x=None, y=None, z=None)- Create a quaternion
Rotation Methods
rotate_vector(vector)- Rotate a vector in space (q * v * q⁻¹)rotate_basis(vector)- Rotate the coordinate basis (q⁻¹ * v * q)to_rotation_matrix()- Get the 3x3 rotation matrix representation
Quaternion Operations
conjugate()- Get the quaternion conjugate (w, -x, -y, -z)norm()- Calculate the quaternion norm squared (w² + x² + y² + z²)inv()- Get the quaternion inversenormalize()- Return normalized (unit) quaternionsimplify()- Simplify all components using SymPyexpand()- Expand all components using SymPyeval(subs_dict=None, **kwargs)- Evaluate/substitute values for symbols
Conversion Methods
to_angle_axis(return_matrix=False)- Convert to angle-axis representationfrom_rotation_matrix(matrix)- Create quaternion from 3x3 rotation matrix (classmethod)
Properties
scalarorw- Scalar (real) part of quaternionvector- Vector part as list [x, y, z]vector_as_matrix- Vector part as sp.Matrix(3,1)as_matrix- Full quaternion as sp.Matrix(4,1)
Operators
q1 * q2- Quaternion multiplication (Hamilton product)q * scalar- Scalar multiplicationscalar * q- Scalar multiplication (reverse)
Running Tests
To run the test suite:
# Install development dependencies
pip install pytest numpy num-quaternions
# Run all tests
pytest tests/
# Run tests with verbose output
pytest -v tests/
# Run comparison tests with num-quaternions
pytest tests/test_comparison_with_num_quaternions.py -v
# Run specific test
pytest tests/test_comparison_with_num_quaternions.py::TestSymbolicEvaluation::test_symbolic_angle_substitution -v
Requirements
- Python >= 3.7
- sympy >= 1.8.0
- numpy (for testing and numerical evaluation)
- num-quaternions (for comparison tests)
Comparison with num-quaternions
sym-quaternions is the symbolic counterpart to num-quaternions:
| Feature | sym-quaternions | num-quaternions |
|---|---|---|
| Backend | SymPy (symbolic) | NumPy (numerical) |
| Parameters | Symbolic or numeric | Numeric only |
| Use case | Analytical derivations, symbolic algebra | Fast numerical computation |
| Differentiation | Automatic (via SymPy) | Manual implementation needed |
| Performance | Slower (symbolic) | Fast (compiled NumPy) |
| Simplification | Built-in (SymPy) | N/A |
Both libraries share the same API design and produce identical numerical results when symbolic expressions are evaluated.
License
MIT License - see LICENSE file for details.
Author
Alexander Abramov (extremal.ru@gmail.com)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Links
- GitHub: https://github.com/avabr/sym-quaternions
- PyPI: https://pypi.org/project/sym-quaternions/
- Issues: https://github.com/avabr/sym-quaternions/issues
- Related: num-quaternions (NumPy-based numerical quaternions)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sym_quaternions-0.1.0.tar.gz.
File metadata
- Download URL: sym_quaternions-0.1.0.tar.gz
- Upload date:
- Size: 13.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
00f597aa25b75efd350ee4c37b05b2c99b1824352ad846f9fcacf5f6505ec078
|
|
| MD5 |
48df5a784662c32fc2303ba901526365
|
|
| BLAKE2b-256 |
d04030b68422df354a8fc1e78221682dec3b26abe7f750370a572775d0d70ff7
|
File details
Details for the file sym_quaternions-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sym_quaternions-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ce30d087ee844208a6132d73a30a4dd786259a1bc8a54599a3268d32d7dab2b
|
|
| MD5 |
42d7212479d3f675b80d99bab11293d1
|
|
| BLAKE2b-256 |
be2385334ac32ef3e4a58fc9e65ff316da246df543ab5b70cdadbb3c9b7fd0de
|