SymPy를 이용하여 미분방정식 해결하기

이경헌·2021년 3월 8일
0

SymPy 란?

SymPy는 심볼릭 수학을 위한 Python 라이브러리입니다. 가능한 한 이해하기 쉽고 확장하기 편하게 컴퓨터 대수 시스템(CAS)을 지원합니다. 라이브러리는 Python으로 작성되었습니다. (공식 홈페이지 소개 번역)

가령 인수분해, 부정적분을 구하는 문제 등은 수치해석 라이브러리인 SciPy 등으로 해결할 수 없는 문제입니다. SymPy는 이러한 문제에 '마치 손으로 푸는 것과 같은' 솔루션을 제시합니다.

SymPy 설치하기

본 글에서는 ODE만을 다룹니다.

SymPy는 내장 라이브러리가 아닙니다. 따라서 이를 설치해야 합니다.

  • pip 환경에서
pip install sympy
  • conda 환경에서
conda install sympy

SymPy로 미분방정식 해결하기

1. 모듈 로드

SymPy 모듈을 로드합니다.

import sympy as sp

2. 가독성 개선

보기 편하게 하기 위해 use_latex를 사용하도록 하겠습니다.

sp.init_printing(use_latex=True)

use_unicode를 사용해도 되고, 사용하지 않아도 가독성이 감소하는 것을 제외하면 실행하지 않아도 되는 코드입니다.

3. 함수 설정

미분방정식에 사용할 함수를 만들도록 하겠습니다.

함수는 매개변수와 종속변수간의 관계를 나타냅니다. 본 글에서는 한 개의 매개변수에 대한 함수만을 다룹니다. 일반적으로 통용되는 미지수 xy를 각각 매개변수와 종속변수로, f를 함수로 사용하겠습니다.

SymPy에서는 변수를 나타내기 위해 일련의 과정을 거쳐야 합니다. 변수는 상수, 변수, 함수 등 모든 것을 포괄하는 개념입니다. symbols 메서드를 이용해 변수를 정의할 수 있습니다.

x = sp.symbols('x')
f = sp.symbols('f', cls=sp.Function) # 함수임을 나타냄

이때 종속변수 y는 함수 fx를 대입했을 때의 값이므로 다음과 같이 코드를 입력합니다.

y = f(x)

4. 미분방정식 풀이

이제 미분방정식을 풀어보도록 하겠습니다.

xy+y=2x(1)xy'+y=2x \tag{1}

다음 선형 미분방정식을 해결하기 위해, 먼저 방정식 자체를 정의하도록 하겠습니다. Equation 메서드는 첫 번째 인자에 좌변의 식을, 두 번째 인자에 우변의 식을 넣어 등식을 정의할 수 있습니다.

eq = sp.Eq(x * sp.diff(y, x) + y, 2 * x)

이 때 sp.diff(y, x)fx에 대한 도함수입니다. 보다 직관적인 표기를 위해 sp.diff(f(x), x)를 사용할 수도 있으나, 가독성의 문제로 이전에 y를 정의하였습니다.

이제 등식(미분방정식)이 정의되었으므로, 이를 해결합니다. dsolve 함수는 미분방정식의 해를 제공합니다.

sp.dsolve(eq, y)
# >> f(x)=C1/x+x

이 또한 마찬가지로 미분방정식 eqy, 즉 f(x)에 관해 풀라는 의미입니다.

이번엔 고계 미분방정식을 풀어보도록 하겠습니다.

(D2+1)y=secx(2)\left(D^2+1\right)y=\sec x \tag{2}
eq = sp.Eq(sp.diff(y, x, 2) + y, sp.sec(x))
sp.dsolve(eq, y)
# >> f(x)=(C1+x)sin(x)+(C2+log(cos(x))cos(x))

sp.diff에 세 개의 인자가 들어가면 첫 번째 인자(y)를 두 번째 인자(x)에 대해 세 번째 인자(2)에 해당하는 횟수의 미분, 즉 이계 도함수를 의미합니다. sec함수는 SymPy에서 제시하는 함수로, 어떤 SymPy 변수를 인자로 받는 함수입니다. 즉, sp.sec(x)는 SymPy의 을 나타냅니다.

5. 초기조건 설정

때론 미분방정식의 초기 조건이 제시되기도 합니다.

그 경우 dsolve에 초기 조건에 대한 식을 전달하여 해를 명확히 할 수도 있습니다.

첫 번째 미분방정식에 초기조건 y(1)=2y(1)=2을 적용해 봅시다.

sp.dsolve(eq, y, ics={f(1): 2})
# >> f(x)=x+1/x

dsolveics 인자에 좌변을 key로, 우변을 value로 한 dict 개체를 전달할 수 있습니다. 여기서 y(1)y(1)f에 1을 대입한 값이므로 y(1)이 아닌 f(1)로 입력해야 함이 마땅합니다.

두 번째 미분방정식은 이계 미분방정식이므로 두 개의 초기조건 y(0)=0y(0)=0, y(0)=0y'(0)=0을 적용해 봅시다.

sp.dsolve(eq, y, ics={f(0): 0, sp.diff(y, x).subs(x, 0): 0})
# >> f(x)=xsin(x)+log(cos(x))cos(x)

subs 메서드는 식의 해당하는 미지수(첫 번째 인자; x)에 값(두 번째 인자; 0)를 대입한 식을 반환합니다. 따라서 sp.diff(y, x).subs(x, 0)yx=0=y(0)y'\big\vert_{x=0}=y'(0)을 의미합니다.


Note

symbols 메서드는 여러개의 변수를 한 번에 정의할 수 있습니다. 가령,

x, y = sp.symbols('x y')

과 같이 사용 가능합니다.

profile
Undergraduate student in Korea University. Major in electrical engineering and computer science.

2개의 댓글

comment-user-thumbnail
2022년 4월 3일

감사합니다 bb

답글 달기
comment-user-thumbnail
2023년 10월 15일

안녕하세요 글 잘 보고 있어요..!
제가 요즘 많이 고심하는데도 모르겠어서
여쭤보고 싶은 공업수학 문제가 있는데
혹시 답변 해주실 수 있으실까요..?
곤란 하시다면 답변 안 해주셔도 괜찮아요
문제는 이거예요…!

“분리가능 상미분 방정식은 양형태 상미분 방정식의 일부이고, 완전 상미분 방정식은 음형태 상미분 방정식 일부라고 볼 수 있다.
양형태의 상미분 방정식 중 분리가능한 상미분 방정식을 제외하고 남은 상미분 방정식들은 어떤 것들이 있는지 (즉, 분리가능하지 않은 상미분 방정식들), 음형태의 상미분 방정식 중 완전 상미분 방정식을 제외하고 남은 상미분 방정식들은 어떤 것들이 있는지 (즉, 완전하지 않은 상미분 방정식들) 쓰시오.
즉.
양형태의 상미분 방정식의 전체 집합을 W.
음형태의 상미분 방정식의 전체 집합을 U,
분리가능한 상미분 방정식의 전체 집합을 A,
완전 상미분 방정식의 전체 집합을 B
라고 할 때
집합 A^c ᑎ W 과 집합 B^c ᑎ U 에 대해 기술하는 문제이다. 그 집합에 해당하는 미분 방 정식의 예를 몇 개 구하고 그들의 공통된 특징을 기술하는 방법을 써도 좋고, 아니면 이 집 합에 속하는 방정식들의 특징을 바로 기술하여도 좋다.“

답글 달기