Complex 클래스

Complex 클래스

Complex 객체는 값 한 쌍을 담아요. 객체를 만들 때 직교 좌표(rectangular coordinates) 또는 극좌표(polar coordinates) 중 하나로 값을 줘요. 복소수를 다뤄 본 적이 없다면, 실수부와 허수부로 이루어진 수라고 생각하면 돼요.

출처: Ruby 4.0 API

본문

Complex 객체는 값 한 쌍을 담는데, 만들 때 직교 좌표 또는 극좌표로 값을 줘요.

직교 좌표

복소수의 직교 좌표는 *실수부(real)*와 *허수부(imaginary)*라고 불러요. 직교 좌표로 Complex 객체를 만들 수 있는 방법이 여러 개예요:

  • 복소수 리터럴.
  • Complex.rect 메서드.
  • Kernel#Complex 메서드(숫자 인자 또는 특정 문자열 인자 사용).
  • String#to_c 메서드(특정 문자열에 대해).

저장된 각 부분은 Complex, Float, Integer, Rational 클래스 중 하나의 인스턴스일 수 있어요. 각 부분은 다음과 같이 가져올 수 있어요:

  • 각각 따로: Complex#realComplex#imaginary.
  • 함께: Complex#rect.

이에 대응하는 (계산된) 극좌표 값은 다음과 같이 가져올 수 있어요:

  • 각각 따로: Complex#absComplex#arg.
  • 함께: Complex#polar.

극좌표

복소수의 극좌표는 *절댓값(absolute)*과 편각(argument) 부분이라고 불러요. 이 클래스에서 편각 부분은 라디안(도가 아니라)으로 표현돼요.

극좌표로 Complex 객체를 만들 수 있는 방법이 여러 개예요:

  • Complex.polar 메서드.
  • Kernel#Complex 메서드(특정 문자열 인자 사용).
  • String#to_c 메서드(특정 문자열에 대해).

저장된 각 부분은 Complex, Float, Integer, Rational 클래스 중 하나의 인스턴스일 수 있어요. 각 부분은 다음과 같이 가져올 수 있어요:

  • 각각 따로: Complex#absComplex#arg.
  • 함께: Complex#polar.

이에 대응하는 (계산된) 직교 좌표 값은 다음과 같이 가져올 수 있어요:

  • 각각 따로: Complex#realComplex#imag.
  • 함께: Complex#rect.

여기 있는 것들

먼저, 여기 아닌 곳에 있는 것:

  • Complex 클래스는 NumericObject 클래스에서 (직간접적으로) 상속받아요.
  • Comparable 모듈을 (간접적으로) 포함해요.

여기 Complex 클래스에는 다음과 같은 메서드들이 있어요:

Complex 객체 만들기

  • ::polar: 주어진 극좌표를 기반으로 새 Complex 객체를 돌려줘요.
  • ::rect(별칭 ::rectangular): 주어진 직교 좌표를 기반으로 새 Complex 객체를 돌려줘요.

조회

  • abs(별칭 magnitude): self의 절댓값을 돌려줘요.
  • arg(별칭 angle, phase): self의 편각(각도)을 라디안으로 돌려줘요.
  • denominator: self의 분모를 돌려줘요.
  • finite?: self.realself.image가 모두 유한한지 돌려줘요.
  • hash: self의 정수 해시 값을 돌려줘요.
  • imag(별칭 imaginary): self의 허수 값을 돌려줘요.
  • infinite?: self.real 또는 self.image가 무한한지 돌려줘요.
  • numerator: self의 분자를 돌려줘요.
  • polar: 배열 [self.abs, self.arg]를 돌려줘요.
  • inspect: self의 문자열 표현을 돌려줘요.
  • real: self의 실수 값을 돌려줘요.
  • real?: false를 돌려줘요. Numeric#real?과의 호환용이에요.
  • rect(별칭 rectangular): 배열 [self.real, self.imag]를 돌려줘요.

비교

  • <=>: self가 주어진 인자보다 작은지, 같은지, 큰지 돌려줘요.
  • ==: self가 주어진 인자와 같은지 돌려줘요.

변환

  • rationalize: self.real의 값과 정확히 또는 근사적으로 같은 Rational 객체를 돌려줘요.
  • to_c: self를 돌려줘요.
  • to_d: 값을 BigDecimal 객체로 돌려줘요.
  • to_f: 가능하면 self.real의 값을 Float로 돌려줘요.
  • to_i: 가능하면 self.real의 값을 Integer로 돌려줘요.
  • to_r: 가능하면 self.real의 값을 Rational로 돌려줘요.
  • to_s: self의 문자열 표현을 돌려줘요.

Complex 산술 연산

  • *: self와 주어진 숫자의 곱을 돌려줘요.
  • **: self를 주어진 숫자의 거듭제곱으로 올린 값을 돌려줘요.
  • +: self와 주어진 숫자의 합을 돌려줘요.
  • -: self와 주어진 숫자의 차를 돌려줘요.
  • -@: self의 부정(negation)을 돌려줘요.
  • /: self와 주어진 숫자의 몫을 돌려줘요.
  • abs2: self의 절댓값(크기)의 제곱을 돌려줘요.
  • conj(별칭 conjugate): self의 켤레복소수를 돌려줘요.
  • fdiv: Complex.rect(self.real/numeric, self.imag/numeric)을 돌려줘요.

JSON 작업

  • ::json_create: 주어진 직렬화된 해시에서 역직렬화한 새 Complex 객체를 돌려줘요.
  • as_json: self로부터 만든 직렬화된 해시를 돌려줘요.
  • to_json: self를 나타내는 JSON 문자열을 돌려줘요.

이 메서드들은 JSON 젬이 제공해요. 사용하려면:

require 'json/add/complex'

상수

I

Complex.rect(0, 1) 과 같아요:

Complex::I # => (0+1i)

Class Methods

json_create(object)

as_json을 보세요. 직렬화된 해시에서 Complex 객체를 역직렬화해 돌려줘요.

# File ext/json/lib/json/add/complex.rb, line 9
def self.json_create(object)
  Complex(object['r'], object['i'])
end

polar(abs, arg = 0) → complex

주어진 인자들로 만든 새 Complex 객체를 돌려줘요. 각 인자는 Numeric 인스턴스이거나 그 서브클래스(Complex, Float, Integer, Rational)의 인스턴스여야 해요. 인자 arg는 라디안으로 주어져요:

Complex.polar(3)        # => (3+0i)
Complex.polar(3, 2.0)   # => (-1.2484405096414273+2.727892280477045i)
Complex.polar(-3, -2.0) # => (1.2484405096414273+2.727892280477045i)

rect(real, imag = 0) → complex

주어진 인자들로 만든 새 Complex 객체를 돌려줘요. 각 인자는 Numeric 인스턴스이거나 그 서브클래스(Complex, Float, Integer, Rational)의 인스턴스여야 해요:

Complex.rect(3)             # => (3+0i)
Complex.rect(3, Math::PI)   # => (3+3.141592653589793i)
Complex.rect(-3, -Math::PI) # => (-3-3.141592653589793i)

Complex.rectangularComplex.rect 의 별칭이에요.

Public Instance Methods

self * other → numeric

selfother의 숫자 곱을 돌려줘요:

Complex.rect(9, 8)  * 4                   # => (36+32i)
Complex.rect(20, 9) * 9.8                 # => (196.0+88.2i)
Complex.rect(2, 3)  * Complex.rect(2, 3)  # => (-5+12i)
Complex.rect(900)   * Complex.rect(1)     # => (900+0i)
Complex.rect(-2, 9) * Complex.rect(-9, 2) # => (0-85i)
Complex.rect(9, 8)  * Rational(2, 3)      # => ((6/1)+(16/3)*i)

self ** exponent → complex

selfexponent 거듭제곱으로 올린 값을 돌려줘요:

Complex.rect(0, 1) ** 2            # => (-1+0i)
Complex.rect(-8) ** Rational(1, 3) # => (1.0000000000000002+1.7320508075688772i)

self + other → numeric

selfother의 합을 돌려줘요:

Complex(1, 2) + 0  # => (1+2i)
Complex(1, 2) + 1  # => (2+2i)
Complex(1, 2) + -1 # => (0+2i)

Complex(1, 2) + 1.0  # => (2.0+2i)

Complex(1, 2) + Complex(2, 1)     # => (3+3i)
Complex(1, 2) + Complex(2.0, 1.0) # => (3.0+3.0i)

Complex(1, 2) + Rational(1, 1) # => ((2/1)+2i)
Complex(1, 2) + Rational(1, 2) # => ((3/2)+2i)

Float가 얽힌 계산에서는 결과가 부정확할 수 있어요(Float#+ 참고):

Complex(1, 2) + 3.14 # => (4.140000000000001+2i)

self - other → complex

selfother의 차를 돌려줘요:

Complex.rect(2, 3)  - Complex.rect(2, 3)  # => (0+0i)
Complex.rect(900)   - Complex.rect(1)     # => (899+0i)
Complex.rect(-2, 9) - Complex.rect(-9, 2) # => (7+7i)
Complex.rect(9, 8)  - 4                   # => (5+8i)
Complex.rect(20, 9) - 9.8                 # => (10.2+9i)

-self → complex

self에 부호를 붙인 값을 돌려줘요.즉 각 부분의 부정이에요:

-Complex.rect(1, 2)   # => (-1-2i)
-Complex.rect(-1, -2) # => (1+2i)

self / other → complex

selfother의 몫을 돌려줘요:

Complex.rect(2, 3)  / Complex.rect(2, 3)  # => (1+0i)
Complex.rect(900)   / Complex.rect(1)     # => (900+0i)
Complex.rect(-2, 9) / Complex.rect(-9, 2) # => ((36/85)-(77/85)*i)
Complex.rect(9, 8)  / 4                   # => ((9/4)+2i)
Complex.rect(20, 9) / 9.8                 # => (2.0408163265306123+0.9183673469387754i)

self <=> other → -1, 0, 1, or nil

selfother를 비교해요.

반환:

  • 다음 두 조건이 모두 참이면 self.real <=> other.real:
    • self.imag == 0.
    • other.imag == 0(other가 숫자이면서 복소수가 아니면 항상 참).
  • 그 외에는 nil.

예시:

Complex.rect(2) <=> 3                  # => -1
Complex.rect(2) <=> 2                  # => 0
Complex.rect(2) <=> 1                  # => 1
Complex.rect(2, 1) <=> 1               # => nil # self.imag not zero.
Complex.rect(1) <=> Complex.rect(1, 1) # => nil # object.imag not zero.
Complex.rect(1) <=> 'Foo'              # => nil # object.imag not defined.

Complex 클래스는 Comparable 모듈을 포함하며, 그 메서드들은 모두 Complex#<=>를 비교에 사용해요.

complex == object → true or false

self.real == object.real 이고 self.imag == object.imag 이면 true를 돌려줘요:

Complex.rect(2, 3)  == Complex.rect(2.0, 3.0) # => true

abs → float

self의 절댓값(크기)을 돌려줘요:

Complex.polar(-1, 0).abs # => 1.0

self를 직교 좌표로 만들었다면 반환 값이 계산되며 부정확할 수 있어요:

Complex.rectangular(1, 1).abs # => 1.4142135623730951 # The square root of 2.

magnitude의 별칭이기도 해요.

abs2 → float

self의 절댓값(크기)의 제곱을 돌려줘요:

Complex.polar(2, 2).abs2 # => 4.0

self를 직교 좌표로 만들었다면 반환 값이 계산되며 부정확할 수 있어요:

Complex.rectangular(1.0/3, 1.0/3).abs2 # => 0.2222222222222222

arg → float

self의 편각(각도)을 라디안으로 돌려줘요:

Complex.polar(3, Math::PI/2).arg  # => 1.57079632679489660

self를 직교 좌표로 만들었다면 반환 값이 계산되며 부정확할 수 있어요:

Complex.polar(1, 1.0/3).arg # => 0.33333333333333326

angle, phase 의 별칭이기도 해요.

as_json(*)

Complex#as_jsonComplex.json_create 메서드로 Complex 객체를 직렬화·역직렬화할 수 있어요. Marshal 문서도 함께 보세요.

Complex#as_jsonself를 직렬화해 self를 나타내는 2-요소 해시를 돌려줘요:

require 'json/add/complex'
x = Complex(2).as_json      # => {"json_class"=>"Complex", "r"=>2, "i"=>0}
y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, "i"=>4}

JSON.create 메서드는 그런 해시를 역직렬화해 Complex 객체를 돌려줘요:

Complex.json_create(x) # => (2+0i)
Complex.json_create(y) # => (2.0+4i)

conj → complex

self의 켤레복소수 Complex.rect(self.imag, self.real)을 돌려줘요:

Complex.rect(1, 2).conj # => (1-2i)

conjugate의 별칭이에요.

conjugate

self의 켤레복소수를 돌려줘요. conj 의 별칭이기도 해요.

denominator → integer

self의 분모를 돌려줘요. self.real.denominatorself.imag.denominator 의 최소공배수예요:

Complex.rect(Rational(1, 2), Rational(2, 3)).denominator # => 6

비-유리수 숫자의 n.denominator1 이라는 점에 주의하세요. 관련: Complex#numerator.

fdiv(numeric) → new_complex

Complex.rect(self.real/numeric, self.imag/numeric) 을 돌려줘요:

Complex.rect(11, 22).fdiv(3) # => (3.6666666666666665+7.333333333333333i)

finite? → true or false

self.real.finite?self.imag.finite? 가 모두 truetrue, 그 외에는 false를 돌려줘요:

Complex.rect(1, 1).finite?               # => true
Complex.rect(Float::INFINITY, 0).finite? # => false

관련: Numeric#finite?, Float#finite?.

hash → integer

self의 정수 해시 값을 돌려줘요. 같은 값으로 만든 두 Complex 객체는 같은 해시 값을 가져요(eql?로도 비교돼요):

Complex.rect(1, 2).hash == Complex.rect(1, 2).hash # => true

imag → numeric

self의 허수 값을 돌려줘요:

Complex.rect(7).imag     # => 0
Complex.rect(9, -4).imag # => -4

self를 극좌표로 만들었다면 반환 값이 계산되며 부정확할 수 있어요:

Complex.polar(1, Math::PI/4).imag # => 0.7071067811865476 # Square root of 2.

imaginary 의 별칭이에요.

imaginary

self의 허수 값을 돌려줘요. imag 의 별칭이기도 해요.

infinite? → 1 or nil

self.real.infinite? 또는 self.imag.infinite? 중 하나가 true1을, 그 외에는 nil을 돌려줘요:

Complex.rect(Float::INFINITY, 0).infinite? # => 1
Complex.rect(1, 1).infinite?               # => nil

관련: Numeric#infinite?, Float#infinite?.

inspect → string

self의 문자열 표현을 돌려줘요:

Complex.rect(2).inspect                      # => "(2+0i)"
Complex.rect(-8, 6).inspect                  # => "(-8+6i)"
Complex.rect(0, Rational(1, 2)).inspect      # => "(0+(1/2)*i)"
Complex.rect(0, Float::INFINITY).inspect     # => "(0+Infinity*i)"
Complex.rect(Float::NAN, Float::NAN).inspect # => "(NaN+NaN*i)"

magnitude

abs 의 별칭이에요.

numerator → new_complex

self의 실수부와 허수부를 둘의 최소공통분모로 변환한 뒤, 각 부분의 분자로 만든 Complex 객체를 돌려줘요:

c = Complex.rect(Rational(2, 3), Rational(3, 4)) # => ((2/3)+(3/4)*i)
c.numerator                                      # => (8+9i)

이 예시에서 두 부분의 최소공통분모는 12예요. 변환된 두 부분을 Rational(8, 12), Rational(9, 12)로 생각할 수 있는데, 그 분자는 각각 8과 9예요. 그래서 c.numerator 의 반환 값은 Complex.rect(8, 9) 가 돼요.

관련: Complex#denominator.

phase

arg 의 별칭이에요.

polar → array

배열 [self.abs, self.arg] 를 돌려줘요:

Complex.polar(1, 2).polar # => [1.0, 2.0]

self를 직교 좌표로 만들었다면 반환 값이 계산되며 부정확할 수 있어요:

Complex.rect(1, 1).polar # => [1.4142135623730951, 0.7853981633974483]

rationalize(epsilon = nil) → rational

self.real 의 값과 정확히 또는 근사적으로 같은 Rational 객체를 돌려줘요.

epsilon 인자 없이 호출하면 self.real.rationalize 와 정확히 같은 값을 가진 Rational 객체를 돌려줘요:

Complex.rect(1, 0).rationalize              # => (1/1)
Complex.rect(1, Rational(0, 1)).rationalize # => (1/1)
Complex.rect(3.14159, 0).rationalize        # => (314159/100000)

epsilon 인자를 주면 주어진 정밀도까지 self.real 과 정확히 또는 근사적으로 같은 값을 가진 Rational 객체를 돌려줘요:

Complex.rect(3.14159, 0).rationalize(0.1)          # => (16/5)
Complex.rect(3.14159, 0).rationalize(0.01)         # => (22/7)
Complex.rect(3.14159, 0).rationalize(0.001)        # => (201/64)
Complex.rect(3.14159, 0).rationalize(0.0001)       # => (333/106)
Complex.rect(3.14159, 0).rationalize(0.00001)      # => (355/113)
Complex.rect(3.14159, 0).rationalize(0.000001)     # => (7433/2366)
Complex.rect(3.14159, 0).rationalize(0.0000001)    # => (9208/2931)
Complex.rect(3.14159, 0).rationalize(0.00000001)   # => (47460/15107)
Complex.rect(3.14159, 0).rationalize(0.000000001)  # => (76149/24239)
Complex.rect(3.14159, 0).rationalize(0.0000000001) # => (314159/100000)
Complex.rect(3.14159, 0).rationalize(0.0)          # => (3537115888337719/1125899906842624)

관련: Complex#to_r.

real → numeric

self의 실수 값을 돌려줘요:

Complex.rect(7).real     # => 7
Complex.rect(9, -4).real # => 9

self를 극좌표로 만들었다면 반환 값이 계산되며 부정확할 수 있어요:

Complex.polar(1, Math::PI/4).real # => 0.7071067811865476 # Square root of 2.

real? → false

false 를 돌려줘요. Numeric#real? 과의 호환용이에요.

rect → array

배열 [self.real, self.imag] 를 돌려줘요. rectangular 의 별칭이에요.

rectangular

rect 의 별칭이에요.

to_c → self

self 를 돌려줘요.

to_f → float

가능하면 self.real 의 값을 Float 로 돌려줘요:

Complex.rect(1, 0).to_f              # => 1.0
Complex.rect(1, Rational(0, 1)).to_f # => 1.0

self.imag 가 정확히 0이 아니면(Integer(0) 또는 Rational(0, *n*)) RangeError 를 발생시켜요.

to_i → integer

가능하면 self.real 의 값을 Integer 로 돌려줘요:

Complex.rect(1, 0).to_i              # => 1
Complex.rect(1, Rational(0, 1)).to_i # => 1

self.imag 가 정확히 0이 아니면(Integer(0) 또는 Rational(0, *n*)) RangeError 를 발생시켜요.

to_json(*args)

self 를 나타내는 JSON 문자열을 돌려줘요:

require 'json/add/complex'
puts Complex(2).to_json
puts Complex(2.0, 4).to_json

출력:

{"json_class":"Complex","r":2,"i":0}
{"json_class":"Complex","r":2.0,"i":4}

to_r → rational

가능하면 self.real 의 값을 Rational 로 돌려줘요:

Complex.rect(1, 0).to_r              # => (1/1)
Complex.rect(1, Rational(0, 1)).to_r # => (1/1)
Complex.rect(1, 0.0).to_r            # => (1/1)

self.imag 가 정확히 0이 아니고(Integer(0) 또는 Rational(0, *n*)) self.imag.to_r 가 정확히 0이 아니면 RangeError 를 발생시켜요.

관련: Complex#rationalize.

to_s → string

self 의 문자열 표현을 돌려줘요:

Complex.rect(2).to_s                      # => "2+0i"
Complex.rect(-8, 6).to_s                  # => "-8+6i"
Complex.rect(0, Rational(1, 2)).to_s      # => "0+1/2i"
Complex.rect(0, Float::INFINITY).to_s     # => "0+Infinity*i"
Complex.rect(Float::NAN, Float::NAN).to_s # => "NaN+NaN*i"