import sympy
import numpy as np
import matplotlib.pyplot as plt
# gradient vector를 구하기 위해서, symbolic formula로 표현해줌
x, y = sympy.symbols('x y')
#f = x**2 + y**2 +x*y
f = x**2 + y**2 + x*y - sympy.sin(x)*5
f_diff_by_x = sympy.diff(f, x)
f_diff_by_y = sympy.diff(f, y)
# make meshgrid with xs, ys
sample_size = 100
xs, ys = np.meshgrid(np.linspace(-10, 10, sample_size), np.linspace(-10, 10, sample_size))
# make zs
zs = [float(f.subs(x, xv).subs(y, yv)) for xv, yv in zip(xs.ravel(), ys.ravel())]
zs = np.array(zs).reshape(sample_size, sample_size)
plt.figure(figsize=(16, 8))
plt.contour(xs, ys, zs, 50, levels = np.logspace(-1.2, 2.3, 20), cmap=plt.cm.rainbow)
# gradient vector는 조금 덜 촘촘하게 meshgrid를 그려줌
xs_q, ys_q = np.meshgrid( np.linspace(-10, 10, 10), np.linspace(-10, 10, 10) )
# gradient vector 계산
xs_q_grad = [-float(f_diff_by_x.subs(x, xv).subs(y, yv)) for xv, yv in zip(xs_q.ravel(), ys_q.ravel())]
ys_q_grad = [-float(f_diff_by_y.subs(x, xv).subs(y, yv)) for xv, yv in zip(xs_q.ravel(), ys_q.ravel())]
"""
간단하게,
scale: 길이, 값을 키울수록 화살표의 길이는 작아짐.
width: 너비(화살표의 너비)
"""
plt.quiver(xs_q, ys_q, xs_q_grad, ys_q_grad, width=0.005, scale=500, color='red')
plt.savefig('../../assets/images/markdown_img/180615_1602_quiver_plot_with_grad.svg')
plt.show()
댓글남기기