A C++ compile-time math library using generalized constant expressions
Switch branches/tags
Nothing to show
Clone or download
Latest commit fe6c4f9 Dec 8, 2018
Type Name Latest commit message Commit time
Failed to load latest commit information.
binder update Oct 28, 2018
cmake_files version 1.6.0 Oct 27, 2018
docs update Nov 11, 2018
include internal update Dec 8, 2018
notebooks update Oct 28, 2018
tests update incomplete_gamma UB Nov 21, 2018
.appveyor.yml fix appveyor build Nov 10, 2018
.gitignore update Oct 28, 2018
.lgtm.yml Fix lgtm.yml Oct 27, 2018
.readthedocs.requirements.txt rename log_multi_gamma Oct 27, 2018
.readthedocs.yml rename log_multi_gamma Oct 27, 2018
.travis.yml Fix clang6 build Nov 4, 2018
CMakeLists.txt update CMake list Dec 8, 2018
LICENSE Version 1 release Mar 1, 2018
NOTICE.txt Version 1 release Mar 1, 2018
README.md update Nov 11, 2018
contributors.txt Version 1.8.0 Nov 4, 2018



Build Status Build status Coverage Status Codacy Badge Language grade: C/C++ Documentation Status

GCE-Math (Generalized Constant Expression Math) is a templated C++ library enabling compile-time computation of mathematical functions.


  • The library is written in C++11 constexpr format, and is C++11/14/17 compatible.
  • Continued fraction and series expansions are implemented using recursive templates.
  • The gcem:: syntax is identical to the C++ standard library (std::).
  • Tested and accurate to floating-point precision against the C++ standard library.
  • Released under a permissive, non-GPL license.

Author: Keith O'Hara



Status and Documentation

The library is actively maintained, and is still being extended. A list of features includes:

  • basic library functions:
    • abs, max, min, pow, sqrt,
    • exp, expm1, log, log1p, and more
  • trigonometric functions:
    • basic: cos, sin, tan
    • inverse: acos, asin, atan, atan2
  • hyperbolic (area) functions:
    • cosh, sinh, tanh, acosh, asinh, atanh
  • algorithms:
    • gcd, lcm
  • special functions:
    • factorials and the binomial coefficient: factorial, binomial_coef
    • beta, gamma, and multivariate gamma functions: beta, lbeta, lgamma, tgamma, lmgamma
    • the Gaussian error function and inverse error function: erf, erf_inv
    • (regularized) incomplete beta and incomplete gamma functions: incomplete_beta, incomplete_gamma
    • inverse incomplete beta and incomplete gamma functions: incomplete_beta_inv, incomplete_gamma_inv

Full documentation is available online:

Documentation Status

Installation and Tests

GCE-Math is a header-only library and does not require any additional libraries (beyond a C++11 compatible compiler). Simply add the header files to your project using:

#include "gcem.hpp"


You can install GCE-Math using the conda package manager.

conda install gcem -c kthohr


You can also install the library from source using CMake.

# clone gcem from GitHub
git clone https://github.com/kthohr/gcem ./gcem

# make a build directory
cd ./gcem
mkdir build
cd build

# generate Makefiles and install
cmake .. -DCMAKE_INSTALL_PREFIX=/gcem/install/location
make install

For example, /gcem/install/location could be /usr/local/.

Test Suite

There are two ways to build the test suite. On Unix-alike systems, a Makefile is available under tests/.

cd ./gcem/tests

With CMake, the option BUILD_TESTS=1 generates the necessary Makefiles to build the test suite.

cd ./gcem
mkdir build

cd build
cmake ../ -DBUILD_TESTS=1 -DCMAKE_INSTALL_PREFIX=/gcem/install/location
make gcem_tests

cd tests

Jupyter Notebook

You can test the library online using an interactive Jupyter notebook:


General Syntax

GCE-Math functions are written as C++ templates with constexpr specifiers, the format of which might be confusing to users unfamiliar with template-based programming. As an example, the Gaussian error function (erf) is defined as:

template<typename T>
erf(const T x) noexcept;

where a set of internal templated constexpr functions will implement a continued fraction expansion to return a value of type return_t<T>. This output type ('return_t<T>') is generally determined by the input type, e.g., int, float, double, long double, etc. When T is an intergral type, the output will be upgraded to return_t<T> = double, otherwise return_t<T> = T. For types not covered by std::is_integral, recasts should be used.


To calculate 10!:

#include "gcem.hpp"

int main()
    constexpr int x = 10;
    constexpr int res = gcem::factorial(x);

    return 0;

Inspecting the assembly code generated by Clang 7.0.0:

        push    rbp
        mov     rbp, rsp
        xor     eax, eax
        mov     dword ptr [rbp - 4], 0
        mov     dword ptr [rbp - 8], 10
        mov     dword ptr [rbp - 12], 3628800
        pop     rbp

We see that a function call has been replaced by a numeric value (10! = 3628800).

Similarly, to compute the log Gamma function at a point:

#include "gcem.hpp"

int main()
    constexpr long double x = 1.5;
    constexpr long double res = gcem::lgamma(x);

    return 0;

Assembly code:

        .long   1069547520              # float 1.5
        .quad   -622431863250842976     # x86_fp80 -0.120782237635245222719
        .short  49147
        .zero   6
main:                                   # @main
        push    rbp
        mov     rbp, rsp
        xor     eax, eax
        mov     dword ptr [rbp - 4], 0
        fld     dword ptr [rip + .LCPI0_0]
        fstp    tbyte ptr [rbp - 32]
        fld     tbyte ptr [rip + .LCPI0_1]
        fstp    tbyte ptr [rbp - 48]
        pop     rbp

Related libraries

For a library built on the GCEM compile-time functionality, see StatsLib.