Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 NumPy einsum()으로 아인슈타인 합 규약 기반 행렬-벡터 곱셈 수행하기

아인슈타인 합 규약(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()은 첨자 표기만 바꿔가며 전치, 내적, 외적 등 다양한 연산을 하나의 문법으로 처리할 수 있다는 장점이 있습니다.