아인슈타인 합 규약(Einstein Summation Convention)을 활용해 행렬과 벡터의 곱셈을 수행하려면 파이썬의 numpy.einsum() 메서드를 사용하면 됩니다.
einsum() 메서드는 두 개의 주요 매개변수를 받습니다. 첫 번째 매개변수는 첨자(subscript)로, 합산에 사용될 첨자 레이블들을 쉼표로 구분된 문자열 형태로 지정합니다. 두 번째 매개변수는 피연산자(operands)로, 연산 대상이 되는 배열들을 의미합니다.
einsum() 메서드는 피연산자들에 대해 아인슈타인 합 규약을 평가합니다. 이 규약을 사용하면 다차원 배열에 대한 선형대수 연산 대부분을 간결한 표기법으로 나타낼 수 있습니다.
암시적 모드와 명시적 모드
암시적 모드(implicit mode)에서는 einsum이 아인슈타인 합 규약에 따라 자동으로 값을 계산합니다. 반면 명시적 모드(explicit mode)에서는 특정 첨자 레이블에 대한 합산을 비활성화하거나 강제할 수 있어, 고전적인 아인슈타인 합 연산 범위를 넘어서는 다양한 배열 연산도 유연하게 처리할 수 있습니다.
구현 단계
먼저 필요한 라이브러리를 임포트합니다.
import numpy as np
arange()와 reshape() 메서드를 사용해 5x5 크기의 2차원 배열(행렬)과 길이 5의 1차원 배열(벡터)을 생성합니다.
arr1 = np.arange(25).reshape(5,5) arr2 = np.arange(5)
생성된 배열을 출력해 확인합니다.
print("Array1...\n",arr1)
print("\nArray2...\n",arr2)두 배열의 차원(ndim)을 확인합니다.
print("\nDimensions of Array1...\n",arr1.ndim)
print("\nDimensions of Array2...\n",arr2.ndim)두 배열의 형상(shape)을 확인합니다.
print("\nShape of Array1...\n",arr1.shape)
print("\nShape of Array2...\n",arr2.shape)아인슈타인 합 규약으로 행렬-벡터 곱셈을 수행합니다. 여기서 'ij,j'는 행렬의 행 인덱스 i와 열 인덱스 j 중, j에 대해 합산하여 결과 벡터를 얻음을 의미합니다.
print("\nResult (Matrix Vector multiplication)...\n",np.einsum('ij,j', arr1, arr2))전체 예제 코드
import numpy as np
# arange()와 reshape()를 사용해 배열 생성
arr1 = np.arange(25).reshape(5,5)
arr2 = np.arange(5)
# 배열 출력
print("Array1...\n",arr1)
print("\nArray2...\n",arr2)
# 배열의 차원 확인
print("\nDimensions of Array1...\n",arr1.ndim)
print("\nDimensions of Array2...\n",arr2.ndim)
# 배열의 형상 확인
print("\nShape of Array1...\n",arr1.shape)
print("\nShape of Array2...\n",arr2.shape)
# einsum()으로 행렬-벡터 곱셈 수행
print("\nResult (Matrix Vector multiplication)...\n",np.einsum('ij,j', arr1, arr2))실행 결과
Array1... [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19] [20 21 22 23 24]] Array2... [0 1 2 3 4] Dimensions of Array1... 2 Dimensions of Array2... 1 Shape of Array1... (5, 5) Shape of Array2... (5,) Result (Matrix Vector multiplication)... [ 30 80 130 180 230]
실행 결과를 보면 5x5 행렬과 길이 5의 벡터가 곱해져 길이 5의 결과 벡터가 출력되었습니다. 이는 일반적인 행렬-벡터 곱셈(arr1 @ arr2)과 동일한 결과를 내지만, einsum()은 첨자 표기만 바꿔가며 전치, 내적, 외적 등 다양한 연산을 하나의 문법으로 처리할 수 있다는 장점이 있습니다.