A work-in-progress C++20/23 header-only maths library for game development, embedded, kernel and general-purpose that works in constant context.

kMath

/kmæθ/

A work-in-progress general-purpose C++20/23 header-only maths library that works in constant context

Abstract

The kMath Project aims to provide a simple implementation of mathematical concepts such as euclidean vectors, matrices, quaternions, euler angles, linear interpolation (lerp, slerp) that can be used in constant context. This allows the compiler to better understand the code at compile-time and generate better assembly.

We are not using compiler-specific or platform specific extensions but rely on the compilers auto-vectorization, -loop-unrolling and inlining instead which is particularly useful in some environments such as embedded or kernel that may not have access to the C Standard Library, AVX/SSE2 or MMX/x87 FPU instructions.

Documentation

You can find our documentation here, to generate it locally cd into git root directory and start doxygen.

Optimizations

// main.cpp
#include <https://raw.githubusercontent.com/auto-lambda/kMath/master/include/kmath/math.hpp>
#include <cstdio>

int main(int const argc, char const * const[]) {
  math::Vector const vector_2d {1.5, 1.5};      // (1.5, 1.5)
  math::Vector       vector_3d {1.5, 1.5, 1.5}; // (1.5, 1.5, 1.5)

  using ScalarType = decltype(vector_2d)::Scalar;
  // argc is 1 but the compiler doesn't know at compile-time
  auto const scalar = static_cast<ScalarType>(argc);
  
  auto const scalar_mul_vec =    scalar * vector_3d; //  1.50
  auto const vec_mul_scalar = vector_3d * scalar;    //  1.50
  auto const vec_mul_vec    = vector_2d * vector_3d; //  2.25
  vector_3d *= vector_3d;                            //  2.25
  auto const neg_vec3d = -vector_3d;                 // -2.25

  // math::ct_sqrt dynamically dispatches between
  // (a) compile-time implementation of sqrt if constant evaluated
  // (b) std::sqrt otherwise
  constexpr auto rational = math::ct_sqrt(5.0625); // 5.0625 = 2.25²
  
  std::printf("%.2lf\n%.2lf\n%.2lf\n%.2lf\n%.2lf\n%.2lf\n",
    scalar_mul_vec[0],  //  1.50
    vec_mul_scalar[0],  //  1.50
       vec_mul_vec[0],  //  2.25
         vector_3d[0],  //  2.25
         neg_vec3d[0],  // -2.25
            rational);  //  2.25

  // This gets optimized out!
  if (vector_2d[0] != static_cast<ScalarType>(1.5))
    puts("test failed");

  // you can use vec.raw() and unpack with structured bindings
  [[maybe_unused]] auto &[x,y,z] = vector_3d.raw();
}

Compiling main.cpp with clang 13 and -std=c++2b -O3 -Wall -Wpedantic -Wconversion -Werror -mavx2 produces the following output:

.LCPI0_0:
  .quad   0x3ff8000000000000                       # double  1.50
.LCPI0_1:
  .quad   0xc002000000000000                       # double -2.25
.LCPI0_2:
  .quad   0x4002000000000000                       # double  2.25
main:                                              # @main
  push      rax
  vcvtsi2sd xmm0, xmm0, edi                        # scalar = static_cast<ScalarType>(argc)
  vmulsd    xmm0, xmm0, qword ptr [rip + .LCPI0_0] #   arg1 = scalar * vector_3d // 1.50
  vmovsd    xmm4,       qword ptr [rip + .LCPI0_1] #   arg5 = -2.25
  vmovsd    xmm2,       qword ptr [rip + .LCPI0_2] #   arg3 =  2.25
  mov       edi, offset .L.str                     #   arg0 = format string
  vmovapd   xmm1, xmm0                             #   arg2 = arg1 // 1.50
  vmovaps   xmm3, xmm2                             #   arg4 = arg3 // 2.25
  vmovaps   xmm5, xmm2                             #   arg6 = arg3 // 2.25
  mov       al, 6                                  # printf argument count
  call      printf                                 # call printf
  xor       eax, eax                               # return 0
  pop       rcx
  ret
.L.str:
  .asciz  "%.2lf\n%.2lf\n%.2lf\n%.2lf\n%.2lf\n%.2lf\n"

Try it live on the amazing Compiler Explorer by Matt Godbolt [x86-64 clang, gcc, icx, ARM64 gcc, RISC-V clang, gcc]

Progress

  • mathematical constants
  • vector
  • matrix
  • quaternions
  • interpolation
Similar Resources

A header-only C++ library for large scale eigenvalue problems

A header-only C++ library for large scale eigenvalue problems

NOTE: Spectra 1.0.0 is released, with a lot of API-breaking changes. Please see the migration guide for a smooth transition to the new version. NOTE:

Sep 22, 2022

Header-only C++11 library to handle physical measures

cpp-measures Header-only C++11 library to handle physical measures License: This project is released under the Mozilla Public License 2.0. Purpose Thi

Jun 28, 2018

A C++ header only library for decomposition of spectra into a sum of response functions whose weights are positive definite.

A C++ header only library for decomposition of spectra into a sum of response functions whose weights are positive definite.

DecompLib A C++ header only library for decomposition of spectra into a sum of response functions whose weights are positive definite. Introduction Bu

Jan 22, 2022

A matrix header-only library, uses graphs internally, helpful when your matrix is part of a simulation where it needs to grow many times (or auto expand)

GraphMat Header-only Library Matrix implemented as a graph, specially for the use case when it should be auto expanding at custom rate, specially in s

Oct 25, 2021

linalg.h is a single header, public domain, short vector math library for C++

linalg.h linalg.h is a single header, public domain, short vector math library for C++. It is inspired by the syntax of popular shading and compute la

Sep 23, 2022

MIRACL Cryptographic SDK: Multiprecision Integer and Rational Arithmetic Cryptographic Library is a C software library that is widely regarded by developers as the gold standard open source SDK for elliptic curve cryptography (ECC).

MIRACL What is MIRACL? Multiprecision Integer and Rational Arithmetic Cryptographic Library – the MIRACL Crypto SDK – is a C software library that is

Sep 20, 2022

A C library for statistical and scientific computing

Apophenia is an open statistical library for working with data sets and statistical or simulation models. It provides functions on the same level as t

Sep 11, 2022

a lean linear math library, aimed at graphics programming. Supports vec3, vec4, mat4x4 and quaternions

linmath.h -- A small library for linear math as required for computer graphics linmath.h provides the most used types required for programming compute

Sep 18, 2022

nml is a simple matrix and linear algebra library written in standard C.

nml is a simple matrix and linear algebra library written in standard C.

Sep 12, 2022
ArrayFire: a general purpose GPU library.
ArrayFire: a general purpose GPU library.

ArrayFire is a general-purpose tensor library that simplifies the process of software development for the parallel architectures found in CPUs, GPUs,

Sep 20, 2022
libmpc++ is a C++ header-only library to solve linear and non-linear MPC

libmpc++ libmpc++ is a C++ library to solve linear and non-linear MPC. The library is written in modern C++17 and it is tested to work on Linux, macOS

Jul 8, 2022
Header only, single file, simple and efficient C++ library to compute the signed distance function to a triangle mesh

TriangleMeshDistance Header only, single file, simple and efficient C++11 library to compute the signed distance function to a triangle mesh. The dist

Sep 12, 2022
A C++ header-only library of statistical distribution functions.

StatsLib StatsLib is a templated C++ library of statistical distribution functions, featuring unique compile-time computing capabilities and seamless

Sep 14, 2022
RcppFastFloat: Rcpp Bindings for the fastfloat C++ Header-Only Library
RcppFastFloat: Rcpp Bindings for the fastfloat C++ Header-Only Library

Converting ascii text into (floating-point) numeric values is a very common problem. The fast_float header-only C++ library by Daniel Lemire does this very well, and very fast at up to or over to 1 gigabyte per second as described in more detail in a recent arXiv paper.

May 2, 2022
Header only FFT library

dj_fft: Header-only FFT library Details This repository provides a header-only library to compute fourier transforms in 1D, 2D, and 3D. Its goal is to

Sep 1, 2022
C++ header-only fixed-point math library

fpm A C++ header-only fixed-point math library. "fpm" stands for "fixed-point math". It is designed to serve as a drop-in replacement for floating-poi

Sep 22, 2022
C++ header-only library with methods to efficiently encode/decode Morton codes in/from 2D/3D coordinates

Libmorton v0.2.7 Libmorton is a C++ header-only library with methods to efficiently encode/decode 64, 32 and 16-bit Morton codes and coordinates, in 2

Sep 13, 2022
Extremely simple yet powerful header-only C++ plotting library built on the popular matplotlib
Extremely simple yet powerful header-only C++ plotting library built on the popular matplotlib

matplotlib-cpp Welcome to matplotlib-cpp, possibly the simplest C++ plotting library. It is built to resemble the plotting API used by Matlab and matp

Sep 23, 2022
A modern, C++20-native, single-file header-only dense 2D matrix library.
A modern, C++20-native, single-file header-only dense 2D matrix library.

A modern, C++20-native, single-file header-only dense 2D matrix library. Contents Example usage creating matrices basic operations row, col, size, sha

Aug 4, 2022