GCE-Math (Generalized Constant Expression Math, or gcem) is a templated C++ library enabling compile-time computation of mathematical functions.
Features:
gcem::
syntax is identical to the C++ standard library (std::
).Author: Keith O'Hara
Contents:
Coverage:
abs
, exp
, log
, max
, min
, pow
, sqrt
gcd
, lcm
, and more
cos
, sin
, tan
acos
, asin
, atan
cosh
, sinh
, tanh
, acosh
, asinh
, atanh
factorial
, binomial_coef
beta
, lbeta
, lgamma
, tgamma
, lmgamma
erf
, erf_inv
incomplete_beta
, incomplete_gamma
incomplete_beta_inv
, incomplete_gamma_inv
Full documentation is available online:
git clone https://github.com/kthohr/gcem.git ./gcem
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/
.
There are two ways to build the test suite. On Unix-alike systems, a Makefile is available under tests/
.
cd ./gcem/tests make ./run_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 ./exp.test
You can test the library online using an interactive Jupyter notebook:
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.
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).