```python
import sympy

# Juypter 노트북에서 수학식의 LaTeX 표현을 위해 필요함
sympy.init_printing(use_latex='mathjax')
```


```python
# sympy를 사용하면 아무런 숫자도 대입되지 않는 변수 생성 가능 (수식!)
# log같은 수학 연산을 취할때 np에 있는걸 사용하면 안되고 sympy에 있는걸 사용해야함
```


```python
x = sympy.symbols('x')
x
```




$\displaystyle x$




```python
type(x)
```




    sympy.core.symbol.Symbol




```python
f = x * sympy.exp(x)
f
```




$\displaystyle x e^{x}$




```python
# 미분
sympy.diff(f)
```




$\displaystyle x e^{x} + e^{x}$




```python
sympy.diff(f)
```




$\displaystyle x e^{x} + e^{x}$




```python
sympy.simplify(sympy.diff(f))
```




$\displaystyle \left(x + 1\right) e^{x}$




```python
x, y = sympy.symbols('x y')
f = x ** 2 + 4 * x * y + 4 * y ** 2
f
```




$\displaystyle x^{2} + 4 x y + 4 y^{2}$




```python
sympy.diff(f, x)
```




$\displaystyle 2 x + 4 y$




```python
sympy.diff(f, y)
```




$\displaystyle 4 x + 8 y$




```python
x, mu, sigma = sympy.symbols('x mu sigma')
f = sympy.exp((x - mu) ** 2 / sigma ** 2)
f
```




$\displaystyle e^{\frac{\left(- \mu + x\right)^{2}}{\sigma^{2}}}$




```python
# x로 미분하는걸 명시해줘야함
sympy.diff(f, x)
```




$\displaystyle \frac{\left(- 2 \mu + 2 x\right) e^{\frac{\left(- \mu + x\right)^{2}}{\sigma^{2}}}}{\sigma^{2}}$




```python
# 이차도함수 -> X에 대해 두번 미분
sympy.diff(f, x, x)
```




$\displaystyle \frac{2 \left(1 + \frac{2 \left(\mu - x\right)^{2}}{\sigma^{2}}\right) e^{\frac{\left(\mu - x\right)^{2}}{\sigma^{2}}}}{\sigma^{2}}$



#### 연습문제 4.2.5


```python
x= sympy.symbols('x')
f= x**3-1
```


```python
sympy.diff(f,x)
```




$\displaystyle 3 x^{2}$




```python
x,k=sympy.symbols('x k')
f=sympy.log(x**2-3*k)
sympy.diff(f,x)
```




$\displaystyle \frac{2 x}{- 3 k + x^{2}}$




```python
x,a,b=sympy.symbols('x a b')
f=sympy.exp(a*x**b)
sympy.diff(f,x),sympy.simplify(sympy.diff(f,x))
```




$\displaystyle \left( \frac{a b x^{b} e^{a x^{b}}}{x}, \  a b x^{b - 1} e^{a x^{b}}\right)$



#### 연습문제 4.2.6


```python
x,y=sympy.symbols('x y')
f=sympy.exp(x**2+2*y**2)
```


```python
sympy.diff(f,x)
```




$\displaystyle 2 x e^{x^{2} + 2 y^{2}}$




```python
sympy.diff(f,y)
```




$\displaystyle 4 y e^{x^{2} + 2 y^{2}}$




```python
sympy.diff(f,x,x)
```




$\displaystyle 2 \left(2 x^{2} + 1\right) e^{x^{2} + 2 y^{2}}$




```python
sympy.diff(f,x,y)
```




$\displaystyle 8 x y e^{x^{2} + 2 y^{2}}$




```python
sympy.diff(f,y,x)
```




$\displaystyle 8 x y e^{x^{2} + 2 y^{2}}$




```python
sympy.diff(f,y,y)
```




$\displaystyle 4 \left(4 y^{2} + 1\right) e^{x^{2} + 2 y^{2}}$



### 심파이를 이용한 부정적분


```python
sympy.init_printing(use_latex='mathjax')

x = sympy.symbols('x')
f = x * sympy.exp(x) + sympy.exp(x)
f
```




$\displaystyle x e^{x} + e^{x}$




```python
sympy.integrate(f)
```




$\displaystyle x e^{x}$




```python
x, y = sympy.symbols('x y')
f = 2 * x + y
f
```




$\displaystyle 2 x + y$




```python
sympy.integrate(f, x)
```




$\displaystyle x^{2} + x y$



#### 연습문제 4.3.4


```python
x=sympy.symbols('x')
f=3*x**2
sympy.integrate(f,x)
```




$\displaystyle x^{3}$




```python
x=sympy.symbols('x')
f=3*x**2-6*x+1
sympy.integrate(f,x)
```




$\displaystyle x^{3} - 3 x^{2} + x$




```python
x=sympy.symbols('x')
f=2+6*x+4*sympy.exp(x)+5/x
sympy.integrate(f,x)
```




$\displaystyle 3 x^{2} + 2 x + 4 e^{x} + 5 \log{\left(x \right)}$




```python
x=sympy.symbols('x')
f=2*x/(x**2-1)
sympy.integrate(f,x)
```




$\displaystyle \log{\left(x^{2} - 1 \right)}$



### 정적분


```python
x, y = sympy.symbols('x y')
f = x ** 3 - 3 * x ** 2 + x + 6
f
```




$\displaystyle x^{3} - 3 x^{2} + x + 6$




```python
# 부정 적분
F=sympy.integrate(f)
F
```




$\displaystyle \frac{x^{4}}{4} - x^{3} + \frac{x^{2}}{2} + 6 x$




```python
# subs : 대입
# evalf : 수치 표현식을 부동소수점 숫자로 평가 
F.subs(x,2)-F.subs(x,0).evalf()
```




$\displaystyle 10$



### 수치적분


```python
import scipy as sp
from scipy import integrate
```


```python
def f(x):
    return x ** 3 - 3 * x ** 2 + x + 6


scipy.integrate.quad(f, 0, 2)  
# 정적분 (수치적분)
# 적분값, 오차 형태로 결과 나옴
```




    (10.0, 1.1102230246251565e-13)



### scipy를 이용한 최적화


```python
def f1(x):
    return (x-2)**2+2
```


```python
x0=0 # 초깃값
result=  sp.optimize.minimize(f1,x0)
print(result)
#success :T -> 최저값 찾는데 성공 -> 그값이 x
# fuc x의 위치에서 함수값
# hess_inv: 헤시안 값 -> 양수면 아래로 볼록이라 최저점이 맞음
# jac: 자코비안 행렬값 =0이면 최저값 맞음
# nit: 두번의 이동만에 끝냄 x0(초깃값)->x1->x2
# njev: 기울기 계산은 세번 -> 초깃값이 최저일수도 있으니 그때도 한번 계산
# nfev: 앞뒤 함수값 구해서 그 두값의 기울기를 구함 
# 앞의값 뒤의값 자기자신의 값 이렇게 한포인트마다 세번씩 계산함
# 그래서 nfev는 (초깃값 포함한 이동한 점개수)*3
```

          fun: 2.0
     hess_inv: array([[0.5]])
          jac: array([0.])
      message: 'Optimization terminated successfully.'
         nfev: 9
          nit: 2
         njev: 3
       status: 0
      success: True
            x: array([1.99999999])



```python
def f1p(x):
#     f1의 도함수
    return 2*(x-2)
```


```python
result=  sp.optimize.minimize(f1,x0,jac=f1p)
result
# nfev 가 9 ->3 으로 변화
# 기울기를 구할때 한포인트당 세번씩 계산을 했어야함
# 하지만 자코비안을넣어주면(도함수) 대입으로 기울기를 구할 수 있음
# 따라서 포인트당 한번씩의 계산만 함
```




          fun: 2.0
     hess_inv: array([[0.5]])
          jac: array([0.])
      message: 'Optimization terminated successfully.'
         nfev: 3
          nit: 2
         njev: 3
       status: 0
      success: True
            x: array([2.])



### 다변수 함수의 최적화(목적함수가 벡터를 인수로)


```python
# 2차원 목적함수 
def f2(x):
    return (1-x[0])**2 + 100.0*(x[1]-x[0]**2)**2

x0=(-2,-2)
result= sp.optimize.minimize(f2,x0)
print(result)
# 초깃값 아무렇게나 줌
# 최저값 찾는데 성공 못함
# 횟수 이상으로는 안돌아감 진동(oscillation) 현상이 있는 함수 
```

          fun: 5.2112890141803265e-12
     hess_inv: array([[0.49938636, 0.99860874],
           [0.99860874, 2.00187364]])
          jac: array([ 7.32138760e-05, -3.35902622e-05])
      message: 'Desired error not necessarily achieved due to precision loss.'
         nfev: 536
          nit: 55
         njev: 131
       status: 2
      success: False
            x: array([0.99999854, 0.9999969 ])


#### 연습 문제 5.1.1
- 1) 최적해에 수렴할 수 있도록 초기점을 변경하여 본다.


```python
x0=(0,0)
result=sp.optimize.minimize(f2,x0)
print(result)
```

          fun: 2.8440316101421118e-11
     hess_inv: array([[0.49482454, 0.98957634],
           [0.98957634, 1.98394215]])
          jac: array([ 3.98673709e-06, -2.84416559e-06])
      message: 'Optimization terminated successfully.'
         nfev: 96
          nit: 19
         njev: 24
       status: 0
      success: True
            x: array([0.99999467, 0.99998932])


- 2)그레디언트 벡터 함수를 구현하여 jac인수로 주는 방법으로 계산 속도를 향상시킨다


```python
def f2p(x):
    return np.array((2.0*(x[0]-1)- 400.0*x[0]*(x[1]-x[0]**2),
                    200.0*(x[1]-x[0]**2)))
# 들어가는것도 벡터 나오는것도 벡터 때문에 ( , )꼴
```


```python
x0=(0,0)
result = sp.optimize.minimize(f2,x0,jac=f2p)
print(result)
```

          fun: 7.717288359756836e-13
     hess_inv: array([[0.49480256, 0.98953879],
           [0.98953879, 1.98387918]])
          jac: array([ 3.92841205e-06, -2.83120876e-06])
      message: 'Optimization terminated successfully.'
         nfev: 24
          nit: 19
         njev: 24
       status: 0
      success: True
            x: array([0.99999913, 0.99999825])



```python

```

35c22918fd2b5caa564d2e494d595339428408c8
ipynb
Jupyter Notebook
math/Day_5.ipynb
Seoheesu1/TIL
5e58e4d07c76c5319da486427857375a29ec0e50
MIT
math/Day_5.ipynb
Seoheesu1/TIL
5e58e4d07c76c5319da486427857375a29ec0e50
MIT
math/Day_5.ipynb
Seoheesu1/TIL
5e58e4d07c76c5319da486427857375a29ec0e50
MIT
Qwen/Qwen-72B
1. YES
2. YES