[파이썬][Scipy] 행렬 조건수(Condition Number)와 수치 안정성 예제

행렬 조건수(Condition Number)와 수치 안정성에 대한 이해를 돕기 위해 예제를 살펴보겠습니다. 행렬 조건수는 행렬의 안정성 및 수치적으로 얼마나 민감한지를 나타내는 중요한 지표입니다.

1. 행렬 조건수 개념:

행렬 조건수는 주어진 행렬 �A에 대해 다음과 같이 정의됩니다.

조건수(�)=∥�∥⋅∥�−1∥조건수(A)=∥A∥⋅∥A−1∥

여기서 ∥�∥∥A∥는 행렬 �A의 노름(norm)을 나타내며, ∥�−1∥∥A−1∥는 역행렬 �−1A−1의 노름을 나타냅니다. 조건수는 보통 양수이며, 조건수가 크면 행렬 �A는 민감하게 작용하고 작은 조건수는 안정적인 행렬을 나타냅니다.

2. 예제: 행렬 조건수와 수치 안정성

아래의 예제에서는 조건수와 수치 안정성을 보여줍니다. 우선, NumPy와 SciPy를 사용하여 행렬 조건수를 계산하고, 조건수가 큰 경우 어떻게 수치적으로 불안정해질 수 있는지 살펴보겠습니다.

mport numpy as np
from scipy.linalg import hilbert

# 힐버트 행렬 생성 (조건수가 높음)
n = 5
A = hilbert(n)

# 행렬 조건수 계산
cond_num = np.linalg.cond(A)
print("행렬 조건수:", cond_num)

# 노이즈 추가 (작은 노이즈)
noise = 1e-6
A_noisy = A + noise * np.random.randn(n, n)

# 해 벡터 생성 (임의의 값)
b = np.random.randn(n)

# 원래 행렬로 해 구하기
x_exact = np.linalg.solve(A, b)

# 노이즈가 추가된 행렬로 해 구하기
x_noisy = np.linalg.solve(A_noisy, b)

# 해의 상대 오차 계산
relative_error = np.linalg.norm(x_exact - x_noisy) / np.linalg.norm(x_exact)
print("해의 상대 오차:", relative_error)

위의 코드에서는 다음을 수행합니다:

조건수가 높은 힐버트 행렬을 사용한 결과, 노이즈가 추가된 행렬로 풀 때 해의 상대 오차가 크게 증가하는 것을 확인할 수 있습니다. 이는 조건수가 높은 행렬의 경우 작은 노이즈만 추가되어도 수치적으로 불안정한 결과를 초래할 수 있음을 보여줍니다. 따라서 조건수를 고려하여 수치 안정성을 평가하고 적절한 조치를 취해야 합니다.