Generalized Constant Expression Math

GCEM Build Coverage Status

Watch Star Fork


GCE-Math (generalized constant expression math, or gcem) is a templated C++ library for compile-time computation of mathematical functions.


Features:

  • 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 machine precision against the C++ standard library.
  • Released under a permissive, non-GPL license.

Coverage:

  • basic C++ standard library functions:
    • abs, exp, log, max, min, pow, sqrt
  • trigonometric functions:
    • basic: cos, sin, tan
    • inverse: acos, asin, atan
    • hyperbolic (area) functions: cosh, sinh, tanh, acosh, asinh, atanh
  • special functions:
    • factorials and the binomial coefficient: factorial, binomial_coef
    • beta and gamma functions: beta, lbeta, lgamma, tgamma
    • 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

Author: Keith O'Hara

License


Download and Installation

  • GCE-Math is a header-only library. Simply #include the gcem header files with your project.
  • The source code is available on GitHub.
  •     git clone -b master --single-branch https://github.com/kthohr/gcem ./gcem

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. For example, the Gaussian error function (erf) is defined as:
template<typename T>
constexpr
return_t<T>
erf(const T x);
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.

Examples

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:
    _main:                                  ## @main
	.cfi_startproc
## BB#0:
	push	rbp
Lcfi0:
	.cfi_def_cfa_offset 16
Lcfi1:
	.cfi_offset rbp, -16
	mov	rbp, rsp
Lcfi2:
	.cfi_def_cfa_register rbp
	xor	eax, eax
	mov	dword ptr [rbp - 4], 0
	mov	dword ptr [rbp - 8], 10
	mov	dword ptr [rbp - 12], 3628800
	pop	rbp
	ret
	.cfi_endproc
We see that a function call has been replaced by a numeric value (10! = 3628800).

To build and run the full test suite:

# clone gcem
git clone -b master --single-branch https://github.com/kthohr/gcem ./gcem
# compile tests
cd ./gcem/tests
make
./run_tests