-
[ Python ] 선형대수학 X 파이썬 | 벡터의 외적과 직교벡터 분해Study/Python 2025. 3. 7. 23:28
군 내에서 아이패드, 사지방 컴퓨터를 이용하여 작성함. 본 내용은 자기개발 목적으로 책 '개발자를 위한 실전 선형대수학-한빛미디어', 유튜브 등을 참고하였음. 그래프는 Google Colab에서 작성함.
벡터의 외적
외적은 열벡터와 행벡터를 사용하여 행렬을 만든다. 외적 행렬의 각 행은 행벡터 스칼라에 대응되는 열벡터 원소를 곱한 값이고, 각 열은 열벡터 스칼라에 대응되는 행벡터 원소를 곱한 값이다.
벡터의 외적은 내적의 차이가 있는데, 외적은 스칼라 대신 행렬을 생성한다. 또 외적은 두 벡터의 차원이 달라도 되지만 내적은 같아야 한다.
벡터의 외적 예시
벡터의 외적을 앞으로 다음과 같이 표기하겠다.
벡터의 외적 표기 방법
외적은 브로드캐스팅과 비슷하지만 두 벡터를 곱하는 기법이므로 산술 연산을 벡터로 확장한 브로드캐스팅과는 다르다.
각각 열과 행 방향인 벡터가 존재할 때 np.outer(), np.cross() 두 함수를 통해 외적을 계산할 수 있다.직교벡터 분해
벡터와 행렬을 분해하면, 여러 조각으로 나뉘게 된다. 이를 통해 행렬을 분석하거나 변형하여 목적에 맞게 사용할 수 있다.직교 투영
직교벡터 분해를 통해 직교 투영의 식을 유도할 수 있다.
표준 위치에 두 벡터 a, b가 있을 때, b벡터의 머리가 a벡터와 가장 가까운 점을 찾는다고 하자. b벡터를 a벡터에 투영한 거리가 최소가 되도록 한 지점을 βa라 할 때 b에서 βa까지의 선을 b-βa라고 정의할 수 있다.
위의 내용을 그림으로 표현한 것 b-βa와 βa는 직교하는 걸 알 수 있으므로 둘의 내적의 값은 0이 되어야 한다.
따라서 다음과 같은 식을 유도할 수 있다.
이와 같은 β를 직교 투영(orthographic projection 또는 정사영)이라고 한다.
직교벡터 분해
위에서 한 것처럼, 벡터를 분해하기 위해서는 목표벡터와 기준벡터를 설정해야 된다.(목표벡터를 두 개의 다른 벡터로 분해하려는 목적이다.)
이는 두 가지를 만족해야 된다.- 분해된 두 벡터의 합이 목표벡터가 되어야 한다.
- 한 벡터는 기준벡터와 직교하고, 다른 벡터는 평행해야 된다.
목표벡터를 t, 기준벡터를 r이라 할 때, 주어진 상황은 다음과 같다.

따라서 직교 투영에서 구한 식을 이용하면 평행 성분을 찾을 수 있다.

직교 투영에서 구한 식은 스칼라 β값만 구했으나 이 식에서는 벡터 βr을 구할 수 있다. 이 벡터가 평행 성분이다.
수직 성분은 목표 벡터에서 평행 성분을 뺀 값으로 구할 수 있다.
파이썬으로 구현하기
np.cross()와 np.outer()의 차이
np.cross()와 np.outer()는 외적을 계산하는 데 있어 차이점이 존재한다.
벡터의 외적을 계산할 때는 np.cross()를 사용한다. 같이 외적이라고 불리는 np.outer()는 텐서곱이다.# np.cross()을 이용한 벡터의 외적 예시 import numpy as np Vec_a=np.array([1, 2, 3]) Vec_b=np.array([4, 5, 6]) cross_product = np.cross(Vec_a,Vec_b) print(cross_product) ''' >> [-3 6 -3] '''# np.outer()을 이용한 벡터의 외적(텐서곱) 예시 import numpy as np Vec_a = np.array([1, 2, 3]) Vec_b = np.array([4, 5, 6]) outer_product= np.outer(Vec_a, Vec_b) print(outer_product) ''' >> [[ 4 5 6] [ 8 10 12] [12 15 18]] '''
직교벡터 분해
다음 코드는 두 난수 벡터 t와 r이 있을 때 두 성분의 합이 t이고 t⊥r과 t || r(수직 성분과 평행 성분)이 직교하는지 확인하는 것이다.
import numpy as np import matplotlib.pyplot as plt # 난수 벡터 t, r 생성 t = np.random.randn(2) r = np.random.randn(2) # 벡터 성분 분해 t_para = r * (np.dot(t,r) / np.dot(r,r)) t_perp = t - t_para # 두 구성요소의 덧셈이 목표 벡터인지 확인 print(t) print( t_para + t_perp ) # 직교임을 확인하기(내적의 값은 0) print( np.dot(t_para,t_perp) ) # 그래프 틀 그리기 plt.figure(figsize=(6,6)) # 두 메인 벡터 그리기 plt.plot([0,t[0]],[0,t[1]],color='k',linewidth=3,label=r't') plt.plot([0,r[0]],[0,r[1]],color=[.7,.7,.7],linewidth=3,label=r'r') # 벡터의 두 구성요소 그리기 plt.plot([0,t_para[0]],[0,t_para[1]],'k--',linewidth=3,label=r't para') plt.plot([0,t_perp[0]],[0,t_perp[1]],'k:',linewidth=3,label=r't perp') plt.axis('equal') plt.legend() plt.savefig('Figure_01_08.png',dpi=300) plt.show() ''' >>[-1.19004149 0.34705056] [-1.19004149 0.34705056] 0 (아래 사진 참고) '''
'Study > Python' 카테고리의 다른 글
[ Python ] 선형대수학 X 파이썬 | 행렬 (0) 2025.05.05 [ Python ] 선형대수학 X 파이썬 | 벡터공간(부분공간, 생성)과 기저 (1) 2025.03.29 [ Python ] 선형대수학 X 파이썬 | 선형 결합과 선형 독립성 (0) 2025.03.14 [ Python ] 선형대수학 X 파이썬 | 벡터와 벡터의 기본 연산(내적) (1) 2025.01.19 [ Python ] 선형대수학 X 파이썬 | 시각화 (3) 2024.11.11