Skip to main content

Fast constexpr linear algebra for C++23 with zero-copy NumPy/SciPy interop

Project description

linalg3d

Header-only constexpr linear algebra library for C++23. Provides type-safe 2D, 3D, and 4D math primitives that evaluate entirely at compile time.

Features

  • Fully constexpr — all operations evaluate at compile time via gcem, with if consteval dispatch to std:: math and SIMD at runtime
  • SIMD optimized — SSE2/AVX/FMA (x86) and NEON (ARM) intrinsics for matrix multiply/inverse via automatic if consteval dispatch
  • Python bindingsnanobind-based package with zero-copy NumPy and SciPy interop
  • Type-safe anglesAngle<RADIANS> vs Angle<DEGREES> prevents unit-mismatch bugs at the type level
  • 2D, 3D, 4DVector2/Matrix2, Vector3/Matrix3, Vector4/Matrix4
  • Quaternions — multiplication, rotation, SLERP interpolation, Euler angle conversion
  • std::expected — matrix inverse() returns std::expected<Matrix, MatrixError> instead of silent failure
  • fmt support — optional format.hpp header with fmt::formatter specializations for all types
  • Zero dependencies at runtime — gcem is header-only (compile-time only), fmt is optional

Usage

#include <linalg3d/linalg.hpp>

using namespace linalg3d;

// Compile-time vector math
constexpr Vector3 a{1.0, 2.0, 3.0};
constexpr Vector3 b{4.0, 5.0, 6.0};
constexpr auto c = a.cross(b);
static_assert(c == Vector3{-3.0, 6.0, -3.0});

// Type-safe angles
constexpr Angle<AngleType::DEGREES> heading{90.0};
constexpr auto rad = heading.to_radians();

// Quaternion rotation
constexpr auto q = euler_angles_to_quaternion(EulerAngles{0.0, 0.0, PI / 2.0});
constexpr Vector3 rotated = q * Vector3{1.0, 0.0, 0.0};

// Safe matrix inversion
constexpr Matrix3 m{2.0, -1.0, 0.0, -1.0, 2.0, -1.0, 0.0, -1.0, 2.0};
constexpr auto inv = m.inverse();
static_assert(inv.has_value());

// SLERP interpolation
constexpr auto mid = slerp(Quaternion::identity(), q, 0.5);

// Angle between two vectors (radians)
constexpr auto theta = angle_between(Vector3{1.0, 0.0, 0.0}, Vector3{0.0, 1.0, 0.0});
static_assert(theta > 1.57 && theta < 1.58); // pi/2

// Angle between two quaternion orientations (shortest arc, radians)
auto rot_angle = angle_between(Quaternion::identity(), q);

// 2D and 4D
constexpr Vector2 v2{3.0, 4.0};
static_assert(v2.norm_sq() == 25.0);
constexpr Vector4 v4{1.0, 2.0, 3.0, 4.0};
constexpr auto identity4 = Matrix4::identity();

For fmt::print support:

#include <linalg3d/format.hpp>
fmt::print("{}\n", Vector3{1.0, 2.0, 3.0}); // (1, 2, 3)
fmt::print("{}\n", Quaternion::identity());   // Quaternion(w=1, x=0, y=0, z=0)

Types

Type Header Description
Vector2 vector2.hpp 2D vector with dot/cross(scalar)/norm
Vector3 vector3.hpp 3D vector with dot/cross/norm
Vector4 vector4.hpp 4D vector with dot/norm
Matrix2 matrix2x2.hpp 2x2 matrix with inverse/determinant
Matrix3 matrix3x3.hpp 3x3 matrix with inverse/determinant
Matrix4 matrix4x4.hpp 4x4 matrix with inverse/determinant
Quaternion quaternion.hpp Unit quaternion with rotation/SLERP/angle
Angle<T> angle.hpp Type-safe angle (radians/degrees)
EulerAngles<T> euler_angles.hpp Pitch/yaw/roll triplet

Benchmarks

Measured with nanobench (GCC 14, -O3 -march=native, Ubuntu 24.04). Compared against Eigen 3.4 on equivalent operations:

Operation linalg3d (ns) Eigen (ns) Ratio
Vector3 dot 0.76 0.54 1.4x
Vector3 cross 0.80 0.96 0.8x
Vector3 norm 1.49 1.49 1.0x
Vector3 normalized 3.50 3.48 1.0x
Matrix3 multiply 3.60 2.64 1.4x
Matrix3 inverse 7.11 7.23 0.98x
Matrix4 inverse 14.78 10.72 1.4x
Matrix4 multiply 2.90 2.50 1.2x
Quaternion multiply 1.75 1.21 1.4x
Quaternion inverse 2.02 8.77 0.23x
Quaternion*Vector3 2.01 2.42 0.8x
slerp 21.16 22.12 0.96x
quaternion_to_euler 18.80 26.67 0.7x
Angle::sin 4.22
Angle::cos 3.23

Ratio = linalg3d / Eigen (lower is better for linalg3d; bold = linalg3d wins).

Performance summary vs Eigen

  • linalg3d faster: Matrix3 inverse (0.98x), quaternion inverse (4.3x faster), cross product (0.8x), quaternion*vector (0.8x), slerp (0.96x), quaternion-to-euler (0.7x)
  • On par (0.9-1.2x): vector norm, normalized, add, matrix transpose, matrix4 multiply
  • Eigen faster: matrix3 multiply (1.4x), matrix4 inverse (1.4x), quaternion multiply (1.4x), dot product (1.4x)
  • Unique to linalg3d: all operations are constexpr (Eigen has none), type-safe angles, std::expected error handling, SIMD dispatched via if consteval
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --target linalg3d_bench
./build/linalg3d_bench

Examples

IMU attitude interpolation

Smoothly interpolate between two IMU quaternion readings for sub-frame timing.

#include <linalg3d/linalg.hpp>
using namespace linalg3d;

// Two IMU samples at different timestamps
const Quaternion q_t0{0.998, 0.01, 0.02, 0.05};
const Quaternion q_t1{0.997, 0.01, 0.03, 0.06};

// Interpolate at 60% between the two samples
auto q_mid = slerp(q_t0, q_t1, 0.6);

// How far apart are these orientations?
double delta = angle_between(q_t0, q_t1); // radians

Rotating a body-frame vector to NED

Convert a sensor reading from body frame to North-East-Down using an attitude quaternion.

// Sensor reports acceleration in body frame
constexpr Vector3 accel_body{0.1, -0.05, -9.81};

// Current attitude from IMU (quaternion: w, x, y, z)
const Quaternion attitude{0.998, 0.01, 0.02, 0.05};

// Rotate to NED frame
Vector3 accel_ned = attitude * accel_body;

Compile-time coordinate transform validation

Verify a rotation matrix at compile time -- errors caught before the code even runs.

constexpr auto q = euler_angles_to_quaternion(EulerAngles{0.0, 0.0, PI / 2.0});
constexpr auto mat = quaternion_to_matrix(q);
constexpr auto v = mat * Vector3{1.0, 0.0, 0.0};
// 90 deg yaw: x-axis maps to y-axis
static_assert(fabs(v.x) < 1e-10);
static_assert(fabs(v.y - 1.0) < 1e-10);

Python

Installation

pip install linalg3d

Or build from source:

pip install "./python[test]"

Python usage

from linalg3d import Vector3, Matrix3, Quaternion, slerp
import numpy as np

# Vectors
v = Vector3(1.0, 2.0, 3.0)
print(v.norm(), v.normalized())

# Zero-copy NumPy interop — no data copying
arr = np.asarray(v.numpy())     # shares memory with v
arr[0] = 99.0
assert v.x == 99.0              # modification reflected

# Matrices
m = Matrix3.identity()
arr = np.asarray(m.numpy())     # zero-copy 3x3 view
det = m.determinant()
inv = m.inverse()               # returns None if singular

# Quaternion rotation
import math
q = Quaternion(math.cos(math.pi/4), 0, 0, math.sin(math.pi/4))
rotated = q.rotate(Vector3(1, 0, 0))

# SLERP
mid = slerp(Quaternion(), q, 0.5)

# SciPy interop (convention: [x, y, z, w])
from scipy.spatial.transform import Rotation
scipy_arr = np.asarray(q.to_scipy())   # [x,y,z,w]
rot = Rotation.from_quat(scipy_arr)
q2 = Quaternion.from_scipy(scipy_arr)  # back to linalg3d

Build (C++)

Requires CMake 3.25+ and a C++23 compiler. Dependencies (gcem, fmt, doctest, nanobench) are fetched automatically via FetchContent if not found on the system.

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
ctest --test-dir build

License

MIT

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

linalg3d-0.3.2.tar.gz (11.4 kB view details)

Uploaded Source

Built Distributions

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

linalg3d-0.3.2-cp313-cp313-win_amd64.whl (89.9 kB view details)

Uploaded CPython 3.13Windows x86-64

linalg3d-0.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (92.0 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

linalg3d-0.3.2-cp313-cp313-macosx_11_0_arm64.whl (72.8 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

linalg3d-0.3.2-cp312-cp312-win_amd64.whl (89.9 kB view details)

Uploaded CPython 3.12Windows x86-64

linalg3d-0.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (92.0 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

linalg3d-0.3.2-cp312-cp312-macosx_11_0_arm64.whl (72.8 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

linalg3d-0.3.2-cp311-cp311-win_amd64.whl (90.6 kB view details)

Uploaded CPython 3.11Windows x86-64

linalg3d-0.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (93.1 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

linalg3d-0.3.2-cp311-cp311-macosx_11_0_arm64.whl (74.0 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

Details for the file linalg3d-0.3.2.tar.gz.

File metadata

  • Download URL: linalg3d-0.3.2.tar.gz
  • Upload date:
  • Size: 11.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for linalg3d-0.3.2.tar.gz
Algorithm Hash digest
SHA256 efc331e1c4bb9d95688f8faedcf8c9fc2c2cfe06ab6ff3786db042e04b339c03
MD5 bfe0645643e99acb6b17dc163cb63915
BLAKE2b-256 1bca233c936060e701fcea3a04fecea82f2d07f2330a6989f4682dfe2c56d307

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.3.2.tar.gz:

Publisher: publish.yml on PavelGuzenfeld/linalg3d

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

File details

Details for the file linalg3d-0.3.2-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: linalg3d-0.3.2-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 89.9 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for linalg3d-0.3.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 1efd2f052f1095e48f79560bc10f8c774ae0160f972142cab3d8f7cf42147071
MD5 8b622bc49a6846290dce8c36e0adbf2f
BLAKE2b-256 be5fe77616820633d5f9640ecbbada9ec0265af62734961ac8f4fb10d9479f07

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.3.2-cp313-cp313-win_amd64.whl:

Publisher: publish.yml on PavelGuzenfeld/linalg3d

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

File details

Details for the file linalg3d-0.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for linalg3d-0.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 73bf0cb08184d4449e022b27d81a6ee1b4a6fb6d357a68f103885ef3e5a7659d
MD5 3f020289bd55106a963ad7b4fce92a2a
BLAKE2b-256 960655d66a5fa42817038ea394e2a623e66d3c533188db90a95cc48fcd89d5dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish.yml on PavelGuzenfeld/linalg3d

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

File details

Details for the file linalg3d-0.3.2-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for linalg3d-0.3.2-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8fbf074e272c3248fc364205fb9ef9667b6ed516cee56fa43be130d1b1abd1ab
MD5 2d48c17f93a0ac4d31313c39a57b73d0
BLAKE2b-256 b0c020cf0f3597c2075f5bb57192969452e7009aca563a0f4bd7dfbe0a195242

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.3.2-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: publish.yml on PavelGuzenfeld/linalg3d

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

File details

Details for the file linalg3d-0.3.2-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: linalg3d-0.3.2-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 89.9 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for linalg3d-0.3.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e2af2c7827ed48464eb88abed80e86008274a7842ec5883a2288779ded332e0f
MD5 e866b25da5de7bf813504363ff2c14b9
BLAKE2b-256 b48388dc733ddb5d2c0adc62302a6083dd39aa54a2620bff0eab4274577f5f5a

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.3.2-cp312-cp312-win_amd64.whl:

Publisher: publish.yml on PavelGuzenfeld/linalg3d

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

File details

Details for the file linalg3d-0.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for linalg3d-0.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 41e23427c105dcc485b608f0a1afed66459961c20d748595025a061b43e995d4
MD5 b2cc7d2ce24f4b7fe2ea46815a558058
BLAKE2b-256 5d001dc8b2054087b848937da8db79ec454c697972f33d8c05515966da0ce09a

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish.yml on PavelGuzenfeld/linalg3d

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

File details

Details for the file linalg3d-0.3.2-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for linalg3d-0.3.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 14e64193a449fc6cb6571c3215c3d25f64ea9e0773d8b659378afd45b1eaa4f3
MD5 0c00ac365a789fcd10e4e73656b519e5
BLAKE2b-256 b6ec93fdab7d5d467edceb613b621d346c8441f15e8bf85626458cc42e4e4797

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.3.2-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: publish.yml on PavelGuzenfeld/linalg3d

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

File details

Details for the file linalg3d-0.3.2-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: linalg3d-0.3.2-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 90.6 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for linalg3d-0.3.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 22a8295e740863350d7bed348f41f5a32022559f02b30e35a5b2be51d75bc868
MD5 562ce8b387b6f4c9d94dd4b7442fdb39
BLAKE2b-256 5262094df6cedb1c06aa2d489d6fa51fd958f17432d3c323a35668af39daa2f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.3.2-cp311-cp311-win_amd64.whl:

Publisher: publish.yml on PavelGuzenfeld/linalg3d

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

File details

Details for the file linalg3d-0.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for linalg3d-0.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 790023671e6555ed007947e80afc0f498df54fbebac19c8400623661ad09ca76
MD5 9db835a0d91f05e7f20c166f85eadd99
BLAKE2b-256 2ed276a71e49f3675a4f688206b1b21667d5befd0ec5dd27fb4fee65db86cbe9

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish.yml on PavelGuzenfeld/linalg3d

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

File details

Details for the file linalg3d-0.3.2-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for linalg3d-0.3.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1f6d12059506c4594d992a6249038fc4bfd7242ac72fcb9631b9632aa4969519
MD5 ba5538eab339be41453a1427a446b5d4
BLAKE2b-256 70cccd366b306e5ae61096e74e13940eba2b398e87537f0b83fe57ba9fc14bcf

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.3.2-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: publish.yml on PavelGuzenfeld/linalg3d

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