Skip to main content

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 inverse
  • normalize() - Return normalized (unit) quaternion
  • simplify() - Simplify all components using SymPy
  • expand() - Expand all components using SymPy
  • eval(subs_dict=None, **kwargs) - Evaluate/substitute values for symbols

Conversion Methods

  • to_angle_axis(return_matrix=False) - Convert to angle-axis representation
  • from_rotation_matrix(matrix) - Create quaternion from 3x3 rotation matrix (classmethod)

Properties

  • scalar or w - Scalar (real) part of quaternion
  • vector - 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 multiplication
  • scalar * 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

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

sym_quaternions-0.1.0.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

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

sym_quaternions-0.1.0-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

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

Hashes for sym_quaternions-0.1.0.tar.gz
Algorithm Hash digest
SHA256 00f597aa25b75efd350ee4c37b05b2c99b1824352ad846f9fcacf5f6505ec078
MD5 48df5a784662c32fc2303ba901526365
BLAKE2b-256 d04030b68422df354a8fc1e78221682dec3b26abe7f750370a572775d0d70ff7

See more details on using hashes here.

File details

Details for the file sym_quaternions-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for sym_quaternions-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0ce30d087ee844208a6132d73a30a4dd786259a1bc8a54599a3268d32d7dab2b
MD5 42d7212479d3f675b80d99bab11293d1
BLAKE2b-256 be2385334ac32ef3e4a58fc9e65ff316da246df543ab5b70cdadbb3c9b7fd0de

See more details on using hashes here.

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