`cacos`, `cacosf`, `cacosl` — 복소수 아크코사인

cacos, cacosf, cacosl — 복소수 아크코사인

실수 코사인의 역함수 acos는 잘 알지만, 복소수까지 확장하면 이야기가 달라져요. 복소 평면에서 아크코사인은 **다가 함수(multivalued function)**라서 가지 자름(branch cut)이 필요해요. 이 복소 아크코사인을 계산하는 함수가 cacos예요.

출처: cppreference — cacos

본문

cacos 계열 함수는 실수축을 따라 구간 [−1,+1] 바깥에 가지 자름을 두고, 복소수 z의 복소 아크코사인을 계산해요.

float complex       cacosf( float complex z );        // (1)  (since C99)
double complex      cacos( double complex z );        // (2)  (since C99)
long double complex cacosl( long double complex z );  // (3)  (since C99)

// Defined in header <tgmath.h>
#define acos( z )                                     // (4)  (since C99)

1-3) 실수축을 따라 구간 [−1,+1] 바깥에서 가지 자름을 갖는 z의 복소 아크코사인을 계산해요. 4) 타입 제네릭 매크로예요. zlong double complexcacosl, double complexcacos, float complexcacosf가 호출돼요. z가 실수·정수면 대응하는 실수 함수(acosf, acos, acosl)를, 허수면 대응하는 복소수 버전을 호출해요.

매개변수

매개변수 설명
z 복소수 인자

반환값

오류가 없으면 z의 복소 아크코사인을 반환하는데, 그 범위는 허수축 방향으로 무한히 뻗은 띠(strip)이면서 실수축 방향으로는 구간 [0; π] 안쪽이에요.

오류 처리와 특수 값

오류는 math_errhandling에 따라 보고돼요. 구현이 IEEE 부동소수점 산술을 지원한다면 다음 규칙이 적용돼요.

  • cacos(conj(z)) == conj(cacos(z))
  • z±0+0i → 결과는 π/2-0i
  • z±0+NaNi → 결과는 π/2+NaNi
  • zx+∞i(임의의 유한 x) → 결과는 π/2-∞i
  • zx+NaNi(0이 아닌 임의의 유한 x) → 결과는 NaN+NaNi, FE_INVALID 발생 가능
  • z-∞+yi(양의 유한 y) → 결과는 π-∞i
  • z+∞+yi(양의 유한 y) → 결과는 +0-∞i
  • z-∞+∞i → 결과는 3π/4-∞i
  • z+∞+∞i → 결과는 π/4-∞i
  • z±∞+NaNi → 결과는 NaN±∞i(허수부 부호는 명시되지 않음)
  • zNaN+yi(임의의 유한 y) → 결과는 NaN+NaNi, FE_INVALID 발생 가능
  • zNaN+∞i → 결과는 NaN-∞i
  • zNaN+NaNi → 결과는 NaN+NaNi

Notes

역코사인(아크코사인)은 다가 함수라서 복소평면에 가지 자름이 필요해요. 관례적으로 실수축의 선분 (-∞,-1)(1,∞)에 가지 자름을 둬요.

아크코사인의 주값(principal value)의 수학적 정의는 다음과 같아요.

acos z = (π + i·ln(iz + √(1-z²))) / 2

모든 z에 대해 acos(z) = π - acos(-z)가 성립해요.

예시

가지 자름의 양쪽에서 값이 어떻게 달라지는지 확인해 보는 코드예요.

#include <stdio.h>
#include <math.h>
#include <complex.h>

int main(void)
{
    double complex z = cacos(-2);
    printf("cacos(-2+0i) = %f%+fi\n", creal(z), cimag(z));

    double complex z2 = cacos(conj(-2)); // or CMPLX(-2, -0.0)
    printf("cacos(-2-0i) (the other side of the cut) = %f%+fi\n", creal(z2), cimag(z2));

    // for any z, acos(z) = pi - acos(-z)
    double pi = acos(-1);
    double complex z3 = ccos(pi-z2);
    printf("ccos(pi - cacos(-2-0i) = %f%+fi\n", creal(z3), cimag(z3));
}

출력:

cacos(-2+0i) = 3.141593-1.316958i
cacos(-2-0i) (the other side of the cut) = 3.141593+1.316958i
ccos(pi - cacos(-2-0i) = 2.000000+0.000000i

-2+0i-2-0i는 허수부 부호만 다를 뿐인데 아크코사인 결과가 완전히 반대가 돼요. 이것이 가지 자름을 가로지르는 순간 값이 점프한다는 걸 보여주는 예시예요. 그리고 ccos(π - cacos(z))가 다시 원래 값 2로 돌아와 역함수 관계를 확인해 줘요.

표준 참조

  • C11: 7.3.5.1 The cacos functions (p: 190), 7.25 (p: 373-375), G.6.1.1 (p: 539), G.7 (p: 545)
  • C99: 7.3.5.1 (p: 172), 7.22 (p: 335-337), G.6.1.1 (p: 474), G.7 (p: 480)

더 알아보기

  • 복소 아크사인 casin, 복소 아크탄젠트 catan과 함께 역삼각 함수군을 이뤄요.
  • 원함수는 복소 코사인 ccos예요.
  • 실수 아크코사인 acos·acosf·acosl과 비교해 보세요.
  • cppreference의 cacos 원문에서 참조 절을 더 확인할 수 있어요.