Python/SciPy

SciPy 선형 방정식 풀기 (solve)

임베디드 친구 2025. 11. 18. 20:50
728x90
반응형

SciPy 선형 방정식 풀기 (solve)

1. 개요

선형 방정식(Linear Equations)은 수학과 공학에서 자주 등장하는 문제로, 행렬과 벡터 연산을 통해 해결할 수 있습니다. Python의 SciPy 라이브러리는 강력한 선형 대수 모듈을 제공하며, scipy.linalg.solve 함수를 사용하면 선형 방정식을 쉽게 해결할 수 있습니다.

이번 포스팅에서는 SciPy의 solve 함수를 활용하여 선형 방정식을 푸는 방법을 설명하고, 다양한 예제와 함께 실전에서 활용할 수 있는 기법을 소개하겠습니다.


2. 선형 방정식의 기본 개념

선형 방정식은 일반적으로 다음과 같은 형태를 가집니다:

$$
Ax = b
$$

여기서:

  • $ A $ : 계수 행렬 (Coefficient Matrix, $ n \times n $ 크기의 정방 행렬)
  • $ x $ : 미지수 벡터 (Unknown Vector, $ n \times 1 $ 크기의 벡터)
  • $ b $ : 상수 벡터 (Constant Vector, $ n \times 1 $ 크기의 벡터)

이 방정식에서 $ x $ 값을 구하는 것이 목표입니다.

예를 들어, 다음과 같은 선형 방정식이 있다고 가정해 보겠습니다:

$$
\begin{bmatrix} 2 & 3 \ 1 & 2 \end{bmatrix} \begin{bmatrix} x_1 \ x_2 \end{bmatrix} = \begin{bmatrix} 5 \ 3 \end{bmatrix}
$$

이를 Python에서 해결하는 방법을 살펴보겠습니다.


3. SciPy의 solve 함수 사용법

SciPy의 scipy.linalg.solve 함수는 위와 같은 선형 방정식을 풀 때 사용됩니다. 기본적인 사용법은 다음과 같습니다:

import numpy as np
from scipy.linalg import solve

# 계수 행렬 A
A = np.array([[2, 3], [1, 2]])

# 상수 벡터 b
b = np.array([5, 3])

# 선형 방정식 풀기
x = solve(A, b)

# 결과 출력
print("해:", x)

위 코드를 실행하면 x1x2의 값을 포함한 해가 출력됩니다.


4. solve 함수의 동작 원리

SciPy의 solve 함수는 LU 분해(LU Decomposition) 를 기반으로 선형 방정식을 풉니다. 이는 행렬을 하삼각 행렬(Lower Triangular Matrix, $ L $)과 상삼각 행렬(Upper Triangular Matrix, $ U $)로 분해하여 연산을 최적화하는 방법입니다.

LU 분해를 통해 연산을 수행하면, 계산 속도가 개선되고 수치적으로 안정적인 결과를 얻을 수 있습니다. solve 함수는 내부적으로 이러한 최적화 기법을 사용하여 빠르게 방정식을 풉니다.


5. 특수한 경우의 선형 방정식 해결

(1) 해가 없는 경우

특정한 선형 방정식에서는 해가 존재하지 않을 수도 있습니다. 예를 들어:

A = np.array([[1, 2], [2, 4]])  # 두 행이 선형 종속 관계
b = np.array([3, 6])

x = solve(A, b)  # 이 경우 오류 발생

위 예제에서는 A의 두 번째 행이 첫 번째 행의 2배이므로, 행렬이 특이 행렬(Singular Matrix) 이 되어 해를 구할 수 없습니다. 이 경우 numpy.linalg.lstsq를 사용하여 최소제곱 해를 찾을 수 있습니다.

(2) 여러 개의 해가 존재하는 경우

정방행렬이 아닌 과잉결정(overdetermined) 또는 과소결정(underdetermined) 시스템의 경우, 일반적인 solve 함수는 사용할 수 없습니다. 이런 경우 numpy.linalg.lstsq를 활용해야 합니다.

from numpy.linalg import lstsq

A = np.array([[1, 2, 3], [4, 5, 6]])  # 비정방 행렬
b = np.array([7, 8])

x, residuals, rank, s = lstsq(A, b, rcond=None)
print("최소제곱 해:", x)

lstsq 함수는 잔차(residuals)까지 계산하여 가장 근사한 해를 제공합니다.


6. 성능 최적화 기법

(1) 대각행렬 또는 삼각행렬을 활용한 최적화

특정한 구조를 가진 행렬에서는 solve 함수보다 효율적인 특수 함수가 제공됩니다.

  • 대각행렬(diagonal matrix) : scipy.linalg.solve_triangular을 사용하면 연산 속도를 개선할 수 있습니다.
  • 희소 행렬(sparse matrix) : scipy.sparse.linalg.spsolve를 사용하면 메모리 사용량을 절약할 수 있습니다.
from scipy.linalg import solve_triangular

U = np.array([[3, 2], [0, 1]])  # 상삼각 행렬
b = np.array([5, 3])

x = solve_triangular(U, b, lower=False)
print("해:", x)

(2) 반복법 활용 (큰 규모의 행렬)

크기가 매우 큰 행렬을 다룰 때는 scipy.sparse.linalg.cg와 같은 반복법(Iterative Method) 을 활용하는 것이 효과적입니다.

from scipy.sparse.linalg import cg

A = np.array([[4, 1], [1, 3]])
b = np.array([1, 2])

x, info = cg(A, b)
print("해:", x)

cg 함수는 공액 그래디언트 방법(Conjugate Gradient Method) 을 사용하여 매우 큰 행렬에서도 효율적으로 선형 방정식을 풀 수 있도록 합니다.


7. 결론

이번 포스팅에서는 SciPy의 scipy.linalg.solve 함수를 활용하여 선형 방정식을 푸는 방법을 살펴보았습니다. 핵심 요점을 정리하면 다음과 같습니다:

  1. solve 함수는 Ax = b 형태의 선형 방정식을 효율적으로 해결한다.
  2. 특이 행렬(Singular Matrix)이나 해가 여러 개인 경우, numpy.linalg.lstsq를 사용하여 해를 근사적으로 구할 수 있다.
  3. 특정한 행렬 구조(삼각 행렬, 희소 행렬 등)에서는 최적화된 함수를 활용하는 것이 성능 향상에 도움이 된다.
  4. 매우 큰 행렬을 다룰 때는 반복법(Iterative Method)을 활용하면 효율적이다.

SciPy는 다양한 수학 연산을 최적화하는 강력한 도구이며, solve 함수는 선형 대수 계산에서 필수적인 기능 중 하나입니다.

반응형