문제풀이

from sympy import *
x, y, z = symbols('x y z')
init_printing(use_unicode=True)
##  
import warnings;
with warnings.catch_warnings():
    warnings.simplefilter("ignore"); 
    import matplotlib.pyplot as plt

방정식에 대해 기억을 환기시키는 메모

Gotcha절에서 심파이에서 기호방정식은 =, ==으로 표현되는 것이 아니라, Eq로 표현되는 것을 상기한다.

Eq(x, y)

\[x = y\]

하지만, 더 쉬운 방식도 있다. 심파이에서 Eq에 없는 표현식은 문제풀이 함수가 0과 같다고 자동으로 가정한다. \(a=b\)이면 \(a-b=0\)으로 필요충분조건이기 때문에, x==y를 사용하는 대신에, x-y만 사용할 수 있다. 예를 들어,

solveset(Eq(x**2, 1), x)

\[\left\{-1, 1\right\}\]

solveset(Eq(x**2 -1, 0), x)

\[\left\{-1, 1\right\}\]

solveset(x**2 -1, x)

\[\left\{-1, 1\right\}\]

풀려고 하는 방정식이 이미 0과 같은 경우 특히나 도움이 된다. solveset(Eq(expr, 0), x) 타이핑하는 대신에, solveset(expr,x)를 바로 사용할 수 있다.

방정식을 대수적으로 문제풀기

대수방정식을 푸는 주요 함수가 solveset이다. solveset 구문은 solveset(equation, variable=None, domain=S.Complexes)이다. equationsEq 인스턴스이거나 0과 같다고 가정한 표현식 형태일 수 있다.

방정식을 푸는데 사용될 수 있는 solve라는 또다른 함수도 주목한다. 구문은 solve(equations, variables)이지만, solveset을 사용할 것을 추천한다.

방정식 한개를 풀 때, solveset 출력결과는 해에 대해 FiniteSet 혹은 Interval 혹은 ImageSet이 된다.

solveset(x**2-x,x)

\[\left\{0, 1\right\}\]

solveset(x-x, x, domain=S.Reals)

\[\mathbb{R}\]

solveset(sin(x)-1, x, domain=S.Reals)

\[\left\{2 n \pi + \frac{\pi}{2}\; |\; n \in \mathbb{Z}\right\}\]

해가 없는 경우, EmptySet이 반환되고, 해를 찾을 수 없는 경우 ConditionSet이 반환된다.

solveset(exp(x), x)

\[\emptyset\]

solveset(cos(x)-x, x)

\[\left\{x\; |\; x \in \mathbb{C} \wedge - x + \cos{\left (x \right )} = 0 \right\}\]

solveset 모듈에서, 선형방정식 시스템을 linsolve를 사용해서 풀수 있다. 향후 solveset에서 직접 linsolve를 사용할 수 있을 것이다. linsolve 구문에 대한 예제가 다음에 나와 있다.

  • 리스트 방정식 형태:
linsolve([x+y+z-1, x+y+2*z-3],(x,y,z))

\[\left\{\left ( - y - 1, \quad y, \quad 2\right )\right\}\]

  • 덧붙임 행렬 형태
linsolve(Matrix(([1,1,1,1],[1,1,2,3])),(x,y,z))

\[\left\{\left ( - y - 1, \quad y, \quad 2\right )\right\}\]

  • \(A*x=b\) 형태
M = Matrix(((1, 1, 1, 1), (1, 1, 2, 3)))
system = A, b=M[:,:-1],M[:,-1]
linsolve(system, x, y,z)

\[\left\{\left ( - y - 1, \quad y, \quad 2\right )\right\}\]

주목: 해의 순서는 주어진 기호 순서와 대응된다.

solveset은 한번만 각해를 출력한다. 중복을 포함하는 다항식에 대한 해를 구하려면, roots 함수를 사용한다.

solveset(x**3 -6*x**2 + 9*x, x)

\[\left\{0, 3\right\}\]

roots(x**3 -6*x**2 + 9*x, x)

\[\left \{ 0 : 1, \quad 3 : 2\right \}\]

roots를 돌려나온 {0: 1, 3: 2} 출력결과는 0이 중복 1회를 갖는 해이고, 3은 중복 2회를 갖는 해이다.

solve([x*y-1,x-2],x,y)

\[\left [ \left ( 2, \quad \frac{1}{2}\right )\right ]\]

solve(x*exp(x)-1,x)

\[\left [ \operatorname{LambertW}{\left (1 \right )}\right ]\]

미분 방정식 문제풀이

미분방정식을 푸는데 dsolve를 사용한다. 먼저, cls=Functionsymbols 함수에 인자로 전달해서 부정의 함수(undefined function)를 생성한다.

f,g=symbols('f g', cls=Function)

fg는 이제 부정의 함수가 되었다. f(x)를 호출할 수 있고, 미지함수를 표현하게 된다.

f(x)

\[f{\left (x \right )}\]

f(x) 미분은 평가되지 않는다.

f(x).diff(x)

\[\frac{d}{d x} f{\left (x \right )}\]

(미분에 대한 좀더 자세한 사항은 Derivatives를 참조한다.) \(f''(x) - 2f'(x) + f(x) = \sin(x)\) 미분방정식을 표현하는데, 다음과 같이 활용한다.

diffeq = Eq(f(x).diff(x, x) - 2*f(x).diff(x) + f(x), sin(x))
diffeq

\[f{\left (x \right )} - 2 \frac{d}{d x} f{\left (x \right )} + \frac{d^{2}}{d x^{2}} f{\left (x \right )} = \sin{\left (x \right )}\]

ODE 해를 구하려면, dsolve 함수에 풀 함수를 넘긴다.

dsolve(diffeq, f(x))

\[f{\left (x \right )} = \left(C_{1} + C_{2} x\right) e^{x} + \frac{1}{2} \cos{\left (x \right )}\]

dsolveEq 인스턴스를 반환한다. 이유는 일반적으로 미분방정식 해가 해당 함수에 대해 명시적으로 풀 수가 없기 때문이다.

dsolve(f(x).diff(x)*(1 - sin(f(x))), f(x))

\[f{\left (x \right )} + \cos{\left (f{\left (x \right )} \right )} = C_{1}\]

dsolve에서 나온 해는 임의 상수로 C1, C2, C3 등과 같은 기호형태를 갖는다.