두 벡터 a = [a0, a1, ..., aM]와 b = [b0, b1, ..., bN]가 주어졌을 때, 외적(outer product)은 다음과 같이 정의됩니다.
[[a0*b0 a0*b1 ... a0*bN ] [a1*b0 . . [ ... . . [aM*b0 aM*bN ]]
Python에서 두 배열의 외적을 구하려면 numpy.outer() 메서드를 사용합니다. 이 메서드는 첫 번째 벡터의 각 요소와 두 번째 벡터의 모든 요소를 곱한 결과를 행렬 형태로 반환합니다.
이번 예제에서는 추가로 다음 두 함수도 함께 사용합니다.
- numpy.ones() : 지정된 shape과 데이터 타입을 가지며, 모든 요소가 1로 채워진 새로운 배열을 반환합니다.
- numpy.linspace() : 지정된 구간(start, stop) 사이에서 균일한 간격의 숫자들을 반환합니다.
복소평면 위에 격자(grid)를 만들려면 실수부(real part)와 허수부(imaginary part)를 각각 외적으로 계산한 뒤 더해주면 됩니다. 이렇게 만든 그리드는 Mandelbrot 집합처럼 복소수 평면 전체를 대상으로 연산할 때 유용하게 쓰입니다.
단계별 진행
먼저 필요한 라이브러리를 임포트합니다.
import numpy as np
1) 실수부 계산 — np.ones()와 np.outer()를 이용해 -2부터 2까지의 값을 가진 5x5 배열을 만듭니다.
rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5))
print("복소수의 실수부...\n", rl)2) 허수부 계산 — linspace 결과에 허수 단위 j를 곱한 뒤 외적합니다.
im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,)))
print("\n복소수의 허수부...\n", im)3) 그리드 생성 — 실수부와 허수부를 더해 복소수 그리드를 완성합니다.
grid = rl + im
전체 예제 코드
import numpy as np
# 두 배열의 외적을 구하려면 Python의 numpy.outer() 메서드를 사용합니다.
# numpy.ones()는 지정된 shape과 타입으로, 모든 값이 1인 새 배열을 반환합니다.
# numpy.linspace()는 지정된 구간에서 균일하게 떨어진 숫자들을 반환합니다.
# 실수부
rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5))
print("복소수의 실수부...\n", rl)
# 허수부
im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,)))
print("\n복소수의 허수부...\n", im)
# 그리드 생성
grid = rl + im
print("\n그리드 출력...\n", grid)실행 결과
복소수의 실수부... [[-2. -1. 0. 1. 2.] [-2. -1. 0. 1. 2.] [-2. -1. 0. 1. 2.] [-2. -1. 0. 1. 2.] [-2. -1. 0. 1. 2.]] 복소수의 허수부... [[0.+2.j 0.+2.j 0.+2.j 0.+2.j 0.+2.j] [0.+1.j 0.+1.j 0.+1.j 0.+1.j 0.+1.j] [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j] [0.-1.j 0.-1.j 0.-1.j 0.-1.j 0.-1.j] [0.-2.j 0.-2.j 0.-2.j 0.-2.j 0.-2.j]] 그리드 출력... [[-2.+2.j -1.+2.j 0.+2.j 1.+2.j 2.+2.j] [-2.+1.j -1.+1.j 0.+1.j 1.+1.j 2.+1.j] [-2.+0.j -1.+0.j 0.+0.j 1.+0.j 2.+0.j] [-2.-1.j -1.-1.j 0.-1.j 1.-1.j 2.-1.j] [-2.-2.j -1.-2.j 0.-2.j 1.-2.j 2.-2.j]]
마무리
이렇게 np.outer(), np.ones(), np.linspace() 세 함수만으로 복소평면 위의 좌표 그리드를 손쉽게 생성할 수 있습니다. 완성된 그리드의 각 원소 c에 대해 반복 수식 z = z² + c를 적용하고 발산 여부를 검사하면, 바로 Mandelbrot 집합을 계산할 수 있습니다. 해상도를 높이고 싶다면 linspace의 샘플 개수를 늘리거나 범위를 조정하면 됩니다.