수학 함수

이 단원에서는 기초적인 수학 함수들을 다룹니다. 여기서 다루는 함수들의 일부는 이미 시스템 라이브러리에서 제공합니다 1 . 그러나 해당 시스템 함수들을 쓸 수 없는 경우를 대비해, gsl 에서 대체 함수들을 포함해 제공합니다.

본 단원에서 제공하는 함수와 매크로들은 gsl_math.h 헤더 파일에 포함되어 있습니다.

수학 상수

이 라이브러리에서는 표준 BSD 라이브러리의 수학 상수들을 제공합니다. 해당 자료를 기반으로 다음과 같은 상수들을 포함합니다.

M_E

지수함수의 밑, \(e\)

M_LOG2E

\(e\) 의 밑이 2인 로그 값, \(\log_2 (e)\)

M_LOG10E

\(e\) 의 밑이 10인 로그 값, \(\log_{10} (e)\)

M_SQRT2

2의 제곱근, \(\sqrt{2}\)

M_SQRT1_2

1/2의 제곱근, \(\sqrt{1/2}\)

M_SQRT3

3의 제곱근, \(\sqrt{3}\)

M_PI

원주율 상수, \(\pi\)

M_PI_2

원주율의 절반 값, \(\pi/2\)

M_PI_4

원주율의 1/4 값, \(\pi/4\)

M_SQRTPI

원주율의 제곱근, \(\sqrt{\pi}\)

M_2_SQRTPI

2를 원주율의 제곱근으로 나눈 값, \(2/\sqrt{\pi}\)

M_1_PI

원주율의 역수, \(1/ \pi\)

M_2_PI

원주율의 역수의 2배, \(2/ \pi\)

M_LN10

10의 자연로그 값, \(\ln(10)\)

M_LN2

2의 자연로그 값, \(\ln(2)\)

M_LNPI

파이의 자연로그 값, \(\ln(\pi)\)

M_EULER

오일러 상수, \(\gamma\)

무한과 비정상 값(Not-A-Number)

GSL_POSINF

IEEE 표기 형식의 양의 무한대( \(+\infty\) )를 나타냅니다. 이 값은 \(+ 1.0/0.0\) 으로 표현될 수 있습니다.

GSL_NEGINF

IEEE 표기 형식의 음의 무한대( \(-\infty\) )를 나타냅니다. 이 값은 \(- 1.0/0.0\) 으로 표현될 수 있습니다.

GSL_NAN

IEEE 표기 형식의 비정상 값(Not-a-Number; \(NAN\) )을 나타냅니다. \(0.0/0,0\) 로 표현될 수 있습니다.

int gsl_isnan(const double x)

\(x\) 이 비정상 값(NaN)인지 아닌지 판단합니다. 비정상 값으로 판단되면 \(1\) 을 반환합니다.

int gsl_isinf(const double x)

양의 무한이면 \(+1\) 음의 무한이면 \(-1\) 반환합니다. 나머지 경우에 0을 반환합니다 2 .

int gsl_finite(const double x)

\(x\) 실수면 1을, 만약 무한대거나 비정상 값이면 0을 반환합니다.

기초 함수들

다음 명령어 집합들은 BSD 수학 라이브러리의 이식을 기반으로 제공됩니다. 시스템 내장 기능이 없다면 다음의 함수들을 대신 사용할 수 있습니다. 만약, autoconf 를 사용해 프로그램을 컴파일한다면, 자동으로 치환이 일어납니다. 함수의 이식성 을 참고할 수 있습니다.

double gsl_log1p(const double x)

\(\log(1+x)\) 의 값을 계산합니다. 정확도는 작은 \(x\) 값에 대해 보장됩니다. 이는 BSD 수학 함수 log1p(x) 대체 함수입니다.

double gsl_expm1(const double x)

\(\text{exp}(x)-1\) 의 값을 계산합니다. 정확도는 작은 \(x\) 값에 대해 보장됩니다. 이는 BSD 수학 함수 expm1(x) 대체 함수입니다.

double gsl_hypot(const double x, const double y)

\(\sqrt{x^2 + y^2}\) 의 값을 오버 플로우가 일어나지 않도록, 계산합니다. BSD 수학 함수 hypot(x,y) 대체 함수입니다.

double gsl_hypot3(const double x, const double y, const double z)

\(\sqrt{x^2 + y^2+z^2}\) 의 값을 오버 플로우가 일어나지 않도록, 계산합니다.

double gsl_acosh(const double x)

\(\text{arccosh}(x)\) 의 값을 계산합니다. 표준 수학 라이브러리 acosh(x) 대체함수입니다.

double gsl_asinh(const double x)

\(\text{arcsinh}(x)\) 의 값을 계산합니다. 표준 수학 라이브러리 asinh(x) 대체함수입니다.

double gsl_atanh(const double x)

\(\text{arctanh}(x)\) 의 값을 계산합니다. 표준 수학 라이브러리 atanh(x) 대체함수입니다.

double gsl_ldexp(double x, int e)

\(x \cdot 2^e\) 의 값을 계산합니다. 표준 수학 라이브러리 ldexp(x) 대체함수입니다.

double gsl_frexp(double x, int *e)

숫자 \(x\) 정규화 분수 \(f\) 와 지수 \(e\) 로 분리합니다. \(x = f \cdot 2^e\) 으로 쓸 수 있고, \(0.5 <= f < 1\) 입니다. \(f\) 의 값을 반환하고 지수를 \(e\) 에 저장합니다. 만약 \(x\) 가 0이라면, \(f, e\) 모두 0으로 맞추어집니다. 표준 라이브러리 frexp(x,e) 대체함수입니다.

작은 정수 지수들

표준 C 라이브러리를 향한 많은 불만들 중 하나는 작은 정수 지수 계산이 없다는 점입니다. GSL에서는 해당 함수들을 제공해 이를 보완합니다. 효율성을 위해서 오버플로나 언더플로 조건을 계산하지 않습니다.

double gsl_pow_int(double x, int n)
double gsl_pow_uint(double x, unsigned int n)

\(n\) 값에 대해 \(x^n\) 의 값을 계산해줍니다. 이 지수 계산은 효율적으로 설계되었습니다. 예를 들어 \(x^8\) 을 계산하고자 하면, \(((x^2)^2)^2\) 으로 3번의 계산만으로 구할 수 있습니다. 수치적 오류를 함께 계산하는 함수도 라이브러리 내에서 같이 제공합니다. gsl_sf_pow_int_e() 를 사용할 수 있습니다.

double gsl_pow_2(const double x)
double gsl_pow_3(const double x)
double gsl_pow_4(const double x)
double gsl_pow_5(const double x)
double gsl_pow_6(const double x)
double gsl_pow_7(const double x)
double gsl_pow_8(const double x)
double gsl_pow_9(const double x)

작은 정수 지수 \(x^2, x^3, \dots\) 값들을 효율적으로 계산해줍니다. 만약, HAVE_INLINE 가 정의되어 있다면, inline 함수로 작동합니다. 따라서 이러한 함수의 사용이 수식을 그대로 사용하는 만큼이나 효율적일 수 있습니다.

#include<gsl/gsl_math.h>
double =y = gsl_pow_4(3.141) /* compute 3.141**4 */

숫자의 부호 판별

GSL_SIGN(x)

\(x\) 부호를 반환합니다. ((x) >= 0 ? 1: -1) 로 정의되어 있습니다. 유의할 점은 이 구현에서 0은 양수로 반환됩니다. (IEEE 부호 비트와 관계 없습니다.)

숫자의 홀짝 판별

GSL_IS_ODD(n)

만약, \(n\) 이 홀수면 1을, \(n\) 이 짝수면 0을 반환합니다. 인자 \(n\) 는 반드시 정수형이어야 합니다.

GSL_IS_EVEN(n)

GSL_IS_ODD 와 정반대로 작동합니다. 만약, \(n\) 이 홀수면 0을, \(n\) 이 짝수면 1을 반환합니다. 인자 \(n\) 는 반드시 정수형이어야 합니다.

최대, 최소 함수

여기서 서술한 매크로에서는 인수에 대한 여러 가지 평가를 수행하므로 부작용이 있는 인수(예: 난수 생성기에 대한 호출)와 함께 사용하지 않아야 합니다.

GSL_MAX(a, b)

ab 중 최대값을 반환합니다. ((a) > (b) ? (a) : (b)) 로 정의되어 있습니다.

GSL_MIN(a, b)

ab 중 최소값을 반환합니다. ((a) < (b) ? (a) : (b)) 정의되어 있습니다.

extern inline double GSL_MAX_DBL(double a, double b)

배정밀도(double) 자료형 변수 ab 에 대해 인라인 함수를 사용해서 큰 값을 반환합니다. 함수를 사용함으로써 추가적인 안전 기능으로 인자의 형식 검사를 사용할 수 있습니다. 인라인 함수를 지원하지 않는 플랫폼에서는 자동으로 GSL_MAX 으로 대체됩니다.

extern inline double GSL_MIN_DBL(double a, double b)
배정밀도(double) 자료형 변수 ab 에 대해

인라인 함수를 사용해서 작은 값을 반환합니다. 함수를 사용함으로써 추가적인 안전 기능으로 인자의 형식 검사를 사용할 수 있습니다. 인라인 함수를 지원하지 않는 플랫폼에서는 자동으로 GSL_MIN 으로 대체됩니다.

extern inline int GSL_MAX_INT(int a, int b)
extern inline int GSL_MIN_INT(int a, int b)

정수(integer) ab 에 대해 인라인 함수를 사용해서 크거나 작은 값을 반환합니다. 인라인 함수를 지원하지 않는 플랫폼에서는 자동으로 GSL_MIN 으로 대체됩니다.

extern inline long double GSL_MAX_LDBL(long double a, long double b)
extern inline long double GSL_MIN_LDBL(long double a, long double b)

정수(integer) ab 에 대해 인라인 함수를 사용해서 크거나 작은 값을 반환합니다. 인라인 함수를 지원하지 않는 플랫폼에서는 자동으로 GSL_MAXGSL_MIN 으로 대체됩니다.

부동 소수점 숫자의 근사 비교

두 개의 부동소수점 숫자들을 반올림하거나 오차들을 절단해서 근사적으로 비교하는 건 많은 경우에 유용합니다. 다음 함수는 “D.E. Knuth in Section 4.2.2 of “Seminumerical Algorithms” (3rd edition)”의 부동 소수점 근사 비교 알고리즘을 이식한 것입니다.

int gsl_fcmp(double x, double y, double epsilon)

주어진 \(x\)\(y\) 가 근사적으로 상대 정확도 epsilon 만큼 같은지 판별합니다.

상대 정확도는 구간 길이 \(2 \delta\) 로 측정됩니다. \(\delta = 2^k \epsilon\) 으로 정의되고, \(k\)\(frexp()\) 함수에 의해 계산된, \(x\)\(y\) 의 밑이 2인 최대 지수 값입니다.

만약, \(x\)\(y\) 의 차가 이 구간 안에 있다면, 이 둘은 근사적으로 같다고 판정하고 0을 반환합니다. 다른 경우에 만약 \(x<y\) 면 -1을, \(x>y\) 면 1을 반환합니다.

명심할 점은 \(x\)\(y\) 가 상대 정확도와 비교해서 결정된다는 점입니다. 따라서 주어진 값이 근사적으로 0에 가까운지 판정하는 것에는 부적절합니다.

이 구현체는 fcmp 패키지에 기반해 T.C Belding이 구현했습니다.

1

C에서 기본으로 제공하는 표준 헤더파일 중 math.h 를 말합니다(*).

2

C99 표준에서는 isinf() 함수가 무한대의 부호와 관계없이 0이 아닌 값을 반환합니다. GSL 이전 버전의 경우 시스템의 isinf() 함수를 사용했고, 어떤 기기에 따라 동일한 현상이 발생할 수도 있습니다. 따라서, 필요한 경우 \(gsl_isinf()\) 반환값의 부호 보다는 \(x\) 의 부호를 별도로 판정하는 것이 현명합니다.