GCE-Math( G eneralized C onstant E xpression 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/
일 수 있습니다.
테스트 스위트를 구축하는 방법에는 두 가지가 있습니다. Unix와 유사한 시스템에서는 tests/
아래에서 Makefile을 사용할 수 있습니다.
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