[개발자를 위한 실전 선형대수학] Chapter 2 연습문제

[chapter 2] 벡터, 파트2 : 벡터의 확장 개념

2-1

선형 가중 결합에 대한 코드 다시 구현하기

리스트 안에 스칼라와 벡터를 원소로 넣고, for 루프 사용해 선형 가중 결합 연산 구현하기

내 코드

v1 = np.array([4,5,1])
v2 = np.array([-4,0,-4])
v3 = np.array([1,3,2])

scalars = [1, 2, -3]
vectors = [v1, v2, v3]

length = len(v1)

answer = np.zeros(length)
for v,s in zip(scalars, vectors):
  answer += v*s

print(answer)

2-2

벡터가 $R^4$라면 어떻게 되고, 벡터보다 스칼라가 많으면 어떻게 될까?

v1 = np.array([4,5,1,1])
v2 = np.array([-4,0,-4,2])
v3 = np.array([1,3,2,3])

scalars = [1, 2, -3,4,5]
vectors = [v1, v2, v3]

length = len(v1)

answer = np.zeros(length)
for v,s in zip(scalars, vectors):
  answer += v*s

print(answer) # [ -7.  -4. -13.  -4.]

위 식에서는 에러가 나지 않는다.(zip은 두 리스트 길이 맞춰서 반복하기 때문)

아래처럼 index로 반복문을 돌리면 (당연히) 에러가 난다.

v1 = np.array([4,5,1,1])
v2 = np.array([-4,0,-4,2])
v3 = np.array([1,3,2,3])

scalars = [1, 2, -3,4,5]
vectors = [v1, v2, v3]

length = len(v1)

answer = np.zeros(length)

for i in range(len(scalars)):
  answer += scalars[i]*vectors[i] # IndexError: list index out of range

print(answer)

2-3

[1,3] 벡터 하나를 가진 벡터 집합을 정의하고, -4와 +4 사이의 균일한 분포로 100개의 숫자를 무작위로 만들어 무작위 스칼라를 만든다.

기저벡터에 이 무작위 스칼라를 곱해 부분공간에 점 100개를 만든다. 이 점들을 그려보기.

다음으로 $R^3$의 [3, 5, 1]과 [0, 2, 2] 두 벡터를 사용해 똑같이 이 과정을 반복한다.

plotly 라이브러리를 사용해 점을 그린다.

마지막으로 $R^3$에서 두 번째 벡터에 1/2를 곱해 똑같이 진행한다.

정답 코드

# 기저 벡터
A  = np.array([ 1,3 ])

xlim = [-4,4]

# np.random.uniform(): 지정 범위에서 균등 분포(uniform distribution)로 숫자를 무작위 생성
# 결과는 길이가 100인 1차원 배열
scalars = np.random.uniform(low=xlim[0],high=xlim[1],size=100)



# 그래프 전체 크기를 6 * 6 인치로 설정
plt.figure(figsize=(6,6))

# 점 100개 찍기
for s in scalars:

  p = A*s # 벡터에 스칼라곱

  # 점찍기
  plt.plot(p[0],p[1],'ko') # k = black, o = circle marker

# x, y축 범위 설정
plt.xlim(xlim)
plt.ylim(xlim)
plt.grid() # 격자 표시
plt.text(-4.5,4.5,'A)',fontweight='bold',fontsize=18) # 왼쪽 상단 라벨 표시
plt.savefig('Figure_02_07a.png',dpi=300) # png 파일로 저장
plt.show() # 그래프 표시

아래와 같이 그래프가 그려진다.

정답코드 2

# 3차원 벡터 2개
v1 = np.array([ 3,5,1 ])
v2 = np.array([ 0,2,2 ])

xlim = [-4,4]
 
scalars = np.random.uniform(low=xlim[0],high=xlim[1],size=(100,2)) # 100 * 2 배열. 각 행은 하나의 스칼라 조합이 된다. ex) [1.2, -0.5]

plt.figure(figsize=(6,6))

# 100 * 3배열. 3차원 좌표 저장할 배열
points = np.zeros((100,3))

# 점들을 선형 가중 결합한다
for i in range(len(scalars)):
  points[i,:] = v1*scalars[i,0] + v2*scalars[i,1]

fig = go.Figure(data=[go.Scatter3d( # scatter3d = 3d 산점도
    x=points[:,0], y=points[:,1], z=points[:,2], 
    mode='markers',  # 점만 그림
    marker=dict(size=6, color='black') # 점 크기/색 지정
)])

fig.update_layout(margin=dict(l=0,r=0,b=0,t=0))
plt.savefig('Figure_02_07b.png', dpi=300)
fig.show()

아래와 같은 3차원 그래프가 생성된다.

이 문제가 왜 나왔을까? 싶었는데, ChatGPT랑 얘기하면서 이해가 되었다.

직접 랜덤값을 만들고, 선형 가중 결합을 통해 벡터가 만드는 부분공간(subspace)을 직접 만들어보고 시각적으로 확인하는 것이 목적이었다.