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.4.1.tar.gz (11.5 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.4.1-cp313-cp313-win_amd64.whl (90.0 kB view details)

Uploaded CPython 3.13Windows x86-64

linalg3d-0.4.1-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.4.1-cp313-cp313-macosx_11_0_arm64.whl (72.9 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

linalg3d-0.4.1-cp312-cp312-win_amd64.whl (90.0 kB view details)

Uploaded CPython 3.12Windows x86-64

linalg3d-0.4.1-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.4.1-cp312-cp312-macosx_11_0_arm64.whl (72.9 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.11Windows x86-64

linalg3d-0.4.1-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.4.1-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.4.1.tar.gz.

File metadata

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

File hashes

Hashes for linalg3d-0.4.1.tar.gz
Algorithm Hash digest
SHA256 7a6f8fa1fc2a4ad594e5a97e89913d7081b1c2b95e2a867145a3d3d75b46feed
MD5 f248ccff78d48adf993487531e76b7e4
BLAKE2b-256 3ae9700b6c49a793fcef7f8b25288f4843f7f7c4c5b36ad00416dd251363096e

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.4.1.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.4.1-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: linalg3d-0.4.1-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 90.0 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.4.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 3a1504f37cb409f5c92c0e0dcaad20cc7f7a783430e277c584a26e79d56e6b3e
MD5 a580678fb4fa6d97a25beddc9f015c72
BLAKE2b-256 8d9ed1aca9d87e7ba07dfad85f9c73a9f445a8da0e1cb2c674b861281090acbf

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.4.1-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.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for linalg3d-0.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 31780c79b5d784cdfab7b3602fc0d06e06c495d96d360dcd37b80446690a21cf
MD5 891105bda48832f600f9542bc399a14d
BLAKE2b-256 ef56101e3c4e398a9af790f419e4ee18250d383744aa0b493b1d3bc0319df955

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.4.1-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.4.1-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for linalg3d-0.4.1-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 df96429a57852a1e6fcbbe82357c1e80cbbcb5610d7614f0dd842ff1db9b170b
MD5 50cb4d139bbf45363636d3bda94180f0
BLAKE2b-256 094439e38c8c91efdd08208523aa45f35821b344384cf2aac29bb686b5e8e9ee

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.4.1-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.4.1-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: linalg3d-0.4.1-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 90.0 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.4.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 63575165489311609bb47fff8c1b6e45eefcf513aa8a319cd487d03fa9da1e04
MD5 d01b5c369435d55bf6fdbec90c458f6b
BLAKE2b-256 eb081a64ea5b8d7e12eec6178ae3d565ba50bb492ba7bdbe4bf11936d08bbd22

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.4.1-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.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for linalg3d-0.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 abb9732162377e045267da41a9d221095dbfbb44fe788612b45ffd4365a0d9bb
MD5 4c88dc31240c0f8f314e5031070454e5
BLAKE2b-256 8baa6a2e73e28373b46b3e9a64371dabfb24e4cf2c5e0ed5f667da4907aa3cb9

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.4.1-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.4.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for linalg3d-0.4.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e2bef12dfbc647ce55d15532aebbf65fde5cc9c4a19fb7f0b49b1d14b3a6b62d
MD5 087934d88f65357856c24f2565c00268
BLAKE2b-256 4fb47eeec9310ceda749abfa3d5df39bd6556d90f3b3eada9b9d251315984712

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.4.1-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.4.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: linalg3d-0.4.1-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.4.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 a5f4b1e6092d50211f52dc9fd73a22de298bce1b7586ecc751f69e3ad0cbfc49
MD5 91e097466b4dd533e492037c7bdbe6f1
BLAKE2b-256 db1e9bd91c98b0bfdce4835df8b7c4253c4460f04b07b2360e8599aa7690d9d6

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.4.1-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.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for linalg3d-0.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2c6ce56b1460f464abf219d4687fe1d3c81b69fc67c1fa866f87a5d05c79ca53
MD5 b4bd7d63e6c8657097a99eec3edd8446
BLAKE2b-256 75bb1ab40b26b142089e8f5976946a700c89c7e9034fa0c1b572b0f669b1a0bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.4.1-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.4.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for linalg3d-0.4.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e0ff6429f109f3e17fd5cb5aaf62d6a9f895b01eed6dee21812cd3740210a069
MD5 615a5bb4fe9bfd926f6e09eb1706dc66
BLAKE2b-256 9e6b381c34f6617714f8f853618d3b24846da75884e5e857788f901e6d214a28

See more details on using hashes here.

Provenance

The following attestation bundles were made for linalg3d-0.4.1-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