GCE-Math ( Generalized C onstant Expression Math) は、数学関数のコンパイル時の計算を可能にするテンプレート化された C++ ライブラリです。
特徴:
constexpr
形式で記述されており、C++11/14/17/20 と互換性があります。gcem::
構文は、C++ 標準ライブラリ ( std::
) の構文と同じです。著者: キース・オハラ
ライブラリは積極的にメンテナンスされており、現在も拡張されています。機能のリストには次のものが含まれます。
abs
、 max
、 min
、 pow
、 sqrt
、 inv_sqrt
、ceil
、 floor
、 round
、 trunc
、 fmod
、exp
、 expm1
、 log
、 log1p
、 log2
、 log10
などcos
、 sin
、 tan
acos
、 asin
、 atan
、 atan2
cosh
、 sinh
、 tanh
、 acosh
、 asinh
、 atanh
gcd
、 lcm
factorial
、 binomial_coef
beta
、 lbeta
、 lgamma
、 tgamma
、 lmgamma
erf
、 erf_inv
incomplete_beta
、 incomplete_gamma
incomplete_beta_inv
、 incomplete_gamma_inv
完全なドキュメントはオンラインで入手できます。
ドキュメントの PDF 版はここから入手できます。
GCE-Math はヘッダーのみのライブラリであり、追加のライブラリやユーティリティ (C++11 互換コンパイラ以外) は必要ありません。以下を使用してヘッダー ファイルをプロジェクトに追加するだけです。
# include " gcem.hpp "
Conda パッケージ マネージャーを使用して GCE-Math をインストールできます。
conda install -c conda-forge gcem
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
たとえば、 /gcem/install/location
/usr/local/
になります。
テスト スイートを構築するには 2 つの方法があります。 Unix 系システムでは、Makefile はtests/
下にあります。
cd ./gcem/tests
make
./run_tests
CMake では、オプションGCEM_BUILD_TESTS=1
により、テスト スイートのビルドに必要な Makefile が生成されます。
cd ./gcem
mkdir build
cd build
cmake ../ -DGCEM_BUILD_TESTS=1 -DCMAKE_INSTALL_PREFIX=/gcem/install/location
make gcem_tests
cd tests
./exp.test
インタラクティブな Jupyter ノートブックを使用して、ライブラリをオンラインでテストできます。
GCE-Math 関数は、 constexpr
指定子を備えた C++ テンプレートとして記述されます。その形式は、テンプレートベースのプログラミングに慣れていないユーザーにとってはわかりにくいかもしれません。
たとえば、ガウス誤差関数 ( erf
) は次のように定義されます。
template < typename T>
constexpr
return_t <T>
erf ( const T x) noexcept ;
内部テンプレート化されたconstexpr
関数のセットは連分数展開を実装し、 return_t<T>
型の値を返します。出力タイプ (' return_t<T>
') は通常、入力タイプ (例: int
、 float
、 double
、 long double
など) によって決まります。 T
が整数型の場合、出力はreturn_t<T> = double
にアップグレードされ、そうでない場合はreturn_t<T> = T
にアップグレードされます。 std::is_integral
でカバーされていない型の場合は、リキャストを使用する必要があります。
10! を計算するには:
# include " gcem.hpp "
int main ()
{
constexpr int x = 10 ;
constexpr int res = gcem::factorial (x);
return 0 ;
}
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
ret
関数呼び出しが数値 (10! = 3628800) に置き換えられていることがわかります。
同様に、ある点での対数ガンマ関数を計算するには、次のようにします。
# include " gcem.hpp "
int main ()
{
constexpr long double x = 1.5 ;
constexpr long double res = gcem::lgamma (x);
return 0 ;
}
アセンブリコード:
.LCPI0_0:
.long 1069547520 # float 1 . 5
.LCPI0_1:
.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
ret