파이썬 뉴턴 방법 구현
뉴턴법이란?
1 변수에서는 초기치 $x_0$ 를 설정해, 이하의 수열에 의해 함수 $f$ 의 근사해를 구하는 방법.
x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}
다변수에서는 초기값 $\boldsymbol{x_0}\in\mathbb{R}^n$ 를 설정해, 함수 $f:\mathbb{R}^n\rightarrow\mathbb{R}^n$ 의 근사해를 찾는 방법.
$$\boldsymbol{x_{n + 1}} =\boldsymbol{x_n} - H^{-1} f(\boldsymbol{x_n})$$
여기서 $H$ 는 헤세 행렬입니다.
1 변수
여기에 넣었습니다.
import sympy as sp
import numpy as np
import matplotlib.pyplot as plt
def newton_method(f, x, init_value, num):
df = sp.diff(f, x)
next_value = 0
for i in range(num):
next_value = init_value - f.subs(x, init_value) / df.subs(x, init_value)
init_value = next_value
return next_value
if __name__ == '__main__':
x = sp.Symbol('x')
# ここで関数を設定する
f = sp.sin(x) - 0.5
# ここで初期値を設定する
init_value = 0.1
# ここで繰り返し回数を設定する
num = 10
solution = newton_method(f, x, init_value, num)
print(solution)
예 1
$${\rm sin}(x) - 0.5 = 0$$
초기값
0.5
출력
0.523598775598299
계산기에서 $\pi/6$ 계산 결과
0.52359877559829887307710723054658381403
오차
1.2692289276945341618597101189910806429 E-16
예 2
$$e^x - 2 = 0$$
초기값
1.0
출력
0.693147180559945
계산기에서 $e^x - 2 = 0$ 의 계산 결과
0.69314718055994530941723212145817656807
오차
3.0941723212145817656806814692747176370 E-16
다변수
import sympy as sp
import numpy as np
def newton_method(f, variables, init_value, num):
for i in range(num):
hesse = get_hesse(f, variables, init_value)
subs_vector = np.array(
[[f[i].subs(init_value)] for i in range(len(f))],
dtype=float
)
init_vector = np.array(
[[v] for v in list(init_value.values())],
dtype=float
)
next_value = init_vector - np.linalg.inv(hesse) @ subs_vector
init_value = {key: next_value[n][0] for n, key in enumerate(init_value)}
return init_value
def get_hesse(f, variables, init_value):
hesse = []
for i in range(len(variables)):
l = []
row = []
l.append(variables[i])
for j in range(len(variables)):
if len(l) == 1:
l.append(variables[j])
else:
l[1] = variables[j]
row.append(
sp.diff(f[i], *l).subs(
init_value
)
)
hesse.append(row)
return np.array(hesse, dtype=float)
if __name__ == '__main__':
x = sp.Symbol('x')
y = sp.Symbol('y')
z = sp.Symbol('z')
variables = [x, y, z]
# ここで関数を設定する
f = [x ** 2 - 2, (x ** 2) * (y ** 2) - 4, x * z ** 2 - 1]
# ここで初期値を設定する
init_value = {x: 1, y: 2, z: 0.3}
# ここで繰り返し回数を設定する
solution = newton_method(f, variables, init_value, 50)
print(solution)
예 1
\left\{
\begin{array}{l}
x^2 - 2 = 0 \\
x^2 y^2 - 4 = 0 \\
x z ^2 - 1 = 0
\end{array}
\right.
초기값
{x: 1, y: 2, z: 0.3}
출력
{x: 1.414213562373095, y: 1.4142135623730954, z: 0.8408964152537146}
해(초기값에 가까운 값)
$$x =\sqrt{2}, y =\sqrt{2}, z =\sqrt{1/\sqrt{2}}$$
상기 해의 계산기에서의 계산 결과
x = 1.4142135623730950488016887242096980786
y = 1.4142135623730950488016887242096980786
z = 0.84089641525371454303112547623321489504
오차
x: 4.8801688724209698078596369014359646933 E-17
y: 3.5119831127579030192140409244737913280 E-16
z: 5.6968874523766785104960243772098740359 E-17
참고 기사
Reference
이 문제에 관하여(파이썬 뉴턴 방법 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/quryu/items/08035216f6ebabed9353
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}
여기에 넣었습니다.
import sympy as sp
import numpy as np
import matplotlib.pyplot as plt
def newton_method(f, x, init_value, num):
df = sp.diff(f, x)
next_value = 0
for i in range(num):
next_value = init_value - f.subs(x, init_value) / df.subs(x, init_value)
init_value = next_value
return next_value
if __name__ == '__main__':
x = sp.Symbol('x')
# ここで関数を設定する
f = sp.sin(x) - 0.5
# ここで初期値を設定する
init_value = 0.1
# ここで繰り返し回数を設定する
num = 10
solution = newton_method(f, x, init_value, num)
print(solution)
예 1
$${\rm sin}(x) - 0.5 = 0$$
초기값
0.5
출력
0.523598775598299
계산기에서 $\pi/6$ 계산 결과
0.52359877559829887307710723054658381403
오차
1.2692289276945341618597101189910806429 E-16
예 2
$$e^x - 2 = 0$$
초기값
1.0
출력
0.693147180559945
계산기에서 $e^x - 2 = 0$ 의 계산 결과
0.69314718055994530941723212145817656807
오차
3.0941723212145817656806814692747176370 E-16
다변수
import sympy as sp
import numpy as np
def newton_method(f, variables, init_value, num):
for i in range(num):
hesse = get_hesse(f, variables, init_value)
subs_vector = np.array(
[[f[i].subs(init_value)] for i in range(len(f))],
dtype=float
)
init_vector = np.array(
[[v] for v in list(init_value.values())],
dtype=float
)
next_value = init_vector - np.linalg.inv(hesse) @ subs_vector
init_value = {key: next_value[n][0] for n, key in enumerate(init_value)}
return init_value
def get_hesse(f, variables, init_value):
hesse = []
for i in range(len(variables)):
l = []
row = []
l.append(variables[i])
for j in range(len(variables)):
if len(l) == 1:
l.append(variables[j])
else:
l[1] = variables[j]
row.append(
sp.diff(f[i], *l).subs(
init_value
)
)
hesse.append(row)
return np.array(hesse, dtype=float)
if __name__ == '__main__':
x = sp.Symbol('x')
y = sp.Symbol('y')
z = sp.Symbol('z')
variables = [x, y, z]
# ここで関数を設定する
f = [x ** 2 - 2, (x ** 2) * (y ** 2) - 4, x * z ** 2 - 1]
# ここで初期値を設定する
init_value = {x: 1, y: 2, z: 0.3}
# ここで繰り返し回数を設定する
solution = newton_method(f, variables, init_value, 50)
print(solution)
예 1
\left\{
\begin{array}{l}
x^2 - 2 = 0 \\
x^2 y^2 - 4 = 0 \\
x z ^2 - 1 = 0
\end{array}
\right.
초기값
{x: 1, y: 2, z: 0.3}
출력
{x: 1.414213562373095, y: 1.4142135623730954, z: 0.8408964152537146}
해(초기값에 가까운 값)
$$x =\sqrt{2}, y =\sqrt{2}, z =\sqrt{1/\sqrt{2}}$$
상기 해의 계산기에서의 계산 결과
x = 1.4142135623730950488016887242096980786
y = 1.4142135623730950488016887242096980786
z = 0.84089641525371454303112547623321489504
오차
x: 4.8801688724209698078596369014359646933 E-17
y: 3.5119831127579030192140409244737913280 E-16
z: 5.6968874523766785104960243772098740359 E-17
참고 기사
Reference
이 문제에 관하여(파이썬 뉴턴 방법 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/quryu/items/08035216f6ebabed9353
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import sympy as sp
import numpy as np
def newton_method(f, variables, init_value, num):
for i in range(num):
hesse = get_hesse(f, variables, init_value)
subs_vector = np.array(
[[f[i].subs(init_value)] for i in range(len(f))],
dtype=float
)
init_vector = np.array(
[[v] for v in list(init_value.values())],
dtype=float
)
next_value = init_vector - np.linalg.inv(hesse) @ subs_vector
init_value = {key: next_value[n][0] for n, key in enumerate(init_value)}
return init_value
def get_hesse(f, variables, init_value):
hesse = []
for i in range(len(variables)):
l = []
row = []
l.append(variables[i])
for j in range(len(variables)):
if len(l) == 1:
l.append(variables[j])
else:
l[1] = variables[j]
row.append(
sp.diff(f[i], *l).subs(
init_value
)
)
hesse.append(row)
return np.array(hesse, dtype=float)
if __name__ == '__main__':
x = sp.Symbol('x')
y = sp.Symbol('y')
z = sp.Symbol('z')
variables = [x, y, z]
# ここで関数を設定する
f = [x ** 2 - 2, (x ** 2) * (y ** 2) - 4, x * z ** 2 - 1]
# ここで初期値を設定する
init_value = {x: 1, y: 2, z: 0.3}
# ここで繰り返し回数を設定する
solution = newton_method(f, variables, init_value, 50)
print(solution)
\left\{
\begin{array}{l}
x^2 - 2 = 0 \\
x^2 y^2 - 4 = 0 \\
x z ^2 - 1 = 0
\end{array}
\right.
{x: 1, y: 2, z: 0.3}
{x: 1.414213562373095, y: 1.4142135623730954, z: 0.8408964152537146}
x = 1.4142135623730950488016887242096980786
y = 1.4142135623730950488016887242096980786
z = 0.84089641525371454303112547623321489504
x: 4.8801688724209698078596369014359646933 E-17
y: 3.5119831127579030192140409244737913280 E-16
z: 5.6968874523766785104960243772098740359 E-17
Reference
이 문제에 관하여(파이썬 뉴턴 방법 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/quryu/items/08035216f6ebabed9353텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)