Processing math: 61%

2018년 10월 20일 토요일

파이썬 Sympy 기호수학 - 기초

파이썬 Sympy 기호수학 - 기초

updated in 2019.09

Sympy 사용법

sympy 라이브러리를 불러온다

In [1]:
from sympy import *

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

In [2]:
init_printing()

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

In [3]:
Rational(1,2)
Out[3]:
12

원주율은 pi 로 표기한다.

In [4]:
pi
Out[4]:
π

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

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

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

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

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

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

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

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

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

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

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

In [11]:
x**2 + 1
Out[11]:
x2+1

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

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

In [12]:
expr = x**2 + 1
expr
Out[12]:
x2+1

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

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

xy 로 바꾸려면

In [14]:
expr.subs(x,y)
Out[14]:
y2+1

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

In [15]:
_
Out[15]:
y2+1
In [16]:
_.subs(y,2)
Out[16]:
5

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

In [17]:
expr = x**2 + 2*y*z + 1
expr
Out[17]:
x2+2yz+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]:
x2+8x+(x1)23
In [21]:
simplify(expr)
Out[21]:
2x2+6x2

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

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

sympify(string)
Out[22]:
xey+cos(x)

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

In [23]:
expand( (x-1)*(x-2) )
Out[23]:
x23x+2

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

In [24]:
factor( x**3 - 8 )
Out[24]:
(x2)(x2+2x+4)

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

In [25]:
expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3
expr
Out[25]:
x3x2z+2x2+xy+x3

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

In [26]:
collect(expr, x)    
Out[26]:
x3+x2(z+2)+x(y+1)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]:
x2+2x+1x2+x
In [29]:
cancel(expr)
Out[29]:
x+1x

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

In [30]:
expr = 1/x + (3*x/2 - 2)/(x - 4)
expr
Out[30]:
3x22x4+1x
In [31]:
cancel(expr)
Out[31]:
3x22x82x28x

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

In [32]:
expr = 1 / x / (x-1)
expr
Out[32]:
1x(x1)
In [33]:
apart(expr)
Out[33]:
1x11x

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

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

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

In [35]:
eqn = Eq( 2*x, 1 )
eqn
Out[35]:
2x=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(x)

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]:
ddxex2

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

In [42]:
deriv.doit()
Out[42]:
2xex2

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

In [43]:
Eq( deriv, deriv.doit() )
Out[43]:
ddxex2=2xex2

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

In [44]:
diff( exp(x*y), x, y )
Out[44]:
(xy+1)exy

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

In [45]:
diff( exp(x*y), y, x )
Out[45]:
(xy+1)exy

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

In [46]:
deriv = Derivative( exp(x*y), x, y )
deriv
Out[46]:
2yxexy

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

In [47]:
deriv.doit()
Out[47]:
(xy+1)exy

적분

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

In [48]:
integrate( 1/x, x )
Out[48]:
log(x)

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

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

10x2dx
In [49]:
integrate( x**2, (x,0,1) )
Out[49]:
13
0ex2dx

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

In [50]:
integrate( exp(-x**2), (x,0,oo) )
Out[50]:
π2

이중적분도 구할 수 있다.

e(x2+y2)dxdy
In [51]:
integrate( exp(-x**2-y**2), (x,-oo,oo), (y,-oo,oo) )
Out[51]:
π

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

In [52]:
integ = Integral( log(x) )
integ
Out[52]:
log(x)dx

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

In [53]:
Eq( integ, integ.doit() )
Out[53]:
log(x)dx=xlog(x)x

함수의 극한

limit 함수로 극한을 구한다.

lim
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 ¶ ...