복소 사인: csin(C99)

복소 사인: csin(C99)

실수에서 sin을 쓰듯, 복소수도 사인을 구할 수 있어요. 복소 사인은 단순히 실수 사인의 '복소 버전'이 아니라 더 넓은 의미를 가져요. 그 함수가 csin이에요. 복소수면 실수 사인과 똑같이 정의가 확장되는데, 몇 가지 재미있는 성질이 생깁니다.

출처: cppreference

본문

시그니처

<complex.h> 헤더에 정의돼 있어요.

형태 주석
float complex csinf ( float complex z ); (1) C99부터
double complex csin ( double complex z ); (2) C99부터
long double complex csinl ( long double complex z ); (3) C99부터
#define sin(z) (4) C99부터, <tgmath.h>

동작 방식

복소수 z의 사인을 계산해요.

(4)의 sin은 타입 제네릭 매크로예요. zfloat complex, double complex, long double complex면 각각 맞는 버전을 불러요. 그런데 z가 실수나 정수 타입이면 복소 함수 대신 대응하는 실수 함수(sinf, sin, sinl)를 호출해요. 또 z가 허수 타입이면 sinh의 실수 버전을 호출하는데, 이때 공식 sin(iy) = i·sinh(y)를 구현하며 매크로의 반환 타입도 허수 타입이 돼요.

반환값

오류가 없다면 z의 복소 사인을 반환해요. 오류와 특수한 경우는 -I * csinh(I * z)로 구현한 것처럼 처리돼요.

주의할 점

복소 사인은 복소평면 전체에서 **전해석 함수(entire function)**예요. 즉 분지 절단(branch cut)이 하나도 없습니다. 수학적 정의는 아래와 같아요.

sin z = (e^(iz) - e^(-iz)) / (2i)

예제

실수축과 허수축에서 복소 사인이 어떻게 동작하는지 비교해 보는 코드예요.

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

int main(void)
{
    double complex z = csin(1);  // behaves like real sine along the real line
    printf("sin(1+0i) = %f%+fi ( sin(1)=%f)\n", creal(z), cimag(z), sin(1));

    double complex z2 = csin(I); // behaves like sinh along the imaginary line
    printf("sin(0+1i) = %f%+fi (sinh(1)=%f)\n", creal(z2), cimag(z2), sinh(1));
}

출력:

sin(1+0i) = 0.841471+0.000000i ( sin(1)=0.841471)
sin(0+1i) = 0.000000+1.175201i (sinh(1)=1.175201)

두 결과가 대비가 재미있어요. 실수축 위에서는 csin(1)이 실수 sin(1)과 정확히 같고요. 허수축 위에서는 csin(i)가 실수 sinh(1)과 값이 같아져요. 즉 복소 사인은 실수축에서는 사인처럼, 허수축에서는 쌍곡 사인처럼 행동한다는 걸 알 수 있어요.

더 알아보기

  • ccos, ctan: 복소 코사인·복소 탄젠트.
  • casin: 복소 아크사인.
  • sin, sinf, sinl: 실수 사인.
  • csinh: 복소 쌍곡 사인.