2018년 10월 20일 토요일

파이썬 Sympy 기호수학 - 기초

파이썬 Sympy 기호수학 - 기초

$\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad $ updated in 2019.09

Sympy 사용법

sympy 라이브러리를 불러온다

In [1]:
from sympy import *

수식 출력을 LaTex 수식으로 보이게 한다.

In [2]:
init_printing()

Rational( 분자, 분모 ) 함수는 유리수를 분수로 나타낸다.

In [3]:
Rational(1,2)
Out[3]:
$$\frac{1}{2}$$

원주율은 pi 로 표기한다.

In [4]:
pi
Out[4]:
$$\pi$$

N() 함수는 수치값으로 계산한다.

In [5]:
N(pi)
Out[5]:
$$3.14159265358979$$

evalf() 메소드로 수치값을 계산할 수도 있다.

In [6]:
pi.evalf()
Out[6]:
$$3.14159265358979$$

복소수는 대문자 $\text I$ 로 나타낸다.

In [7]:
I
Out[7]:
$$i$$
In [8]:
1 + 2*I
Out[8]:
$$1 + 2 i$$

Symbol 함수로 기호변수 $t$ 를 선언한다.

In [9]:
t = Symbol('t')

symbols 함수는 한 번에 여러개의 기호변수를 선언할 수 있어서 더 편리하다.

In [10]:
x, y, z = symbols('x y z')

기호 변수로 수식을 나타낼 수 있다.

In [11]:
x**2 + 1
Out[11]:
$$x^{2} + 1$$

수식을 저장하면, 나중에 참조하거나 사용할 수 있다.

수식이 저장되는 변수는 기호가 아니다.

In [12]:
expr = x**2 + 1
expr
Out[12]:
$$x^{2} + 1$$

subs() 메소드로 기호변수에 특정한 값을 대입하거나, 다른 기호변수로 대체할 수 있다.

In [13]:
expr.subs(x,1)
Out[13]:
$$2$$

$x$ 를 $y$ 로 바꾸려면

In [14]:
expr.subs(x,y)
Out[14]:
$$y^{2} + 1$$

_ 는 바로 이전의 출력을 가리킨다.

In [15]:
_
Out[15]:
$$y^{2} + 1$$
In [16]:
_.subs(y,2)
Out[16]:
$$5$$

여러개의 변수에 값을 대입할 수 있다.

In [17]:
expr = x**2 + 2*y*z + 1
expr
Out[17]:
$$x^{2} + 2 y z + 1$$
In [18]:
expr.subs( [ (x,1), (y,2), (z,3) ] )
Out[18]:
$$14$$

simplify() 함수는 수식을 간단히 만들어준다.

In [19]:
simplify( cos(x)**2 + sin(x)**2 )
Out[19]:
$$1$$
In [20]:
expr = x**2 + 5*x + 3*(x-1) + (x-1)**2
expr
Out[20]:
$$x^{2} + 8 x + \left(x - 1\right)^{2} - 3$$
In [21]:
simplify(expr)
Out[21]:
$$2 x^{2} + 6 x - 2$$

sympify() 함수는 문자열을 수식으로 바꾸어 준다. 사용자가 입력한 수식을 처리하는데 사용할 수 있다.

In [22]:
string = "x*exp(-y)+cos(x)"

sympify(string)
Out[22]:
$$x e^{- y} + \cos{\left (x \right )}$$

expand() 함수는 수식을 전개한다.

In [23]:
expand( (x-1)*(x-2) )
Out[23]:
$$x^{2} - 3 x + 2$$

factor() 함수는 수식을 인수분해 한다.

In [24]:
factor( x**3 - 8 )
Out[24]:
$$\left(x - 2\right) \left(x^{2} + 2 x + 4\right)$$

collect() 함수는 수식을 특정 변수의 다항식으로 정리한다.

In [25]:
expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3
expr
Out[25]:
$$x^{3} - x^{2} z + 2 x^{2} + x y + x - 3$$

$x$ 의 다항식으로 표현하려면

In [26]:
collect(expr, x)    
Out[26]:
$$x^{3} + x^{2} \left(- z + 2\right) + x \left(y + 1\right) - 3$$

coeff() 함수는 수식의 특정항의 계수를 반환한다.

In [27]:
expr.coeff(x,2)       # x**2 항의 계수
Out[27]:
$$- z + 2$$

cancel() 함수는 분수의 분자와 분모를 약분하여 간단한 형태로 만든다.

In [28]:
expr = (x**2 + 2*x + 1)/(x**2 + x)
expr
Out[28]:
$$\frac{x^{2} + 2 x + 1}{x^{2} + x}$$
In [29]:
cancel(expr)
Out[29]:
$$\frac{x + 1}{x}$$

또한, 분수식들을 통분하여, 하나의 분수식으로 만들어준다.

In [30]:
expr = 1/x + (3*x/2 - 2)/(x - 4)
expr
Out[30]:
$$\frac{\frac{3 x}{2} - 2}{x - 4} + \frac{1}{x}$$
In [31]:
cancel(expr)
Out[31]:
$$\frac{3 x^{2} - 2 x - 8}{2 x^{2} - 8 x}$$

apart() 함수는 분수식을 부분 분수들로 쪼개어 준다.

In [32]:
expr = 1 / x / (x-1)
expr
Out[32]:
$$\frac{1}{x \left(x - 1\right)}$$
In [33]:
apart(expr)
Out[33]:
$$\frac{1}{x - 1} - \frac{1}{x}$$

방정식은 Eq( 왼쪽, 오른쪽 ) 으로 표현한다

In [34]:
Eq( 2*x, 1 )
Out[34]:
$$2 x = 1$$

방정식 자체를 변수에 저장하여, 나중에 참조할 수 있다.

In [35]:
eqn = Eq( 2*x, 1 )
eqn
Out[35]:
$$2 x = 1$$

함수의 그래프

노트북 문서에 그래프를 나타내려면, 다음 명령을 실행한다.

In [36]:
%matplotlib inline  

plot() 함수로 그래프를 그린다. 함수들과 x축, y축의 범위를 지정한다.

In [37]:
plot( x+1, x**2, xlim=(-2,2), ylim=(-1,3) )
Out[37]:
<sympy.plotting.plot.Plot at 0x86ff9f0>

미분

diff() 함수로 도함수를 구한다.

In [38]:
diff( cos(x), x )
Out[38]:
$$- \sin{\left (x \right )}$$

2차 도함수

In [39]:
diff( x**2, x, x )
Out[39]:
$$2$$

마지막 인자에 2 를 기입하여도 같은 결과를 얻는다.

In [40]:
diff( x**2, x, 2 )
Out[40]:
$$2$$

Derivative() 함수는 도함수를 표현하는 용도에 사용된다.

In [41]:
deriv = Derivative( exp(-x**2), x )
deriv
Out[41]:
$$\frac{d}{d x} e^{- x^{2}}$$

doit() 메소드로 연산을 수행하여 결과를 얻을 수 있다.

In [42]:
deriv.doit()
Out[42]:
$$- 2 x e^{- x^{2}}$$

도함수의 표현과 그 결과를 수식으로 표현하여 보자.

In [43]:
Eq( deriv, deriv.doit() )
Out[43]:
$$\frac{d}{d x} e^{- x^{2}} = - 2 x e^{- x^{2}}$$

diff() 함수로 편도함수를 구할 수 있다.

In [44]:
diff( exp(x*y), x, y )
Out[44]:
$$\left(x y + 1\right) e^{x y}$$

편도함수는 대부분의 경우에 미분의 순서에 관계 없다.

In [45]:
diff( exp(x*y), y, x )
Out[45]:
$$\left(x y + 1\right) e^{x y}$$

Derivative() 함수로 편도함수를 표현해 본다.

In [46]:
deriv = Derivative( exp(x*y), x, y )
deriv
Out[46]:
$$\frac{\partial^{2}}{\partial y\partial x} e^{x y}$$

doit() 메소드로 실행하여 결과를 얻는다.

In [47]:
deriv.doit()
Out[47]:
$$\left(x y + 1\right) e^{x y}$$

적분

integrate() 함수로 부정적분을 수행한다.

In [48]:
integrate( 1/x, x )
Out[48]:
$$\log{\left (x \right )}$$

적분 상수는 따로 출력되지 않는다 !

integrate() 함수로 정적분을 구할 수 있다. 적분 범위는 두번째 인자로 설정한다.

$$\int_{0}^{1} x^2 dx$$
In [49]:
integrate( x**2, (x,0,1) )
Out[49]:
$$\frac{1}{3}$$
$$\int_{0}^{\infty}e^{-x^2} dx$$

무한대는 소문자 o 를 두개 사용하여 oo 로 나타낸다.

In [50]:
integrate( exp(-x**2), (x,0,oo) )
Out[50]:
$$\frac{\sqrt{\pi}}{2}$$

이중적분도 구할 수 있다.

$$\int_{-\infty}^{\infty}\int_{-\infty}^{\infty}e^{-(x^2+y^2)} dx dy$$
In [51]:
integrate( exp(-x**2-y**2), (x,-oo,oo), (y,-oo,oo) )
Out[51]:
$$\pi$$

Integral() 함수는 적분을 수학적으로 표현하는데 사용된다.

In [52]:
integ = Integral( log(x) )
integ
Out[52]:
$$\int \log{\left (x \right )}\, dx$$

doit() 메소드로 실행 결과를 얻는다.

In [53]:
Eq( integ, integ.doit() )
Out[53]:
$$\int \log{\left (x \right )}\, dx = x \log{\left (x \right )} - x$$

함수의 극한

limit 함수로 극한을 구한다.

$$\lim_{x \to 0 }\frac{sin(x)}{x}$$
In [54]:
limit( sin(x)/x, x, 0 )
Out[54]:
$$1$$

방정식의 해

다음의 방정식에 대하여

$$ 2 x = 1$$

In [55]:
eqn = Eq( 2*x, 1 )
eqn
Out[55]:
$$2 x = 1$$

solve() 함수로 방정식의 해를 구한다.

In [56]:
solve( eqn, x )
Out[56]:
$$\left [ \frac{1}{2}\right ]$$

방정식의 우변이 0 인 형태의 경우는, 좌변의 수식만 기입하여 해를 구할 수도 있다.

$$ 2 x - 1 = 0$$

In [57]:
solve( 2*x-1, x )       
Out[57]:
$$\left [ \frac{1}{2}\right ]$$

이차방정식의 근의 공식

$$ a x^2 + b x + c = 0$$

In [58]:
a, b, c = symbols('a, b, c')
eqn = Eq( a*x**2 + b*x + c, 0 )
eqn
Out[58]:
$$a x^{2} + b x + c = 0$$
In [59]:
solve( eqn, x )
Out[59]:
$$\left [ \frac{- b + \sqrt{- 4 a c + b^{2}}}{2 a}, \quad - \frac{b + \sqrt{- 4 a c + b^{2}}}{2 a}\right ]$$

기호변수는 암묵적으로 복소수로 취급되므로, 복소근도 구해진다.

In [60]:
solve( Eq( x**2, -1 ), x )
Out[60]:
$$\left [ - i, \quad i\right ]$$

연립 방정식의 해

$$x-y+2=0$$

$$x+y-3=0$$

방정식과 변수를 리스트로 묶어서 인수를 전달한다.

In [61]:
solve( [ x-y+2, x+y-3 ], [x,y] )
Out[61]:
$$\left \{ x : \frac{1}{2}, \quad y : \frac{5}{2}\right \}$$

튜플로 묶어도 같은 결과를 얻는다.

In [62]:
solve( ( x-y+2, x+y-3 ), (x,y) )
Out[62]:
$$\left \{ x : \frac{1}{2}, \quad y : \frac{5}{2}\right \}$$

Taylor 급수

In [63]:
series( sin(x), x )
Out[63]:
$$x - \frac{x^{3}}{6} + \frac{x^{5}}{120} + O\left(x^{6}\right)$$

x의 차수를 원하는 값으로 설정할 수 있다. 다음 예와 같이 10차 이전까지의 급수를 나타내면

In [64]:
series( sin(x), x, n=10 )
Out[64]:
$$x - \frac{x^{3}}{6} + \frac{x^{5}}{120} - \frac{x^{7}}{5040} + \frac{x^{9}}{362880} + O\left(x^{10}\right)$$

급수를 계산에 활용하기 위해서는, 마지막 차수항 O(x) 를 제거해야 한다. 이를 위해 removeO 메소드를 사용한다.

In [65]:
Sin = series( sin(x), x, n=10 ).removeO()
Sin
Out[65]:
$$\frac{x^{9}}{362880} - \frac{x^{7}}{5040} + \frac{x^{5}}{120} - \frac{x^{3}}{6} + x$$

사인 함수를 9차의 다항식으로 근사하였다. 이 식에 $x= \pi /2 $ 를 대입하여 보면

In [66]:
Sin.subs( x, pi/2 ).evalf()
Out[66]:
$$1.00000354258429$$

행렬

Matrix() 함수로 행렬을 만든다.

In [67]:
A = Matrix( [[1,2],[3,4]] )
A
Out[67]:
$$\left[\begin{matrix}1 & 2\\3 & 4\end{matrix}\right]$$

일차원 리스트로 만든 행렬은 열벡터로 표현된다.

In [68]:
Matrix( [1,2] )
Out[68]:
$$\left[\begin{matrix}1\\2\end{matrix}\right]$$

단위 행렬은 eye() 함수로 만든다.

In [69]:
eye(2)
Out[69]:
$$\left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right]$$

행렬의 곱은 A * B 이다.

In [70]:
A * eye(2)
Out[70]:
$$\left[\begin{matrix}1 & 2\\3 & 4\end{matrix}\right]$$

det() 함수로 행렬식(determinant)을 구한다.

In [71]:
A.det()
Out[71]:
$$-2$$

inv() 함수로 역행렬을 구한다.

In [72]:
A.inv()
Out[72]:
$$\left[\begin{matrix}-2 & 1\\\frac{3}{2} & - \frac{1}{2}\end{matrix}\right]$$

행렬의 -1 승으로 역행렬을 구할 수도 있다.

In [73]:
A**-1
Out[73]:
$$\left[\begin{matrix}-2 & 1\\\frac{3}{2} & - \frac{1}{2}\end{matrix}\right]$$

행렬과 역행렬의 곱은 단위 행렬이다.

In [74]:
A * A.inv()
Out[74]:
$$\left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right]$$

행렬의 원소를 기호로 표기하여 수식적으로 다룰 수 있다.

In [75]:
a11, a12, a21, a22 = symbols('a11, a12, a21, a22')
A = Matrix( [[a11, a12],[a21, a22]] )
A
Out[75]:
$$\left[\begin{matrix}a_{11} & a_{12}\\a_{21} & a_{22}\end{matrix}\right]$$
In [76]:
A.det()
Out[76]:
$$a_{11} a_{22} - a_{12} a_{21}$$
In [77]:
A.inv()
Out[77]:
$$\left[\begin{matrix}\frac{a_{22}}{a_{11} a_{22} - a_{12} a_{21}} & - \frac{a_{12}}{a_{11} a_{22} - a_{12} a_{21}}\\- \frac{a_{21}}{a_{11} a_{22} - a_{12} a_{21}} & \frac{a_{11}}{a_{11} a_{22} - a_{12} a_{21}}\end{matrix}\right]$$

연립 방정식의 해

\begin{align} x-y &= -2 \\ x+y &= 3 \end{align}

행렬로 나타내면

$$ \mathbf {A x} = \mathbf b $$
In [78]:
A = Matrix( [[1,-1],[1,1]] )
b = Matrix( [-2,3] )

방정식의 해는

$$ \mathbf x = \mathbf A ^{-1} \mathbf b $$
In [79]:
x = A.inv() * b
x
Out[79]:
$$\left[\begin{matrix}\frac{1}{2}\\\frac{5}{2}\end{matrix}\right]$$

댓글 1개:

Numeric Analysis 4 - Numeric Linear Algebra

Numeric Analysis 4 - Numeric Linear Algebra Numeric Linear Algebra ¶ ...