복소수

이 단원에서는 복소수를 다루기 위한 기능들을 제공합니다. 구현된 알고리즘들은 중간 과정에서 불필요한 언더플로우나 오버 플로우가 발생하지 않도록 검토함과 동시에, 가능한한 넓은 범위의 복소 평면상에서 값을 계산할 수 있도록 작성되었습니다.

다변수 함수는 Abramowitz & Stegun 1 의 규약을 따라, 분지 절단이 결정됩니다. 이 함수들은 GNU Calc 과 같은 표준 값들을 반환합니다. 이들은 “Common Lisp, The Language (Second Edition)”과 HP-28/48 계산기 시리즈에서 구현된 값들과 같습니다.

복소수 자료형은 헤더 파일 gsl_complex.h 에 선언되어 있고, 대응되는 복소수 함수들은 gsl_complex_math.h 에 정의되어 있습니다.

복소수의 표현

복소수는 gsl_complex 자료형을 통해 표현됩니다. 이 자료형의 내부 표현은 플랫폼에 따라 다양하기 때문에 직접적으로 접근해서는 안됩니다. 아래에 기술된 함수와 매크로들을 이용해 간단하게 복소수들을 제어할 수 있습니다.

gsl_complex 기본적인 형태는 다음 구조체로 정의됩니다.

type gsl_complex
typedef struct
{
        double dat[2];
} gsl_complex;

실수, 허수부는 각각 붙어 있는 배열의 두 원소에 저장됩니다. 이러한 구현은 실수, 허수부 2 사이에 간격이 없어서, 이 구조체를 복소 배열에 직접 대응시킬 수 있습니다.

만약, C 컴파일러가 C11 표준을 지원하고 <complex.h> 헤더파일을 <gsl_complex.h> 보다 먼저 포함했다면, gsl_complex C의 복소수 자료 형으로 다음과 같이 정의됩니다.

typedef double complex gsl_complex

이 방법은 gsl_complex 구조체를 사용자들이 일반 연산으로 취급할 수 있게 해줍니다.

gsl_complex x = 2+ 5*I;
gsl_complex y = x_ (3-4*I);

중요

C에 내장된 복소수 기능들은 C11 표준 이후에 지원되기 시작했습니다. <complex.h>gsl_complex.h 보다 먼저 포함되었다면, GSL 라이브러리에서는 C11의 새 기능들을 이용해 GSL_REALGSL_IMAG 를 정의합니다. C99 표준에서 이러한 기능들을 정의할 수 있는 적절한 기능은 없습니다. 따라서 C99 컴파일러에서는 gsl_complex 가 C에 내장된 복소수 기능들로 정의되지 않습니다.

gcc 4.8 계열 컴파일러와 같이 몇몇 컴파일러들은 C11의 일부 기능만을 지원하는 경우도 있습니다. 이러한 컴파일러들에서는 사용자가 C의 내장 복소수 기능들을 활성화 시켜 GSL을 컴파일 할 수 없습니다. 이러한 경우 포함하는 헤더 파일 목록에서 complex.h 를 제거하거나, 컴파일러에 -DGSL_COMPLEX_LEGACY 를 넣어서 구조체에 기반해 정의된 gsl_complex 를 사용하도록 해야합니다.

복소수 매크로

다음의 C 매크로들은 복소수를 편하게 조작할 수 있게 해줍니다.

GSL_REAL(z)
GSL_IMAG(z)

이 두 매크로는 각각 복소수 z 실수, 허수부의 메모리 위치 를 반환합니다. 이 매크로를 이용해서 일반적인 연산을 복소수에 대해, 사용할 수 있습니다.

gsl_complex x, y;

GSL_REAL(x) = 4;
GSL_IMAG(x) = 2;

GSL_REAL(y) = GSL_REAL(x);
GSL_IMAG(y) = GSL_REAL(x);

다시 말해, 이 매크로를 이용해서 복소수의 실수, 허수부를 읽고, 쓸 수 있습니다.

GSL_SET_COMPLEX(zp, x, y)

데카르트 좌표 성분 ( x, y )을 포인터 zp 가 가르키는 복소수의 실수, 허수부에 저장합니다. 예를 들어서,

GSL_SET_COMPLEX(&z, 3, 4)

\(z\)\(3 + 4i\) 로 초기화 합니다.

복소수 할당

gsl_complex gsl_complex_react(double x, double y)

직교 데카르트 좌표계 \((x,y)\) 를 이용해 \(z = x + iy\) 복소수를 반환합니다. HAVE_INLINE 을 정의하면, 인라인 형태의 함수를 사용할 수 있습니다.

gsl_complex gsl_complex_polar(double r, double theta)

극좌표 방식의 복소수 \(z = r \text{exp}(i \theta) = r (\cos (\theta) + i \sin (\theta))\) 를 주어진 ( r theta 에 대해 반환합니다.

복소수의 성질

double gsl_complex_arg(gsl_complex z)

주어진 복소수 z 편각 \(\text{arg}(z)\) 을 반환합니다. 편각 \(\text{arg}(z)\) 는, \(-\pi \leq \text{arg}(z) \leq \pi\) 의 범주를 가집니다.

double gsl_complex_abs(gsl_complex z)

주어진 복소수 z 크기, \(|z|\) 의 값을 반환합니다.

double gsl_complex_abs2(gsl_complex z)

주어진 복소수 z 크기의 제곱 \(|z|^2\) 를 반환합니다.

double gsl_complex_logabs(gsl_complex z)

주어진 복소수 z 크기에 대한 자연로그 값 \(\log(|z|)\) 을 반환합니다. \(|z|\) 의 값이 \(1\) 에 가까울 때, 정확한 값을 얻을 수 있습니다. 직접 log(gsl_complexabs(z)) 계산하는 경우 정확도를 잃을 수 있습니다.

복소수 연산자

gsl_complex gsl_complex_add(gsl_complex a, gsl_complex b)

주어진 두 복소수 a b 합, \(z=a+b\) 를 반환합니다.

gsl_complex gsl_complex_sub(gsl_complex a, gsl_complex b)

주어진 두 복소수 a b 차, \(z = a-b\) 를 반환합니다.

gsl_complex gsl_complex_mul(gsl_complex a, gsl_complex b)

주어진 두 복소수 a b 곱, \(z = a \cdot b\) 를 반환합니다.

gsl_complex gsl_complex_div(gsl_complex a, gsl_complex b)

주어진 두 복소수 a b 나눗셈, \(z = a/ b\) 를 반환합니다.

gsl_complex gsl_complex_add_real(gsl_complex a, double x)

주어진 복소수 a 실수 x 합, \(z = a + x\) 를 반환합니다.

gsl_complex gsl_complex_sub_real(gsl_complex a, double x)

주어진 복소수 a 실수 x 차, \(z = a - x\) 를 반환합니다.

gsl_complex gsl_complex_mul_real(gsl_complex a, double x)

주어진 복소수 a 실수 x 곱, \(z = a \cdot x\) 를 반환합니다.

gsl_complex gsl_complex_div_real(gsl_complex a, double x)

주어진 복소수 a 실수 x 나눗셈, \(z = a / x\) 를 반환합니다.

gsl_complex gsl_complex_add_imag(gsl_complex a, double y)

주어진 복소수 a 허수 y 합, \(z = a + y\) 를 반환합니다.

gsl_complex gsl_complex_sub_imag(gsl_complex a, double y)

주어진 복소수 a 허수 y 차, \(z = a - y\) 를 반환합니다.

gsl_complex gsl_complex_mul_imag(gsl_complex a, double y)

주어진 복소수 a 허수 y 곱, \(z = a \cdot y\) 를 반환합니다.

gsl_complex gsl_complex_div_imag(gsl_complex a, double y)

주어진 복소수 a 허수 y 나눗셈, \(z = a / y\) 를 반환합니다.

gsl_complex gsl_complex_conjugate(gsl_complex z)

주어진 복소수 z 컬레 복소수, \(z^* = x - iy\) 를 반환합니다.

gsl_complex gsl_complex_inverse(gsl_complex z)

주어진 복소수 z 역수, \(\frac{1}{z} = \frac{x - iy}{x^2 + y^2}\) 를 반환합니다.

gsl_complex gsl_complex_negative(gsl_complex z)

주어진 복소수 z 덧셈 역원, \(-z = (-x) + i (-y)\) 를 반환합니다.

기초 복소 함수들

gsl_complex gsl_complex_sqrt(gsl_complex z)

주어진 복소수 z 제곱근, \(\sqrt{z}\) 의 값을 반환합니다. 분지 절단은 음의 실수축 에서 이루어집니다. 결과는 항상 복소 평면의 오른쪽 절반 영역에 위치합니다.

gsl_complex gsl_complex_sqrt_real(double x)

주어진 실수 x 복소수 제곱근을 반환합니다. x 음수일 수 있습니다.

gsl_complex gsl_complex_pow(gsl_complex z, gsl_complex a)

주어진 복소수 z a 대해, \(z^a\) 값을 반환합니다. 이 값은 복소수 로그와 지수 함수를 이용해 계산됩니다. \(\text{exp}(\log (z) \cdot a))\)

gsl_complex gsl_complex_pow_real(gsl_complex z, double x)

주어진 복소수 z 대해 주어진 실수 x 승, \(z^x\) 값을 반환합니다.

gsl_complex gsl_complex_exp(gsl_complex z)

주어진 복소수 z 지수 값, \(\text{exp}(z)\) 를 반환합니다.

gsl_complex gsl_complex_log(gsl_complex z)

주어진 복소수 z 복소수 자연 로그(밑이 \(e\) 인) 값, \(\log (z)\) 를 반환합니다. 분지 절단은 음의 실수축에서 이루어집니다.

gsl_complex gsl_complex_log10(gsl_complex z)

주어진 복소수 z 대해, \(10\) 을 밑으로 가지는 로그값, \(\log_10 (z)\) 값을 반환합니다.

gsl_complex gsl_complex_log_b(gsl_complex z, gsl_complex b)

주어진 복소수 z b 대해, b 밑으로 하는 로그에 대한 z , \(\log_b (z)\) 의 값을 반환 합니다. 이 값은 \(\frac{\log(z)}{\log(b)}\) 를 반환합니다.

복소 삼각 함수

gsl_complex gsl_complex_sin(gsl_complex z)

주어진 복소수 z sine 값, \(\sin (z) = \frac{(\text{exp}(iz) - \text{exp}(-iz))}{2i}\) 을 반환합니다.

gsl_complex gsl_complex_cos(gsl_complex z)

주어진 복소수 z cosine 값, \(\cos (z) = \frac{(\text{exp}(iz) + \text{exp}(-iz))}{2}\) 을 반환합니다.

gsl_complex gsl_complex_tan(gsl_complex z)

주어진 복소수 z tangent 값, \(\text{tan} (z) = \frac{\sin (z)}{\cos (z)}\) 을 반환합니다.

gsl_complex gsl_complex_sec(gsl_complex z)

주어진 복소수 z secant 값, \(\text{sec} (z) = \frac{1}{\cos (z)}\) 을 반환합니다.

gsl_complex gsl_complex_csc(gsl_complex z)

주어진 복소수 z 복소수 cosecant 값, \(\text{csc} (z) = \frac{1}{\sin (z)}\) 을 반환합니다.

gsl_complex gsl_complex_cot(gsl_complex z)

주어진 복소수 z cotangent 값, \(\text{cot} (z) = \frac{1}{\text{tan}(z)}\) 을 반환합니다.

복소 역삼각 함수

gsl_complex gsl_complex_arcsin_real(double z)

주어진 복소수 z arcsine 값, \(\text{arcsin}(z)\) 을 반환합니다. 분지 절단은 실수 축 위에서 이루어지며, \(1\) 보다 크거나 \(-1\) 보다 작은 지점으로 이루어집니다.

gsl_complex gsl_complex_arcsin(gsl_complex z)

주어진 실수 z arcsine 값, \(\text{arcsin}(z)\) 의 값을 반환합니다. \(z\) 값이 \(-1\)\(1\) 사이에 있을 때, \([- \frac{\pi}{2}, \frac{\pi}{2}]\) 사이의 값을 반환합니다. \(z\) 값이 \(-1\) 보다 작은 경우 반환 값은 실수부가 \(- \frac{\pi}{2}\) 이고 양의 허수부를 가집니다. \(z\)\(1\) 보다 큰 경우 반환값은 \(\frac{\pi}{2}\) 의 실수부와 음의 허수부를 가집니다.

gsl_complex gsl_complex_arccos(gsl_complex z)

주어진 복소수 z arccosine 값 \(\text{arccos}(z)\) 의 값을 반환합니다. 분지 절단은 실수축 위에서 이루어지며, \(1\) 보다 크거나 \(-1\) 보다 작은 지점으로 이루어집니다.

gsl_complex gsl_complex_arccos_real(double z)

주어진 실수 z arccosine 값, \(\text{arcsin}(z)\) 의 값을 반환합니다. \(z\) 값이 \(-1\)\(1\) 사이에 있을 때, \([0, \pi]\) 사이의 값을 반환합니다. \(z\) 값이 \(-1\) 보다 작은 경우 반환 값은 실수부가 \(\pi\) 이고 음의 허수부를 가집니다. \(z\)\(1\) 보다 큰 경우 반환값은 순허수 형태를 가집니다.

gsl_complex gsl_complex_arctan(gsl_complex z)

주어진 복소수 z arctan 값, \(\text{arctan}(z)\) 을 반환합니다. 분지 절단은 허수 축 위에서 이루어지며, \(i\) 보다 크거나 \(-i\) 보다 작은 지점으로 이루어집니다.

gsl_complex gsl_complex_arcsec(gsl_complex z)

주어진 복소수 z arcsec 값, \(\text{arcsec}(z) = \text{arccos}(\frac{1}{z})\) 을 반환합니다.

gsl_complex gsl_complex_arcsec_real(double z)

주어진 실수 z arcsec 값, \(\text{arcsec}(z) = \text{arccos}(\frac{1}{z})\) 을 반환합니다.

gsl_complex gsl_complex_arccsc(gsl_complex z)

주어진 복소수 z arccsc 값, \(\text{arccsc}(z) = \text{arcsin}(\frac{1}{z})\) 을 반환합니다.

gsl_complex gsl_complex_arccsc_real_real(double z)

주어진 실수 z arccsc 값, \(\text{arccsc}(z) = \text{arcsin}(\frac{1}{z})\) 을 반환합니다.

gsl_complex gsl_complex_arccot(gsl_complex z)

주어진 복소수 z arccot 값, \(\text{arccot}(z) = \text{arctan}(\frac{1}{z})\) 을 반환합니다.

복소 쌍곡 함수

gsl_complex gsl_complex_sinh(gsl_complex z)

주어진 복소수 z sinh 값, \(\text{sinh}(z) = \frac{e^z - e^{-z}}{2}\) 을 반환합니다.

gsl_complex gsl_complex_cosh(gsl_complex z)

주어진 복소수 z cosh 값, \(\text{cosh}(z) = \frac{e^z + e^{-z}}{2}\) 을 반환합니다.

gsl_complex gsl_complex_tanh(gsl_complex z)

주어진 복소수 z tanh 값, \(\text{tanh}(z) = \frac{\text{sinh}(z)}{\text{cosh}(z)}\) 을 반환합니다.

gsl_complex gsl_complex_sech(gsl_complex z)

주어진 복소수 z sech 값, \(\text{sech}(z) = \frac{1}{\text{sinh}(z)}\) 을 반환합니다.

gsl_complex gsl_complex_csch(gsl_complex z)

주어진 복소수 z csch 값, \(\text{csch}(z) = \frac{1}{\text{cosh}(z)}\) 을 반환합니다.

gsl_complex gsl_complex_coth(gsl_complex z)

주어진 복소수 z coth 값, \(\text{coth}(z) = \frac{\text{cosh}(z)}{\text{sinh}(z)}\) 을 반환합니다.

복소 역쌍곡 함수

gsl_complex gsl_complex_arcsinh(gsl_complex z)

주어진 복소수 z arcsinh 값, \(\text{arcsinh}(z)\) 를 반환합니다. 분지 절단은 허수축 위에서 이루어지며, \(-i\) 밑 그리고 \(i\) 위 입니다.

gsl_complex gsl_complex_arccosh(gsl_complex z)

주어진 복소수 z arccosh 값, \(\text{arccosh}(z)\) 를 반환합니다. 분지 절단은 실수축 위에서 이루어지며, \(-1\) 밑입니다. 한가지 알아두어야 할 점은 Abramowitz & Stegun의 4.6.21식에 있는 음수 근을 사용한다는 점입니다. 해당식은 \(\text{arccosh}(z) = \log(z- \sqrt{z^2 -1})\) 입니다.

gsl_complex gsl_complex_arccosh_real(double z)

주어진 실수 z 대해, arccosh 값, \(\text{arccosh}(z)\) 를 반환합니다.

gsl_complex gsl_complex_arctanh(gsl_complex z)

주어진 복소수 z arctanh 값, \(\text{arctanh}(z)\) 를 반환합니다. 분지 절단은 실수축 위에서 이루어지며, \(-1\) 밑 그리고 \(1\) 위 입니다.

gsl_complex gsl_complex_arctanh_real(double z)

주어진 실수 z 대해, arctanh 값, \(\text{arctanh}(z)\) 를 반환합니다.

gsl_complex gsl_complex_arcsech(gsl_complex z)

복소수 z 대해, arcsech 값 \(\text{arcsech}(z) = \text{arccosh}(\frac{1}{z})\) 값을 반환합니다.

gsl_complex gsl_complex_arccsch(gsl_complex z)

복소수 z 대해, arccsch 값 \(\text{arccsch}(z) = \text{arcsinh}(\frac{1}{z})\) 값을 반환합니다.

gsl_complex gsl_complex_arccoth(gsl_complex z)

복소수 z 대해, arccoth 값 \(\text{arccoth}(z) = \text{arctanh}(\frac{1}{z})\) 값을 반환합니다.

참고 문헌과 추가 자료

기초 함수들과 삼각 함수들의 구현체들은 다음의 논문에 기반해 만들어졌습니다.

  • T. E. Hull, Thomas F. Fairgrieve, Ping Tak Peter Tang, “Implementing Complex Elementary Functions Using Exception Handling”, ACM Transactions on Mathematical Software, Volume 20 (1994), pp 215-244, Corrigenda, p553

  • T. E. Hull, Thomas F. Fairgrieve, Ping Tak Peter Tang, “Implementing the complex arcsin and arccosine functions using exception handling”, ACM Transactions on Mathematical Software, Volume 23 (1997) pp 299-335

일반 식들과 분지점은 다음의 책들을 참고할 수 있습니다.

  • Abramowitz & Stegun, Handbook of Mathematical Functions, “Circular Functions in Terms of Real and Imaginary Parts”, Formulas 4.3.55-58, “Inverse Circular Functions in Terms of Real and Imaginary Parts”, Formulas 4.4.37-39, “Hyperbolic Functions in Terms of Real and Imaginary Parts”, Formulas 4.5.49-52, “Inverse Hyperbolic Functions—relation to Inverse Circular Functions”, Formulas 4.6.14-19.

  • Dave Gillespie, Calc Manual, Free Software Foundation, ISBN 1-882114-18-3

각주

1

미국 표준 기술 연구소에서 Milton Abramowitz와 Irene Stegun이 편집한 수학 문헌으로 수식, 그래프 및 수학표를 포함하는 수학 함수 핸드북입니다(*).

2

dat[0] dat[1]