Complex — 복소수

Complex — 복소수

실수부와 허수부로 이루어진 복소평면 위의 수를 다뤄야 할 때가 있어요. Complex는 그런 복소수를 나타내는 타입입니다.

출처: Raku 공식 문서 — Complex

본문

class Complex is Cool does Numeric {}

복소평면 위의 수를 나타내요.

Complex 객체는 변경 불가능(immutable)해요.

연산자

postfix i

숫자 리터럴 끝에 i를 붙이면 Complex가 돼요. 예를 들어:

say 2i;     # same as Complex.new(0, 2);
say 1-2e3i; # same as Complex.new(1, -2e3);

메서드

method new

multi method new(Real $re, Real $im --> Complex:D)

실수부와 허수부로 새 Complex 객체를 만들어요.

my $complex = Complex.new(1, 1);
say $complex;    # OUTPUT: «1+1i␤»

인자 없이 만들면 두 부분 모두 0으로 간주해요.

say Complex.new; # OUTPUT: «0+0i␤»

method re

method re(Complex:D: --> Real:D)

복소수의 실수부를 반환해요.

say (3+5i).re;    # OUTPUT: «3␤»

method im

method im(Complex:D: --> Real:D)

복소수의 허수부를 반환해요.

say (3+5i).im;    # OUTPUT: «5␤»

method reals

method reals(Complex:D: --> Positional:D)

이 값의 실수부와 허수부를 담은 두 요소 리스트를 반환해요.

say (3+5i).reals;    # OUTPUT: «(3 5)␤»

method isNaN

method isNaN(Complex:D: --> Bool:D)

실수부나 허수부가 NaN(숫자가 아님)이면 true를 반환해요.

say (NaN+5i).isNaN; # OUTPUT: «True␤»
say (7+5i).isNaN;   # OUTPUT: «False␤»

method polar

method polar(Complex:D: --> Positional:D)

이 값의 극좌표(polar)인 두 요소 리스트, 즉 크기와 라디안 단위 각도를 반환해요.

say (10+7i).polar; # OUTPUT: «(12.2065556157337 0.610725964389209)␤»

method floor

method floor(Complex:D: --> Complex:D)

self.re.floor + self.im.floor를 반환해요. 즉 실수부와 허수부 각각을 그 부분 값보다 크지 않은 가장 큰 정수로 반올림합니다.

say (1.2-3.8i).floor;           # OUTPUT: «1-4i␤»

method ceiling

method ceiling(Complex:D: --> Complex:D)

self.re.ceiling + self.im.ceiling을 반환해요. 즉 실수부와 허수부 각각을 그 부분 값보다 작지 않은 가장 작은 정수로 반올림합니다.

say (1.2-3.8i).ceiling;         # OUTPUT: «2-3i␤»

routine sign

method sign(Complex:D: --> Complex:D)
multi  sign(Complex:D $z --> Complex:D)

복소수의 절댓값이 0이면 0i를 반환해요. 그렇지 않으면 복소수를 그 절댓값으로 나눈 값($z와 같은 방향의 단위 복소수)을 반환합니다.

6.e 언어 버전부터 사용할 수 있어요(Rakudo 컴파일러 2023.02+에 초기 구현이 있어요).

method round

multi method round(Complex:D: --> Complex:D)
multi method round(Complex:D: Real() $scale --> Complex:D)

인자 없이 호출하면 실수부와 허수부를 둘 다 가장 가까운 정수로 반올림하고 새 Complex를 반환해요. $scale이 주어지면 invocant의 두 부분을 $scale의 가장 가까운 배수로 반올림합니다. 각 부분에 Real.round와 같은 알고리즘을 사용해요.

say (1.2-3.8i).round;           # OUTPUT: «1-4i␤»
say (1.256-3.875i).round(0.1);  # OUTPUT: «1.3-3.9i␤»

method truncate

method truncate(Complex:D: --> Complex:D)

Real.truncate를 사용해 수의 실수부와 허수부의 소수 부분을 모두 제거하고, 결과를 새 Complex로 반환해요.

say (1.2-3.8i).truncate;        # OUTPUT: «1-3i␤»

routine abs

method abs(Complex:D: --> Num:D)
multi  abs(Complex:D $z --> Num:D)

invocant(또는 sub 형태에서는 인자)의 절댓값을 반환해요. 복소수 $z의 절댓값 |$z|sqrt($z.re * $z.re + $z.im * $z.im)로 정의됩니다.

say (3+4i).abs;                 # OUTPUT: «5␤»
                                # sqrt(3*3 + 4*4) == 5

method conj

method conj(Complex:D: --> Complex:D)

invocant의 켤레복소수(즉 허수부의 부호를 뒤집은 수)를 반환해요.

say (1-4i).conj;                # OUTPUT: «1+4i␤»

method sqrt

method sqrt(Complex:D: --> Complex:D)

invocant의 복소 제곱근, 즉 실수부가 ≥ 0이고 허수부가 invocant의 허수부와 같은 부호인 근을 반환해요.

say (3-4i).sqrt;                # OUTPUT: «2-1i␤»
say (-3+4i).sqrt;               # OUTPUT: «1+2i␤»

method gist

method gist(Complex:D: --> Str:D)

내부 공백 없이 "1+2i" 형태의 문자열 표현을 반환해요. (Str 강제 변환도 이걸 반환해요.)

say (1-4i).gist;                # OUTPUT: «1-4i␤»

method raku

method raku(Complex:D: --> Str:D)

EVAL에 주었을 때 동등한 객체를 만들어 내는 구현 특화 문자열을 반환해요.

say (1-3i).raku;                # OUTPUT: «<1-3i>␤»

method Real

multi method Real(Complex:D: --> Num:D)
multi method Real(Complex:U: --> Num:D)

invocant를 Num으로 강제 변환해요. 허수부가 대략적으로 0이 아니면 변환이 X::Numeric::Real실패해요.

:D 변형은 그 변환 결과를 반환해요. :U 변형은 초기화되지 않은 값을 숫자 맥락에서 쓴다는 경고를 낸 다음 0e0 값을 반환해요.

sub infix:<**>

multi infix:<**>(Complex:D \a, Complex:D \b --> Complex:D)
multi infix:<**>(Num(Real) \a, Complex:D \b --> Complex:D)
multi infix:<**>(Complex:D \a, Num(Real) \b --> Complex:D)

[지수 연산자]는 두 번째 인자를 Complex로 강제 변환하고, 좌변을 우변만큼 거듭제곱한 값을 계산해요. 6.d부터는 어느 인자든 0이 될 수 있어요.

say i ** i;   # OUTPUT: «0.20787957635076193+0i␤»
say 2 ** i;   # OUTPUT: «0.7692389013639721+0.6389612763136348i␤»
say i ** 2;   # OUTPUT: «-1+1.2246467991473532e-16i␤»
say 0 ** i;   # OUTPUT: «0+0i␤»
say 0i ** 0i; # OUTPUT: «1+0i␤»